diff --git a/src/main/config.test.ts b/src/main/config.test.ts index 119eae6e7..347f9311c 100644 --- a/src/main/config.test.ts +++ b/src/main/config.test.ts @@ -7,7 +7,7 @@ vi.mock('./utils', () => ({ vi.mock('electron', () => ({ app: { isPackaged: true, - }, + } satisfies Pick, })); describe('main/config.ts', () => { diff --git a/src/main/events.test.ts b/src/main/events.test.ts index 063661f42..bf79d9602 100644 --- a/src/main/events.test.ts +++ b/src/main/events.test.ts @@ -7,7 +7,7 @@ vi.mock('electron', () => ({ ipcMain: { on: (...args: unknown[]) => onMock(...args), handle: (...args: unknown[]) => handleMock(...args), - }, + } satisfies Pick, })); import type { Menubar } from 'menubar'; diff --git a/src/main/handlers/app.test.ts b/src/main/handlers/app.test.ts index 85b6d577e..e23cb9d04 100644 --- a/src/main/handlers/app.test.ts +++ b/src/main/handlers/app.test.ts @@ -11,10 +11,10 @@ vi.mock('electron', () => ({ ipcMain: { handle: (...args: unknown[]) => handleMock(...args), on: (...args: unknown[]) => onMock(...args), - }, + } satisfies Pick, app: { getVersion: vi.fn(() => '1.0.0'), - }, + } satisfies Pick, })); vi.mock('../config', () => ({ diff --git a/src/main/handlers/system.test.ts b/src/main/handlers/system.test.ts index 331efc4dc..e9b5ccba6 100644 --- a/src/main/handlers/system.test.ts +++ b/src/main/handlers/system.test.ts @@ -12,17 +12,17 @@ vi.mock('electron', () => ({ ipcMain: { on: (...args: unknown[]) => onMock(...args), handle: (...args: unknown[]) => handleMock(...args), - }, + } satisfies Pick, globalShortcut: { register: vi.fn(), unregister: vi.fn(), - }, + } satisfies Pick, app: { setLoginItemSettings: vi.fn(), - }, + } satisfies Pick, shell: { openExternal: vi.fn(), - }, + } satisfies Pick, })); describe('main/handlers/system.ts', () => { diff --git a/src/main/handlers/tray.test.ts b/src/main/handlers/tray.test.ts index 4c4584258..57cc0339b 100644 --- a/src/main/handlers/tray.test.ts +++ b/src/main/handlers/tray.test.ts @@ -10,10 +10,10 @@ const onMock = vi.fn(); vi.mock('electron', () => ({ ipcMain: { on: (...args: unknown[]) => onMock(...args), - }, + } satisfies Pick, net: { isOnline: vi.fn().mockReturnValue(true), - }, + } satisfies Pick, })); describe('main/handlers/tray.ts', () => { diff --git a/src/main/lifecycle/first-run.test.ts b/src/main/lifecycle/first-run.test.ts index 4a84f955f..a9eac6548 100644 --- a/src/main/lifecycle/first-run.test.ts +++ b/src/main/lifecycle/first-run.test.ts @@ -20,15 +20,23 @@ const moveToApplicationsFolderMock = vi.fn(); const isInApplicationsFolderMock = vi.fn(() => false); const getPathMock = vi.fn(() => '/User/Data'); -const showMessageBoxMock = vi.fn(async () => ({ response: 0 })); +const showMessageBoxMock = vi.fn(async () => ({ + response: 0, + checkboxChecked: false, +})); vi.mock('electron', () => ({ app: { getPath: () => getPathMock(), isInApplicationsFolder: () => isInApplicationsFolderMock(), moveToApplicationsFolder: () => moveToApplicationsFolderMock(), - }, - dialog: { showMessageBox: () => showMessageBoxMock() }, + } satisfies Pick< + Electron.App, + 'getPath' | 'isInApplicationsFolder' | 'moveToApplicationsFolder' + >, + dialog: { + showMessageBox: () => showMessageBoxMock(), + } satisfies Pick, })); // Ensure the module under test thinks we're not in dev mode @@ -97,7 +105,10 @@ describe('main/lifecycle/first-run', () => { it('prompts and moves app on macOS when user accepts', async () => { existsSyncMock.mockReturnValueOnce(false); // marker existsSyncMock.mockReturnValueOnce(false); // folder - showMessageBoxMock.mockResolvedValueOnce({ response: 0 }); + showMessageBoxMock.mockResolvedValueOnce({ + response: 0, + checkboxChecked: false, + }); await onFirstRunMaybe(); @@ -107,7 +118,10 @@ describe('main/lifecycle/first-run', () => { it('does not move when user declines', async () => { existsSyncMock.mockReturnValueOnce(false); existsSyncMock.mockReturnValueOnce(false); - showMessageBoxMock.mockResolvedValueOnce({ response: 1 }); + showMessageBoxMock.mockResolvedValueOnce({ + response: 1, + checkboxChecked: false, + }); await onFirstRunMaybe(); diff --git a/src/main/lifecycle/reset.test.ts b/src/main/lifecycle/reset.test.ts index 00ed60fe4..381bb0ecc 100644 --- a/src/main/lifecycle/reset.test.ts +++ b/src/main/lifecycle/reset.test.ts @@ -1,7 +1,9 @@ import type { Menubar } from 'menubar'; vi.mock('electron', () => ({ - dialog: { showMessageBoxSync: vi.fn(() => 0) }, + dialog: { + showMessageBoxSync: vi.fn(() => 0), + } satisfies Pick, })); const sendRendererEventMock = vi.fn(); diff --git a/src/main/lifecycle/startup.test.ts b/src/main/lifecycle/startup.test.ts index 8876a8f45..fbf7eff69 100644 --- a/src/main/lifecycle/startup.test.ts +++ b/src/main/lifecycle/startup.test.ts @@ -13,7 +13,7 @@ vi.mock('electron', () => ({ requestSingleInstanceLock: () => requestSingleInstanceLockMock(), on: (...a: unknown[]) => appOnMock(...a), quit: () => appQuitMock(), - }, + } satisfies Pick, })); const sendRendererEventMock = vi.fn(); diff --git a/src/main/menu.test.ts b/src/main/menu.test.ts index 10b7ff958..95a54e7b4 100644 --- a/src/main/menu.test.ts +++ b/src/main/menu.test.ts @@ -29,9 +29,11 @@ vi.mock('electron', () => { return { Menu: { buildFromTemplate: vi.fn(), - }, + } satisfies Pick, MenuItem: MockMenuItem, - shell: { openExternal: vi.fn() }, + shell: { + openExternal: vi.fn(), + } satisfies Pick, }; }); diff --git a/src/main/updater.test.ts b/src/main/updater.test.ts index 237f0f4a2..951b65496 100644 --- a/src/main/updater.test.ts +++ b/src/main/updater.test.ts @@ -45,10 +45,16 @@ vi.mock('electron', () => { } } return { - dialog: { showMessageBox: vi.fn() }, + dialog: { + showMessageBox: vi.fn(), + } satisfies Pick, MenuItem, - Menu: { buildFromTemplate: vi.fn() }, - shell: { openExternal: vi.fn() }, + Menu: { + buildFromTemplate: vi.fn(), + } satisfies Pick, + shell: { + openExternal: vi.fn(), + } satisfies Pick, }; }); diff --git a/src/main/utils.test.ts b/src/main/utils.test.ts index cfd17469c..268847d9a 100644 --- a/src/main/utils.test.ts +++ b/src/main/utils.test.ts @@ -19,9 +19,13 @@ vi.mock('node:os', () => ({ vi.mock('electron', () => ({ app: { isPackaged: true, - }, - shell: { openPath: vi.fn(() => Promise.resolve('')) }, - dialog: { showMessageBoxSync: vi.fn(() => 0) }, + } satisfies Pick, + shell: { + openPath: vi.fn(() => Promise.resolve('')), + } satisfies Pick, + dialog: { + showMessageBoxSync: vi.fn(() => 0), + } satisfies Pick, })); const fileGetFileMock = vi.fn(() => ({ path: '/var/log/app/app.log' })); diff --git a/src/preload/index.test.ts b/src/preload/index.test.ts index 55d508f3f..bb11739ad 100644 --- a/src/preload/index.test.ts +++ b/src/preload/index.test.ts @@ -36,11 +36,11 @@ vi.mock('electron', () => ({ contextBridge: { exposeInMainWorld: (key: string, value: unknown) => exposeInMainWorldMock(key, value), - }, + } satisfies Pick, webFrame: { getZoomLevel: () => getZoomLevelMock(), setZoomLevel: (level: number) => setZoomLevelMock(level), - }, + } satisfies Pick, })); // Simple Notification stub diff --git a/src/preload/utils.test.ts b/src/preload/utils.test.ts index 890b29ca7..3b35ddbde 100644 --- a/src/preload/utils.test.ts +++ b/src/preload/utils.test.ts @@ -3,22 +3,30 @@ import { EVENTS } from '../shared/events'; import { invokeMainEvent, onRendererEvent, sendMainEvent } from './utils'; vi.mock('electron', () => { - type Listener = (event: unknown, ...args: unknown[]) => void; + type Listener = Parameters[1]; const listeners: Record = {}; + const ipcRendererStub = { + send: vi.fn(), + invoke: vi.fn().mockResolvedValue('response'), + on: vi.fn(function ( + this: Electron.IpcRenderer, + channel: string, + listener: Listener, + ) { + if (!listeners[channel]) { + listeners[channel] = []; + } + listeners[channel].push(listener); + return this; + }), + } satisfies Pick; return { ipcRenderer: { - send: vi.fn(), - invoke: vi.fn().mockResolvedValue('response'), - on: vi.fn((channel: string, listener: Listener) => { - if (!listeners[channel]) { - listeners[channel] = []; - } - listeners[channel].push(listener); - }), + ...ipcRendererStub, __emit: (channel: string, ...args: unknown[]) => { const list = listeners[channel] || []; for (const l of list) { - l({}, ...args); + l({} as Electron.IpcRendererEvent, ...args); } }, __listeners: listeners,