diff --git a/packages/main/src/index.spec.ts b/packages/main/src/index.spec.ts index 6ebc170e4..423a866a3 100644 --- a/packages/main/src/index.spec.ts +++ b/packages/main/src/index.spec.ts @@ -17,7 +17,7 @@ ***********************************************************************/ import type { App } from 'electron'; -import { app, BrowserWindow } from 'electron'; +import { app, BrowserWindow, Tray } from 'electron'; import { afterEach, assert, beforeEach, expect, test, vi } from 'vitest'; import { @@ -26,6 +26,7 @@ import { mainWindowDeferred, sanitizeProtocolForExtension, } from './index.js'; +import { PluginSystem } from './plugin/index.js'; import { Deferred } from './plugin/util/deferred.js'; import * as util from './util.js'; @@ -57,16 +58,21 @@ vi.mock('electron-util/main', async () => { }; }); +const fakeWindow = { + isDestroyed: vi.fn(), + webContents: { + send: vi.fn(), + }, +} as unknown as BrowserWindow; + +const initMock = vi.fn(); +const extensionLoader = { + getConfigurationRegistry: vi.fn(), +}; + vi.mock('./plugin', async () => { - const extensionLoader = { - getConfigurationRegistry: vi.fn(), - }; return { - PluginSystem: vi.fn().mockImplementation(() => { - return { - initExtensions: vi.fn().mockImplementation(() => extensionLoader), - }; - }), + PluginSystem: vi.fn(), }; }); @@ -135,141 +141,147 @@ vi.mock('electron', async () => { Menu: { buildFromTemplate: vi.fn(), getApplicationMenu: vi.fn(), + setApplicationMenu: vi.fn(), }, BrowserWindow: MyCustomWindow /*{ getAllWindows: vi.fn().mockReturnValue([]), },*/, - Tray: vi.fn().mockImplementation(() => { - return { - tray: vi.fn(), - setImage: vi.fn(), - setToolTip: vi.fn(), - setContextMenu: vi.fn(), - }; - }), + Tray: vi.fn(), }; }); beforeEach(() => { console.log = consoleLogMock; vi.clearAllMocks(); - // reset the promise + vi.mocked(Tray).mockImplementation(() => { + return { + tray: vi.fn(), + setImage: vi.fn(), + setToolTip: vi.fn(), + setContextMenu: vi.fn(), + } as unknown as Tray; + }); + vi.mocked(PluginSystem).mockImplementation(() => { + return { + initExtensions: initMock.mockImplementation(() => extensionLoader), + } as unknown as PluginSystem; + }); + + vi.mocked(app.whenReady).mockReturnValue(constants.appReadyDeferredPromise); + const newDefer = new Deferred(); if (mainWindowDeferred.promise !== undefined) { - mainWindowDeferred.promise = new Promise((resolve, reject) => { - mainWindowDeferred.resolve = resolve; - mainWindowDeferred.reject = reject; - }); + mainWindowDeferred.resolve = newDefer.resolve; + mainWindowDeferred.promise = newDefer.promise; + mainWindowDeferred.reject = newDefer.reject; } + mainWindowDeferred.resolve(fakeWindow); }); afterEach(() => { console.log = originalConsoleLog; }); -test('should send the URL to open when mainWindow is created', async () => { - handleOpenUrl('podman-desktop:extension/my.extension'); +test('app-ready event with activate event', async () => { + vi.mocked(util.isMac).mockReset(); + vi.mocked(util.isMac).mockReturnValue(true); - const deferredCall = new Deferred(); - const sendMock = vi.fn().mockImplementation(() => { - deferredCall.resolve(true); + // grab all windows + const windows = BrowserWindow.getAllWindows(); + expect(windows).toHaveLength(1); + + const window = windows[0]; + if (!window) { + assert.fail('window is undefined'); + } + const spyShow = vi.spyOn(window, 'show'); + const spyFocus = vi.spyOn(window, 'focus'); + + let activateCallback: ((event: unknown) => void) | undefined = undefined; + + // capture activate event + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + vi.mocked(app.on).mockImplementation((event: string, callback: Function): App => { + if (event === 'activate') { + activateCallback = callback as (event: unknown) => void; + } + return app; }); - const fakeWindow = { - isDestroyed: vi.fn(), - webContents: { - send: sendMock, - }, - } as unknown as BrowserWindow; - mainWindowDeferred.resolve(fakeWindow); + if (constants.resolveFn) { + const appReady: (value: void | Promise) => void = constants.resolveFn; + if (constants.resolveFn) { + appReady(); + } + } else { + assert.fail('constants.resolveFn is undefined'); + } + // wait activateCallback being set + await vi.waitUntil(() => activateCallback !== undefined); + // now, check that we called + activateCallback!({}); + + // expect show and focus have been called + expect(spyShow).toHaveBeenCalled(); + expect(spyFocus).toHaveBeenCalled(); +}); + +test('should send the URL to open when mainWindow is created', async () => { + handleOpenUrl('podman-desktop:extension/my.extension'); // wait sendMock being called - await deferredCall.promise; + await vi.waitFor(() => expect(fakeWindow.webContents.send).toHaveBeenCalled()); - expect(sendMock).toHaveBeenCalledWith('podman-desktop-protocol:install-extension', 'my.extension'); + expect(fakeWindow.webContents.send).toHaveBeenCalledWith('podman-desktop-protocol:install-extension', 'my.extension'); }); test('should send the URL to open when mainWindow is created with :// format', async () => { handleOpenUrl('podman-desktop://extension/my.extension'); - const deferredCall = new Deferred(); - const sendMock = vi.fn().mockImplementation(() => { - deferredCall.resolve(true); - }); - const fakeWindow = { - isDestroyed: vi.fn(), - webContents: { - send: sendMock, - }, - } as unknown as BrowserWindow; - - mainWindowDeferred.resolve(fakeWindow); - // wait sendMock being called - await deferredCall.promise; - - expect(sendMock).toHaveBeenCalledWith('podman-desktop-protocol:install-extension', 'my.extension'); + await vi.waitFor(() => + expect(fakeWindow.webContents.send).toHaveBeenCalledWith( + 'podman-desktop-protocol:install-extension', + 'my.extension', + ), + ); }); test('should not send the URL for invalid URLs', async () => { handleOpenUrl('podman-desktop:foobar'); - const sendMock = vi.fn(); - // expect an error expect(consoleLogMock).toHaveBeenCalledWith( 'url podman-desktop:foobar does not start with podman-desktop:extension/, skipping.', ); - expect(sendMock).not.toHaveBeenCalled(); + expect(vi.mocked(fakeWindow.webContents.send)).not.toHaveBeenCalled(); }); test('should handle podman-desktop:extension/ URL on Windows', async () => { vi.spyOn(util, 'isWindows').mockReturnValue(true); - const deferredCall = new Deferred(); - const sendMock = vi.fn().mockImplementation(() => { - deferredCall.resolve(true); - }); - - const fakeWindow = { - isDestroyed: vi.fn(), - webContents: { - send: sendMock, - }, - } as unknown as BrowserWindow; - mainWindowDeferred.resolve(fakeWindow); - handleAdditionalProtocolLauncherArgs(['podman-desktop:extension/my.extension']); - // wait sendMock being called - await deferredCall.promise; - // expect handleOpenUrl not be called - expect(fakeWindow.webContents.send).toHaveBeenCalledWith('podman-desktop-protocol:install-extension', 'my.extension'); + await vi.waitFor(() => + expect(fakeWindow.webContents.send).toHaveBeenCalledWith( + 'podman-desktop-protocol:install-extension', + 'my.extension', + ), + ); }); test('should handle podman-desktop://extension/my.extension format URL on Windows', async () => { vi.spyOn(util, 'isWindows').mockReturnValue(true); - const deferredCall = new Deferred(); - const sendMock = vi.fn().mockImplementation(() => { - deferredCall.resolve(true); - }); - - const fakeWindow = { - isDestroyed: vi.fn(), - webContents: { - send: sendMock, - }, - } as unknown as BrowserWindow; - mainWindowDeferred.resolve(fakeWindow); - handleAdditionalProtocolLauncherArgs(['podman-desktop://extension/my.extension']); - // wait sendMock being called - await deferredCall.promise; - // expect handleOpenUrl not be called - expect(fakeWindow.webContents.send).toHaveBeenCalledWith('podman-desktop-protocol:install-extension', 'my.extension'); + await vi.waitFor(() => + expect(fakeWindow.webContents.send).toHaveBeenCalledWith( + 'podman-desktop-protocol:install-extension', + 'my.extension', + ), + ); }); test('should not do anything with podman-desktop:extension/ URL on OS different than Windows', async () => { @@ -277,8 +289,8 @@ test('should not do anything with podman-desktop:extension/ URL on OS different // spy .promise field of mainWindowDeferred const spyWindowDefferedPromise = vi.spyOn(mainWindowDeferred, 'promise', 'get'); - handleAdditionalProtocolLauncherArgs(['podman-desktop:extension/my.extension']); + // no called on it expect(spyWindowDefferedPromise).not.toHaveBeenCalled(); }); @@ -293,47 +305,3 @@ test('handle sanitizeProtocolForExtension noop', () => { const sanitizedLink = 'podman-desktop:extension/my.extension'; expect(sanitizeProtocolForExtension(sanitizedLink)).toEqual(sanitizedLink); }); - -test('app-ready event with activate event', async () => { - vi.mocked(util.isMac).mockReset(); - vi.mocked(util.isMac).mockReturnValue(true); - - // grab all windows - const windows = BrowserWindow.getAllWindows(); - expect(windows).toHaveLength(1); - - const window = windows[0]; - if (!window) { - assert.fail('window is undefined'); - } - const spyShow = vi.spyOn(window, 'show'); - const spyFocus = vi.spyOn(window, 'focus'); - - let activateCallback: ((event: unknown) => void) | undefined = undefined; - - // capture activate event - // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type - vi.mocked(app.on).mockImplementation((event: string, callback: Function): App => { - if (event === 'activate') { - activateCallback = callback as (event: unknown) => void; - } - return app; - }); - - if (constants.resolveFn) { - const appReady: (value: void | Promise) => void = constants.resolveFn; - if (constants.resolveFn) { - appReady(); - } - } else { - assert.fail('constants.resolveFn is undefined'); - } - // wait activateCallback being set - await vi.waitUntil(() => activateCallback !== undefined); - // now, check that we called - activateCallback!({}); - - // expect show and focus have been called - expect(spyShow).toHaveBeenCalled(); - expect(spyFocus).toHaveBeenCalled(); -});