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

Fix behavioural tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-06-06 11:09:52 -04:00
parent 9ebd495617
commit 3d6e77d186
7 changed files with 189 additions and 43 deletions

View File

@ -59,15 +59,14 @@ describe("installing update using tray", () => {
});
it("user cannot install update yet", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
expect(applicationBuilder.tray.get("install-update")).toBeNull();
});
describe("when user checks for updates using tray", () => {
let processCheckingForUpdatesPromise: Promise<void>;
beforeEach(async () => {
processCheckingForUpdatesPromise =
applicationBuilder.tray.click("check-for-updates");
processCheckingForUpdatesPromise = applicationBuilder.tray.click("check-for-updates");
});
it("does not show application window yet", () => {
@ -76,18 +75,18 @@ describe("installing update using tray", () => {
it("user cannot check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
applicationBuilder.tray.get("check-for-updates")?.enabled,
).toBe(false);
});
it("name of tray item for checking updates indicates that checking is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
applicationBuilder.tray.get("check-for-updates")?.label,
).toBe("Checking for updates...");
});
it("user cannot install update yet", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
expect(applicationBuilder.tray.get("install-update")).toBeNull();
});
it("renders", () => {
@ -108,18 +107,18 @@ describe("installing update using tray", () => {
});
it("user cannot install update", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
expect(applicationBuilder.tray.get("install-update")).toBeNull();
});
it("user can check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
applicationBuilder.tray.get("check-for-updates")?.enabled,
).toBe(true);
});
it("name of tray item for checking updates no longer indicates that checking is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
applicationBuilder.tray.get("check-for-updates")?.label,
).toBe("Check for updates");
});
@ -144,13 +143,13 @@ describe("installing update using tray", () => {
it("user cannot check for updates again yet", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
applicationBuilder.tray.get("check-for-updates")?.enabled,
).toBe(false);
});
it("name of tray item for checking updates indicates that downloading is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
applicationBuilder.tray.get("check-for-updates")?.label,
).toBe("Downloading update some-version (0%)...");
});
@ -162,12 +161,12 @@ describe("installing update using tray", () => {
progressOfUpdateDownload.set({ percentage: 42.424242 });
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
applicationBuilder.tray.get("check-for-updates")?.label,
).toBe("Downloading update some-version (42%)...");
});
it("user still cannot install update", () => {
expect(applicationBuilder.tray.get("install-update")).toBeUndefined();
expect(applicationBuilder.tray.get("install-update")).toBeNull();
});
it("renders", () => {
@ -182,18 +181,18 @@ describe("installing update using tray", () => {
it("user cannot install update", () => {
expect(
applicationBuilder.tray.get("install-update"),
).toBeUndefined();
).toBeNull();
});
it("user can check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
applicationBuilder.tray.get("check-for-updates")?.enabled,
).toBe(true);
});
it("name of tray item for checking updates no longer indicates that downloading is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
applicationBuilder.tray.get("check-for-updates")?.label,
).toBe("Check for updates");
});
@ -209,19 +208,19 @@ describe("installing update using tray", () => {
it("user can install update", () => {
expect(
applicationBuilder.tray.get("install-update")?.label?.get(),
applicationBuilder.tray.get("install-update")?.label,
).toBe("Install update some-version");
});
it("user can check for updates again", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.enabled.get(),
applicationBuilder.tray.get("check-for-updates")?.enabled,
).toBe(true);
});
it("name of tray item for checking updates no longer indicates that downloading is happening", () => {
expect(
applicationBuilder.tray.get("check-for-updates")?.label?.get(),
applicationBuilder.tray.get("check-for-updates")?.label,
).toBe("Check for updates");
});

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 type { MenuItemConstructorOptions } from "electron";
import { Menu } from "electron";
export type BuildMenuFromTemplate = (template: MenuItemConstructorOptions[]) => Menu;
const buildMenuFromTemplateInjectable = getInjectable({
id: "build-menu-from-template",
instantiate: (): BuildMenuFromTemplate => (template) => Menu.buildFromTemplate(template),
causesSideEffects: true, // Not really but isn't defined
});
export default buildMenuFromTemplateInjectable;

View File

