mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add unit test to make sure that enabling, disabling and re-enabling extensions does not make tray menu items throw
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
e051155890
commit
6b8382f815
@ -46,7 +46,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => {
|
||||
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
||||
const testExtension = getRendererExtensionFake(extensionStubWithSidebarItems);
|
||||
|
||||
await applicationBuilder.addExtensions(testExtension);
|
||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
||||
});
|
||||
|
||||
describe("given no state for expanded sidebar items exists, and navigated to child sidebar item, when rendered", () => {
|
||||
|
||||
@ -23,7 +23,7 @@ describe("extension special characters in page registrations", () => {
|
||||
extensionWithPagesHavingSpecialCharacters,
|
||||
);
|
||||
|
||||
await applicationBuilder.addExtensions(testExtension);
|
||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
||||
|
||||
rendered = await applicationBuilder.render();
|
||||
});
|
||||
|
||||
@ -27,7 +27,7 @@ describe("navigate to extension page", () => {
|
||||
extensionWithPagesHavingParameters,
|
||||
);
|
||||
|
||||
await applicationBuilder.addExtensions(testExtension);
|
||||
await applicationBuilder.extensions.renderer.enable(testExtension);
|
||||
|
||||
rendered = await applicationBuilder.render();
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ describe("preferences - navigation to extension specific preferences", () => {
|
||||
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
||||
const testExtension = getRendererExtensionFake(extensionStubWithExtensionSpecificPreferenceItems);
|
||||
|
||||
applicationBuilder.addExtensions(testExtension);
|
||||
applicationBuilder.extensions.renderer.enable(testExtension);
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
|
||||
@ -50,7 +50,7 @@ describe("preferences - navigation to telemetry preferences", () => {
|
||||
const getRendererExtensionFake = getRendererExtensionFakeFor(applicationBuilder);
|
||||
const testExtensionWithTelemetryPreferenceItems = getRendererExtensionFake(extensionStubWithTelemetryPreferenceItems);
|
||||
|
||||
applicationBuilder.addExtensions(
|
||||
applicationBuilder.extensions.renderer.enable(
|
||||
testExtensionWithTelemetryPreferenceItems,
|
||||
);
|
||||
});
|
||||
@ -105,7 +105,7 @@ describe("preferences - navigation to telemetry preferences", () => {
|
||||
],
|
||||
});
|
||||
|
||||
applicationBuilder.addExtensions(
|
||||
applicationBuilder.extensions.renderer.enable(
|
||||
testExtensionWithTelemetryPreferenceItems,
|
||||
);
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ describe("clicking tray menu item originating from extension", () => {
|
||||
trayMenus: [{ label: "some-label", click: clickMock }],
|
||||
});
|
||||
|
||||
await applicationBuilder.addMainExtensions(someExtension);
|
||||
await applicationBuilder.extensions.main.enable(someExtension);
|
||||
});
|
||||
|
||||
it("when item is clicked, triggers the click handler", () => {
|
||||
@ -84,15 +84,33 @@ describe("clicking tray menu item originating from extension", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("when disabling extension, does not have tray menu items", () => {
|
||||
applicationBuilder.removeMainExtensions(someExtension);
|
||||
describe("when disabling extension", () => {
|
||||
beforeEach(() => {
|
||||
applicationBuilder.extensions.main.disable(someExtension);
|
||||
});
|
||||
|
||||
expect(
|
||||
applicationBuilder.tray.get(
|
||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-1",
|
||||
),
|
||||
).toBeNull();
|
||||
it("does not have the tray menu item from extension", () => {
|
||||
applicationBuilder.extensions.main.disable(someExtension);
|
||||
|
||||
expect(
|
||||
applicationBuilder.tray.get(
|
||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-1",
|
||||
),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
// Note: Motivation here is to make sure that enabling same extension does not throw
|
||||
it("when extension is re-enabled, has the tray menu item from extension", async () => {
|
||||
await applicationBuilder.extensions.main.enable(someExtension);
|
||||
|
||||
expect(
|
||||
applicationBuilder.tray.get(
|
||||
"some-label-tray-menu-item-for-extension-some-extension-id-instance-2",
|
||||
),
|
||||
).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import type { LensRendererExtension } from "../../../extensions/lens-renderer-ex
|
||||
import rendererExtensionsInjectable from "../../../extensions/renderer-extensions.injectable";
|
||||
import currentlyInClusterFrameInjectable from "../../routes/currently-in-cluster-frame.injectable";
|
||||
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
|
||||
import type { IObservableArray } from "mobx";
|
||||
import type { IObservableArray, ObservableSet } from "mobx";
|
||||
import { computed, observable, runInAction } from "mobx";
|
||||
import { renderFor } from "./renderFor";
|
||||
import React from "react";
|
||||
@ -58,15 +58,29 @@ import { StatusBar } from "../status-bar/status-bar";
|
||||
import lensProxyPortInjectable from "../../../main/lens-proxy/lens-proxy-port.injectable";
|
||||
import type { LensMainExtension } from "../../../extensions/lens-main-extension";
|
||||
import trayMenuItemsInjectable from "../../../main/tray/tray-menu-item/tray-menu-items.injectable";
|
||||
import type { LensExtension } from "../../../extensions/lens-extension";
|
||||
|
||||
type Callback = (dis: DiContainers) => void | Promise<void>;
|
||||
|
||||
type EnableExtensions<T> = (...extensions: T[]) => Promise<void>;
|
||||
type DisableExtensions<T> = (...extensions: T[]) => void;
|
||||
|
||||
export interface ApplicationBuilder {
|
||||
dis: DiContainers;
|
||||
setEnvironmentToClusterFrame: () => ApplicationBuilder;
|
||||
addExtensions: (...extensions: LensRendererExtension[]) => Promise<ApplicationBuilder>;
|
||||
addMainExtensions: (...extensions: LensMainExtension[]) => Promise<ApplicationBuilder>;
|
||||
removeMainExtensions: (...extensions: LensMainExtension[]) => ApplicationBuilder;
|
||||
|
||||
extensions: {
|
||||
renderer: {
|
||||
enable: EnableExtensions<LensRendererExtension>;
|
||||
disable: DisableExtensions<LensRendererExtension>;
|
||||
};
|
||||
|
||||
main: {
|
||||
enable: EnableExtensions<LensMainExtension>;
|
||||
disable: DisableExtensions<LensMainExtension>;
|
||||
};
|
||||
};
|
||||
|
||||
allowKubeResource: (resourceName: KubeResource) => ApplicationBuilder;
|
||||
beforeApplicationStart: (callback: Callback) => ApplicationBuilder;
|
||||
beforeRender: (callback: Callback) => ApplicationBuilder;
|
||||
@ -139,7 +153,7 @@ export const getApplicationBuilder = () => {
|
||||
const beforeApplicationStartCallbacks: Callback[] = [];
|
||||
const beforeRenderCallbacks: Callback[] = [];
|
||||
|
||||
const extensionsState = observable.array<LensRendererExtension>();
|
||||
const rendererExtensionsState = observable.set<LensRendererExtension>();
|
||||
const mainExtensionsState = observable.set<LensMainExtension>();
|
||||
|
||||
rendererDi.override(subscribeStoresInjectable, () => () => () => {});
|
||||
@ -179,7 +193,7 @@ export const getApplicationBuilder = () => {
|
||||
);
|
||||
|
||||
rendererDi.override(rendererExtensionsInjectable, () =>
|
||||
computed(() => extensionsState),
|
||||
computed(() => [...rendererExtensionsState]),
|
||||
);
|
||||
|
||||
mainDi.override(mainExtensionsInjectable, () =>
|
||||
@ -204,6 +218,43 @@ export const getApplicationBuilder = () => {
|
||||
let allowedResourcesState: IObservableArray<KubeResource>;
|
||||
let rendered: RenderResult;
|
||||
|
||||
const enableExtensionsFor = <T extends ObservableSet>(
|
||||
extensionState: T,
|
||||
di: DiContainer,
|
||||
) => {
|
||||
let index = 0;
|
||||
|
||||
return async (...extensions: LensExtension[]) => {
|
||||
const extensionRegistrators = di.injectMany(
|
||||
extensionRegistratorInjectionToken,
|
||||
);
|
||||
|
||||
const addAndEnableExtensions = async () => {
|
||||
index++;
|
||||
|
||||
const registratorPromises = extensions.flatMap((extension) =>
|
||||
extensionRegistrators.map((registrator) =>
|
||||
registrator(extension, index),
|
||||
),
|
||||
);
|
||||
|
||||
await Promise.all(registratorPromises);
|
||||
|
||||
runInAction(() => {
|
||||
extensions.forEach((extension) => {
|
||||
extensionState.add(extension);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (rendered) {
|
||||
await addAndEnableExtensions();
|
||||
} else {
|
||||
builder.beforeRender(addAndEnableExtensions);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const builder: ApplicationBuilder = {
|
||||
dis,
|
||||
|
||||
@ -349,70 +400,16 @@ export const getApplicationBuilder = () => {
|
||||
return builder;
|
||||
},
|
||||
|
||||
addExtensions: async (...extensions) => {
|
||||
const extensionRegistrators = rendererDi.injectMany(
|
||||
extensionRegistratorInjectionToken,
|
||||
);
|
||||
extensions: {
|
||||
renderer: {
|
||||
enable: enableExtensionsFor(rendererExtensionsState, rendererDi),
|
||||
disable: disableExtensionsFor(rendererExtensionsState),
|
||||
},
|
||||
|
||||
const addAndEnableExtensions = async () => {
|
||||
const registratorPromises = extensions.flatMap((extension) =>
|
||||
extensionRegistrators.map((registrator) => registrator(extension, 1)),
|
||||
);
|
||||
|
||||
await Promise.all(registratorPromises);
|
||||
|
||||
runInAction(() => {
|
||||
extensions.forEach((extension) => {
|
||||
extensionsState.push(extension);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (rendered) {
|
||||
await addAndEnableExtensions();
|
||||
} else {
|
||||
builder.beforeRender(addAndEnableExtensions);
|
||||
}
|
||||
|
||||
return builder;
|
||||
},
|
||||
|
||||
addMainExtensions: async (...extensions) => {
|
||||
const extensionRegistrators = mainDi.injectMany(
|
||||
extensionRegistratorInjectionToken,
|
||||
);
|
||||
|
||||
const addAndEnableExtensions = async () => {
|
||||
const registratorPromises = extensions.flatMap((extension) =>
|
||||
extensionRegistrators.map((registrator) => registrator(extension, 1)),
|
||||
);
|
||||
|
||||
await Promise.all(registratorPromises);
|
||||
|
||||
runInAction(() => {
|
||||
extensions.forEach((extension) => {
|
||||
mainExtensionsState.add(extension);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (rendered) {
|
||||
await addAndEnableExtensions();
|
||||
} else {
|
||||
builder.beforeRender(addAndEnableExtensions);
|
||||
}
|
||||
|
||||
return builder;
|
||||
},
|
||||
|
||||
removeMainExtensions: (...extensions) => {
|
||||
extensions.forEach(extension => {
|
||||
runInAction(() => {
|
||||
mainExtensionsState.delete(extension);
|
||||
});
|
||||
});
|
||||
|
||||
return builder;
|
||||
main: {
|
||||
enable: enableExtensionsFor(mainExtensionsState, mainDi),
|
||||
disable: disableExtensionsFor(mainExtensionsState),
|
||||
},
|
||||
},
|
||||
|
||||
allowKubeResource: (resourceName) => {
|
||||
@ -536,3 +533,14 @@ function toFlatChildren(parentId: string | null | undefined): ToFlatChildren {
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
const disableExtensionsFor =
|
||||
<T extends ObservableSet>(extensionState: T) =>
|
||||
|
||||
(...extensions: LensExtension[]) => {
|
||||
extensions.forEach((extension) => {
|
||||
runInAction(() => {
|
||||
extensionState.delete(extension);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user