1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

chore: Replace all uses of stopServicesAndExitApp with requestQuitOfApp

- Also updated tests with new behaviour

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-04-05 11:04:56 -04:00
parent 4ff3186ca7
commit 2c4a7ecfb4
8 changed files with 43 additions and 110 deletions

View File

@ -4,28 +4,23 @@
*/ */
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import applicationMenuItemInjectionToken from "../../application-menu-item-injection-token"; import applicationMenuItemInjectionToken from "../../application-menu-item-injection-token";
import stopServicesAndExitAppInjectable from "../../../../../../main/stop-services-and-exit-app.injectable";
import isMacInjectable from "../../../../../../common/vars/is-mac.injectable"; import isMacInjectable from "../../../../../../common/vars/is-mac.injectable";
import requestQuitOfAppInjectable from "../../../../../../main/electron-app/features/require-quit.injectable";
const quitApplicationMenuItemInjectable = getInjectable({ const quitApplicationMenuItemInjectable = getInjectable({
id: "quit-application-menu-item", id: "quit-application-menu-item",
instantiate: (di) => { instantiate: (di) => {
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable);
const isMac = di.inject(isMacInjectable); const isMac = di.inject(isMacInjectable);
return { return {
kind: "clickable-menu-item" as const, kind: "clickable-menu-item" as const,
id: "quit", id: "quit",
label: "Quit", label: "Quit",
parentId: isMac ? "mac" : "file", parentId: isMac ? "mac" : "file",
orderNumber: isMac ? 140 : 70, orderNumber: isMac ? 140 : 70,
keyboardShortcut: isMac ? "Cmd+Q" : "Alt+F4", keyboardShortcut: isMac ? "Cmd+Q" : "Alt+F4",
onClick: di.inject(requestQuitOfAppInjectable),
onClick: () => {
stopServicesAndExitApp();
},
}; };
}, },

View File

@ -5,14 +5,13 @@
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
import forceAppExitInjectable from "../../main/electron-app/features/force-app-exit.injectable"; import { testUsingFakeTime } from "../../test-utils/use-fake-time";
import stopServicesAndExitAppInjectable from "../../main/stop-services-and-exit-app.injectable"; import requestQuitOfAppInjectable from "../../main/electron-app/features/require-quit.injectable";
import { testUsingFakeTime, advanceFakeTime } from "../../test-utils/use-fake-time";
describe("quitting the app using application menu", () => { describe("quitting the app using application menu", () => {
describe("given application has started", () => { describe("given application has started", () => {
let builder: ApplicationBuilder; let builder: ApplicationBuilder;
let forceAppExitMock: jest.Mock; let requestQuitOfAppMock: jest.Mock;
beforeEach(async () => { beforeEach(async () => {
testUsingFakeTime("2015-10-21T07:28:00Z"); testUsingFakeTime("2015-10-21T07:28:00Z");
@ -20,10 +19,8 @@ describe("quitting the app using application menu", () => {
builder = getApplicationBuilder(); builder = getApplicationBuilder();
builder.beforeApplicationStart(({ mainDi }) => { builder.beforeApplicationStart(({ mainDi }) => {
mainDi.unoverride(stopServicesAndExitAppInjectable); requestQuitOfAppMock = jest.fn();
mainDi.override(requestQuitOfAppInjectable, () => requestQuitOfAppMock);
forceAppExitMock = jest.fn();
mainDi.override(forceAppExitInjectable, () => forceAppExitMock);
}); });
await builder.render(); await builder.render();
@ -40,26 +37,8 @@ describe("quitting the app using application menu", () => {
builder.applicationMenu.click("root", "mac", "quit"); builder.applicationMenu.click("root", "mac", "quit");
}); });
it("closes all windows", () => { it("requests quit of application", () => {
const windows = builder.applicationWindow.getAll(); expect(requestQuitOfAppMock).toBeCalled();
expect(windows).toEqual([]);
});
it("after insufficient time passes, does not terminate application yet", () => {
advanceFakeTime(999);
expect(forceAppExitMock).not.toHaveBeenCalled();
});
describe("after sufficient time passes", () => {
beforeEach(() => {
advanceFakeTime(1000);
});
it("terminates application", () => {
expect(forceAppExitMock).toHaveBeenCalled();
});
}); });
}); });
}); });

View File

@ -6,16 +6,17 @@
import { kebabCase } from "lodash"; import { kebabCase } from "lodash";
import { getGlobalOverride } from "@k8slens/test-utils"; import { getGlobalOverride } from "@k8slens/test-utils";
import electronAppInjectable from "./electron-app.injectable"; import electronAppInjectable from "./electron-app.injectable";
import EventEmitter from "events";
export default getGlobalOverride(electronAppInjectable, () => { export default getGlobalOverride(electronAppInjectable, () => {
const commandLineArgs: string[] = []; const commandLineArgs: string[] = [];
const chromiumArgs = new Map<string, string | undefined>(); const chromiumArgs = new Map<string, string | undefined>();
const appPaths = new Map<string, string>(); const appPaths = new Map<string, string>();
const app = ({ const app = (new EventEmitter(), {
getVersion: () => "6.0.0", getVersion: () => "6.0.0",
setLoginItemSettings: () => { }, setLoginItemSettings: () => { },
on: () => app, quit: () => {},
whenReady: async () => {}, whenReady: async () => {},
getPath: (name) => appPaths.get(name) ?? `/some-directory-for-${kebabCase(name)}`, getPath: (name) => appPaths.get(name) ?? `/some-directory-for-${kebabCase(name)}`,
setPath: (name, value) => appPaths.set(name, value), setPath: (name, value) => appPaths.set(name, value),

View File

@ -0,0 +1,17 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import electronAppInjectable from "../electron-app.injectable";
const requestQuitOfAppInjectable = getInjectable({
id: "request-quit-of-app",
instantiate: (di) => {
const app = di.inject(electronAppInjectable);
return () => app.quit();
},
});
export default requestQuitOfAppInjectable;

View File

@ -1,20 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { applicationWindowInjectionToken } from "../application-window/application-window-injection-token";
const closeAllWindowsInjectable = getInjectable({
id: "close-all-windows",
instantiate: (di) => () => {
const lensWindows = di.injectMany(applicationWindowInjectionToken);
lensWindows.forEach((lensWindow) => {
lensWindow.close();
});
},
});
export default closeAllWindowsInjectable;

View File

@ -1,23 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import forceAppExitInjectable from "./electron-app/features/force-app-exit.injectable";
import emitAppEventInjectable from "../common/app-event-bus/emit-event.injectable";
const stopServicesAndExitAppInjectable = getInjectable({
id: "stop-services-and-exit-app",
instantiate: (di) => {
const forceAppExit = di.inject(forceAppExitInjectable);
const emitAppEvent = di.inject(emitAppEventInjectable);
return async () => {
emitAppEvent({ name: "service", action: "close" });
setTimeout(forceAppExit, 1000);
};
},
});
export default stopServicesAndExitAppInjectable;

View File

@ -5,37 +5,20 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token"; import { trayMenuItemInjectionToken } from "../tray-menu-item-injection-token";
import { computed } from "mobx"; import { computed } from "mobx";
import stopServicesAndExitAppInjectable from "../../../stop-services-and-exit-app.injectable"; import requestQuitOfAppInjectable from "../../../electron-app/features/require-quit.injectable";
import { withErrorSuppression } from "../../../../common/utils/with-error-suppression/with-error-suppression";
import { pipeline } from "@ogre-tools/fp";
import withErrorLoggingInjectable from "../../../../common/utils/with-error-logging/with-error-logging.injectable";
const quitAppTrayItemInjectable = getInjectable({ const quitAppTrayItemInjectable = getInjectable({
id: "quit-app-tray-item", id: "quit-app-tray-item",
instantiate: (di) => { instantiate: (di) => ({
const stopServicesAndExitApp = di.inject(stopServicesAndExitAppInjectable); id: "quit-app",
const withErrorLoggingFor = di.inject(withErrorLoggingInjectable); parentId: null,
orderNumber: 150,
return { label: computed(() => "Quit App"),
id: "quit-app", enabled: computed(() => true),
parentId: null, visible: computed(() => true),
orderNumber: 150, click: di.inject(requestQuitOfAppInjectable),
label: computed(() => "Quit App"), }),
enabled: computed(() => true),
visible: computed(() => true),
click: pipeline(
stopServicesAndExitApp,
withErrorLoggingFor(() => "[TRAY]: Quitting application failed."),
// TODO: Find out how to improve typing so that instead of
// x => withErrorSuppression(x) there could only be withErrorSuppression
(x) => withErrorSuppression(x),
),
};
},
injectionToken: trayMenuItemInjectionToken, injectionToken: trayMenuItemInjectionToken,
}); });

View File

@ -50,7 +50,6 @@ import createApplicationWindowInjectable from "../../../main/start-main-applicat
import type { CreateElectronWindow } from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable"; import type { CreateElectronWindow } from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable";
import createElectronWindowInjectable from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable"; import createElectronWindowInjectable from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable";
import { applicationWindowInjectionToken } from "../../../main/start-main-application/lens-window/application-window/application-window-injection-token"; import { applicationWindowInjectionToken } from "../../../main/start-main-application/lens-window/application-window/application-window-injection-token";
import closeAllWindowsInjectable from "../../../main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable";
import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable"; import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable";
import type { FakeExtensionOptions } from "./get-extension-fake"; import type { FakeExtensionOptions } from "./get-extension-fake";
import { getExtensionFakeForMain, getExtensionFakeForRenderer } from "./get-extension-fake"; import { getExtensionFakeForMain, getExtensionFakeForRenderer } from "./get-extension-fake";
@ -330,9 +329,11 @@ export const getApplicationBuilder = () => {
mainDi, mainDi,
applicationWindow: { applicationWindow: {
closeAll: () => { closeAll: () => {
const closeAll = mainDi.inject(closeAllWindowsInjectable); const lensWindows = mainDi.injectMany(applicationWindowInjectionToken);
closeAll(); for (const lensWindow of lensWindows) {
lensWindow.close();
}
document.documentElement.innerHTML = ""; document.documentElement.innerHTML = "";
}, },