diff options
| author | Oskar <oskar@mullvad.net> | 2025-09-03 13:48:19 +0200 |
|---|---|---|
| committer | Oskar <oskar@mullvad.net> | 2025-09-05 11:47:01 +0200 |
| commit | df2afc3d583095408f6bb3bbb1400d9d34311105 (patch) | |
| tree | a1749f0f17c1abb7a3e20dbe51a0711725c217e3 | |
| parent | 72664231e8703127bc492222d8ea630b4a590f2d (diff) | |
| download | mullvadvpn-df2afc3d583095408f6bb3bbb1400d9d34311105.tar.xz mullvadvpn-df2afc3d583095408f6bb3bbb1400d9d34311105.zip | |
Refactor creation of mock ipc methods
| -rw-r--r-- | desktop/packages/mullvad-vpn/src/shared/utility-types.ts | 3 | ||||
| -rw-r--r-- | desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts | 85 |
2 files changed, 31 insertions, 57 deletions
diff --git a/desktop/packages/mullvad-vpn/src/shared/utility-types.ts b/desktop/packages/mullvad-vpn/src/shared/utility-types.ts new file mode 100644 index 0000000000..1d6c41992f --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/shared/utility-types.ts @@ -0,0 +1,3 @@ +export type Async<F extends (...args: unknown[]) => unknown> = ( + ...args: Parameters<F> +) => Promise<ReturnType<F>>; diff --git a/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts b/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts index 84722617c3..e693d1e570 100644 --- a/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts +++ b/desktop/packages/mullvad-vpn/test/e2e/mocked/mocked-utils.ts @@ -2,6 +2,7 @@ import { ElectronApplication } from 'playwright'; import { AnyIpcCall, createIpc, Schema } from '../../../src/shared/ipc-helpers'; import { IpcSchema, ipcSchema } from '../../../src/shared/ipc-schema'; +import { Async } from '../../../src/shared/utility-types'; import { startApp, TestUtils } from '../utils'; // This option can be removed in the future when/if we're able to tun the tests with the sandbox @@ -13,9 +14,6 @@ interface StartMockedAppResponse extends Awaited<ReturnType<typeof startApp>> { } export interface MockedTestUtils extends TestUtils { - mockIpcHandle: MockIpcHandle; - sendMockIpcResponse: SendMockIpcResponse; - expectIpcCall: ExpectIpcCall; ipc: IpcMockedTest<IpcSchema>; } @@ -29,77 +27,55 @@ export const startMockedApp = async (): Promise<StartMockedAppResponse> => { args.push('--gtk-version=3'); const startAppResult = await startApp({ args }); - const mockIpcHandle = generateMockIpcHandle(startAppResult.app); - const sendMockIpcResponse = generateSendMockIpcResponse(startAppResult.app); - const expectIpcCall = generateExpectIpcCall(startAppResult.app); return { ...startAppResult, util: { ...startAppResult.util, - mockIpcHandle, - sendMockIpcResponse, - expectIpcCall, - ipc: createTestIpc(startAppResult.app), }, }; }; -type MockIpcHandleProps<T> = { - channel: string; - response: T; -}; - -export type MockIpcHandle = ReturnType<typeof generateMockIpcHandle>; - -export const generateMockIpcHandle = (electronApp: ElectronApplication) => { - return async <T>({ channel, response }: MockIpcHandleProps<T>): Promise<void> => { +export const createMockIpcHandle = (electronApp: ElectronApplication, event: string) => { + // This function resolves when the handle is registered. To await the event, use `expect()`. + return async <T>(response: T): Promise<void> => { await electronApp.evaluate( - ({ ipcMain }, { channel, response }) => { - ipcMain.removeHandler(channel); - ipcMain.handle(channel, () => { + ({ ipcMain }, { event, response }) => { + ipcMain.removeHandler(event); + ipcMain.handle(event, () => { return Promise.resolve({ type: 'success', value: response, }); }); }, - { channel, response }, + { event, response }, ); }; }; -type SendMockIpcResponseProps<T> = { - channel: string; - response: T; -}; - -export type SendMockIpcResponse = ReturnType<typeof generateSendMockIpcResponse>; - -export const generateSendMockIpcResponse = (electronApp: ElectronApplication) => { - return async <T>({ channel, response }: SendMockIpcResponseProps<T>) => { +export const createMockIpcNotify = (electronApp: ElectronApplication, event: string) => { + return async <T>(arg: T) => { await electronApp.evaluate( - ({ webContents }, { channel, response }) => { + ({ webContents }, { event, arg }) => { webContents .getAllWebContents() // Select window that isn't devtools .find((webContents) => webContents.getURL().startsWith('file://'))! - .send(channel, response); + .send(event, arg); }, - { channel, response }, + { event, arg }, ); }; }; -export type ExpectIpcCall = ReturnType<typeof generateExpectIpcCall>; - -export const generateExpectIpcCall = (electronApp: ElectronApplication) => { - return <T>(channel: string): Promise<T> => { +export const createMockIpcExpect = (electronApp: ElectronApplication, event: string) => { + return <T>(): Promise<T> => { return electronApp.evaluate( - ({ ipcMain }, { channel }) => { + ({ ipcMain }, { event }) => { return new Promise<T>((resolve) => { - ipcMain.handleOnce(channel, (_event, arg) => { + ipcMain.handleOnce(event, (_event, arg) => { resolve(arg); return { type: 'success', @@ -108,22 +84,22 @@ export const generateExpectIpcCall = (electronApp: ElectronApplication) => { }); }); }, - { channel }, + { event }, ); }; }; -export const generateIgnoreIpcCall = (electronApp: ElectronApplication) => { - return async (channel: string): Promise<void> => { +export const createMockIpcIgnore = (electronApp: ElectronApplication, event: string) => { + return async (): Promise<void> => { await electronApp.evaluate( - ({ ipcMain }, { channel }) => { - ipcMain.removeHandler(channel); - ipcMain.handle(channel, () => ({ + ({ ipcMain }, { event }) => { + ipcMain.removeHandler(event); + ipcMain.handle(event, () => ({ type: 'success', value: null, })); }, - { channel }, + { event }, ); }; }; @@ -137,9 +113,6 @@ type IpcMockedTestExtraHandlerKey< K, > = I['direction'] extends 'main-to-renderer' ? never : K; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type Async<F extends (...args: any) => any> = (arg: Parameters<F>[0]) => Promise<ReturnType<F>>; - type IpcMockedTestFn<I extends AnyIpcCall> = I['direction'] extends 'main-to-renderer' ? Async<NonNullable<ReturnType<I['send']>>> : Async<Parameters<ReturnType<I['receive']>>[0]>; @@ -164,12 +137,10 @@ export function createTestIpc(electronApp: ElectronApplication): IpcMockedTest<I key, { eventKey: event, - notify: <T>(message: T) => - generateSendMockIpcResponse(electronApp)({ channel: event, response: message }), - handle: <T>(response: T) => - generateMockIpcHandle(electronApp)({ channel: event, response }), - expect: () => generateExpectIpcCall(electronApp)(event), - ignore: () => generateIgnoreIpcCall(electronApp)(event), + notify: createMockIpcNotify(electronApp, event), + handle: createMockIpcHandle(electronApp, event), + expect: createMockIpcExpect(electronApp, event), + ignore: createMockIpcIgnore(electronApp, event), }, ]; }); |