@ -9,8 +9,8 @@ import { getStartableStoppable } from "../../../common/utils/get-startable-stopp
import electronTrayInjectable from "../electron-tray/electron-tray.injectable";
import trayIconPathsInjectable from "../tray-icon-path.injectable";
const reactiveMenuIconInjectable = getInjectable({
id: "reactive-menu-icon",
const reactiveTrayMenuIconInjectable = getInjectable({
id: "reactive-tray-menu-icon",
instantiate: (di) => {
const discoveredUpdateVersion = di.inject(discoveredUpdateVersionInjectable);
const electronTray = di.inject(electronTrayInjectable);
@ -20,11 +20,12 @@ const reactiveMenuIconInjectable = getInjectable({
reaction(
() => discoveredUpdateVersion.value.get(),
updateVersion => {
if (updateVersion) {
electronTray.setIconPath(trayIconPaths.updateAvailable);
} else {
electronTray.setIconPath(trayIconPaths.normal);
}
void updateVersion;
electronTray.setIconPath(trayIconPaths.updateAvailable);
// if (updateVersion) {
// } else {
// electronTray.setIconPath(trayIconPaths.normal);
// }
},
{
fireImmediately: true,
@ -34,4 +35,4 @@ const reactiveMenuIconInjectable = getInjectable({
},
});
export default reactiveMenuIconInjectable;
export default reactiveTrayMenuIconInjectable;

View File

@ -0,0 +1,28 @@
/**
* 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 { onLoadOfApplicationInjectionToken } from "../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
import startTrayInjectable from "../electron-tray/start-tray.injectable";
import reactiveTrayMenuIconInjectable from "./reactive.injectable";
const startReactiveTrayMenuIconInjectable = getInjectable({
id: "start-reactive-tray-menu-icon",
instantiate: (di) => {
const reactiveTrayMenuIcon = di.inject(reactiveTrayMenuIconInjectable);
return {
run: async () => {
await reactiveTrayMenuIcon.start();
},
runAfter: di.inject(startTrayInjectable),
};
},
injectionToken: onLoadOfApplicationInjectionToken,
});
export default startReactiveTrayMenuIconInjectable;

View File

@ -0,0 +1,25 @@
/**
* 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 { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
import reactiveTrayMenuIconInjectable from "./reactive.injectable";
const stopReactiveTrayMenuIconInjectable = getInjectable({
id: "stop-reactive-tray-menu-icon",
instantiate: (di) => {
const reactiveTrayMenuIcon = di.inject(reactiveTrayMenuIconInjectable);
return {
run: async () => {
await reactiveTrayMenuIcon.stop();
},
};
},
injectionToken: beforeQuitOfBackEndInjectionToken,
});
export default stopReactiveTrayMenuIconInjectable;

View File

@ -3,9 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { Menu } from "electron";
import { computed } from "mobx";
import trayMenuItemsInjectable from "../tray-menu-item/tray-menu-items.injectable";
import buildMenuFromTemplateInjectable from "../../electron/build-from-template.injectable";
import convertToElectronMenuTemplateInjectable from "./convert-to-electron-menu-template.injectable";
const trayMenuInjectable = getInjectable({
@ -13,9 +13,10 @@ const trayMenuInjectable = getInjectable({
instantiate: (di) => {
const trayMenuItems = di.inject(trayMenuItemsInjectable);
const convertToElectronMenuTemplate = di.inject(convertToElectronMenuTemplateInjectable);
const buildMenuFromTemplate = di.inject(buildMenuFromTemplateInjectable);
return computed(() => (
Menu.buildFromTemplate(
buildMenuFromTemplate(
convertToElectronMenuTemplate(
trayMenuItems.get(),
),

View File

@ -24,12 +24,12 @@ import type { ClusterStore } from "../../../common/cluster-store/cluster-store";
import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable";
import currentRouteComponentInjectable from "../../routes/current-route-component.injectable";
import { pipeline } from "@ogre-tools/fp";
import { flatMap, compact, join, get, filter, find, map, matches } from "lodash/fp";
import { flatMap, compact, join, get, filter, map } from "lodash/fp";
import preferenceNavigationItemsInjectable from "../+preferences/preferences-navigation/preference-navigation-items.injectable";
import navigateToPreferencesInjectable from "../../../common/front-end-routing/routes/preferences/navigate-to-preferences.injectable";
import type { MenuItemOpts } from "../../../main/menu/application-menu-items.injectable";
import applicationMenuItemsInjectable from "../../../main/menu/application-menu-items.injectable";
import type { MenuItem, MenuItemConstructorOptions } from "electron";
import type { MenuItemConstructorOptions, MenuItem, Menu } from "electron";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable";
import hostedClusterInjectable from "../../../common/cluster-store/hosted-cluster.injectable";
@ -43,7 +43,6 @@ import { flushPromises } from "../../../common/test-utils/flush-promises";
import type { NamespaceStore } from "../+namespaces/store";
import namespaceStoreInjectable from "../+namespaces/store.injectable";
import historyInjectable from "../../navigation/history.injectable";
import type { TrayMenuItem } from "../../../main/tray/tray-menu-item/tray-menu-item-injection-token";
import electronTrayInjectable from "../../../main/tray/electron-tray/electron-tray.injectable";
import applicationWindowInjectable from "../../../main/start-main-application/lens-window/application-window/application-window.injectable";
import { Notifications } from "../notifications/notifications";
@ -51,6 +50,7 @@ import broadcastThatRootFrameIsRenderedInjectable from "../../frames/root-frame/
import { getDiForUnitTesting as getRendererDi } from "../../getDiForUnitTesting";
import { getDiForUnitTesting as getMainDi } from "../../../main/getDiForUnitTesting";
import { overrideChannels } from "../../../test-utils/channel-fakes/override-channels";
import buildMenuFromTemplateInjectable from "../../../main/electron/build-from-template.injectable";
type Callback = (dis: DiContainers) => void | Promise<void>;
@ -65,7 +65,7 @@ export interface ApplicationBuilder {
tray: {
click: (id: string) => Promise<void>;
get: (id: string) => TrayMenuItem | undefined;
get: (id: string) => Electron.MenuItem | null;
};
applicationMenu: {
@ -96,6 +96,10 @@ interface Environment {
onAllowKubeResource: () => void;
}
const getAllSubMenuItems = (item: MenuItem): MenuItem[] => {
return [item, ...(item.submenu?.items ?? []).flatMap(getAllSubMenuItems)];
};
export const getApplicationBuilder = () => {
const mainDi = getMainDi({
doGeneralOverrides: true,
@ -166,15 +170,84 @@ export const getApplicationBuilder = () => {
computed(() => []),
);
let trayMenuItemsStateFake: TrayMenuItem[];
let commandId = 0;
const makeFakeMenuItem = (opts: MenuItemConstructorOptions, menu: Menu): MenuItem => {
const menuItemFake: MenuItem = {
accelerator: opts.accelerator,
checked: opts.checked ?? false,
click: () => opts.click?.(menuItemFake, undefined, new KeyboardEvent("fake")),
commandId: commandId += 1,
enabled: opts.enabled ?? false,
icon: opts.icon,
id: opts.id ?? "",
label: opts.label ?? "",
menu,
registerAccelerator: opts.registerAccelerator ?? true,
sharingItem: opts.sharingItem ?? {},
sublabel: opts.sublabel ?? "",
toolTip: opts.toolTip ?? "",
type: opts.type ?? "normal",
visible: opts.visible ?? true,
role: opts.role,
submenu: opts.submenu === undefined
? undefined
: Array.isArray(opts.submenu)
? makeFakeMenu(opts.submenu)
: opts.submenu,
};
return menuItemFake;
};
const makeFakeMenu = (templates: MenuItemConstructorOptions[]): Menu => {
const menuFake: Electron.Menu = {
addListener: () => {
throw new Error("Adding listeners is not supported currently");
},
on: () => {
throw new Error("Adding listeners is not supported currently");
},
once: () => {
throw new Error("Adding listeners is not supported currently");
},
removeListener: () => {
throw new Error("Removing listeners is not supported currently");
},
append: () => {
throw new Error("Adding new menu items is not supported currently");
},
insert: () => {
throw new Error("Adding new menu items is not supported currently");
},
popup: () => {
throw new Error("Popping up menu is not supported currently");
},
closePopup: () => {
throw new Error("Popping up menu is not supported currently");
},
get items() {
return [...menuItems];
},
getMenuItemById: (id) => menuItems
.flatMap(getAllSubMenuItems)
.find(menuItem => menuItem.id === id)
?? null,
};
const menuItems = templates.map(template => makeFakeMenuItem(template, menuFake));
return menuFake;
};
mainDi.override(buildMenuFromTemplateInjectable, () => makeFakeMenu);
let trayMenuStateFake: Electron.Menu | undefined;
mainDi.override(electronTrayInjectable, () => ({
start: () => {},
stop: () => {},
setMenuItems: (items) => {
trayMenuItemsStateFake = items;
setMenu: (menu) => {
trayMenuStateFake = menu;
},
setIconPath: () => {},
}));
let allowedResourcesState: IObservableArray<KubeResource>;
@ -221,18 +294,20 @@ export const getApplicationBuilder = () => {
tray: {
get: (id: string) => {
return trayMenuItemsStateFake.find(matches({ id }));
return trayMenuStateFake?.getMenuItemById(id) ?? null;
},
click: async (id: string) => {
const menuItem = pipeline(
trayMenuItemsStateFake,
find((menuItem) => menuItem.id === id),
);
if (!trayMenuStateFake) {
throw new Error(`Tried to click tray menu with ID ${id}, but tray menu has not been set yet`);
}
const menuItem = trayMenuStateFake.getMenuItemById(id);
if (!menuItem) {
const availableIds = pipeline(
trayMenuItemsStateFake,
trayMenuStateFake.items,
flatMap(getAllSubMenuItems),
filter(item => !!item.click),
map(item => item.id),
join(", "),