mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Kludge "isEnabledForCluster" work again for cluster pages
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
d44599af00
commit
2010df9cb5
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||
import type { TestExtensionRenderer } from "../../../renderer/components/test-utils/get-extension-fake";
|
||||
import { getExtensionFakeFor } from "../../../renderer/components/test-utils/get-extension-fake";
|
||||
import type { KubernetesCluster } from "../../../common/catalog-entities";
|
||||
import React from "react";
|
||||
import extensionShouldBeEnabledForClusterFrameInjectable from "../../../renderer/extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||
|
||||
describe("disable-cluster-pages-when-cluster-is-not-relevant", () => {
|
||||
let builder: ApplicationBuilder;
|
||||
let rendered: RenderResult;
|
||||
let rendererTestExtension: TestExtensionRenderer;
|
||||
let isEnabledForClusterMock: AsyncFnMock<(cluster: KubernetesCluster) => boolean>;
|
||||
|
||||
beforeEach(async () => {
|
||||
builder = getApplicationBuilder();
|
||||
|
||||
builder.setEnvironmentToClusterFrame();
|
||||
|
||||
builder.dis.rendererDi.unoverride(extensionShouldBeEnabledForClusterFrameInjectable);
|
||||
|
||||
const getExtensionFake = getExtensionFakeFor(builder);
|
||||
|
||||
isEnabledForClusterMock = asyncFn();
|
||||
|
||||
const testExtension = getExtensionFake({
|
||||
id: "test-extension-id",
|
||||
name: "test-extension",
|
||||
|
||||
rendererOptions: {
|
||||
isEnabledForCluster: isEnabledForClusterMock,
|
||||
|
||||
clusterPages: [{
|
||||
components: {
|
||||
Page: () => <div data-testid="some-test-page">Some page</div>,
|
||||
},
|
||||
}],
|
||||
},
|
||||
});
|
||||
|
||||
rendererTestExtension = testExtension.renderer;
|
||||
|
||||
rendered = await builder.render();
|
||||
|
||||
builder.extensions.enable(testExtension);
|
||||
});
|
||||
|
||||
describe("given not yet known if extension should be enabled for the cluster, when navigating", () => {
|
||||
beforeEach(() => {
|
||||
rendererTestExtension.navigate();
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not show the page", () => {
|
||||
const actual = rendered.queryByTestId("some-test-page");
|
||||
|
||||
expect(actual).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("given extension shouldn't be enabled for the cluster, when navigating", () => {
|
||||
beforeEach(async () => {
|
||||
await isEnabledForClusterMock.resolve(false);
|
||||
|
||||
rendererTestExtension.navigate();
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("does not show the page", () => {
|
||||
const actual = rendered.queryByTestId("some-test-page");
|
||||
|
||||
expect(actual).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("given extension should be enabled for the cluster, when navigating", () => {
|
||||
beforeEach(async () => {
|
||||
await isEnabledForClusterMock.resolve(true);
|
||||
|
||||
rendererTestExtension.navigate();
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(rendered.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("shows the page", () => {
|
||||
const actual = rendered.getByTestId("some-test-page");
|
||||
|
||||
expect(actual).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import type { KubernetesCluster } from "../../common/catalog-entities";
|
||||
import type { LensRendererExtension } from "../lens-renderer-extension";
|
||||
|
||||
interface ExtensionIsEnabledForCluster {
|
||||
extension: LensRendererExtension;
|
||||
cluster: KubernetesCluster;
|
||||
}
|
||||
|
||||
const extensionIsEnabledForClusterInjectable = getInjectable({
|
||||
id: "extension-is-enabled-for-cluster",
|
||||
|
||||
instantiate: async (
|
||||
di,
|
||||
{ extension, cluster }: ExtensionIsEnabledForCluster,
|
||||
) => (await extension.isEnabledForCluster(cluster)) as boolean,
|
||||
|
||||
lifecycle: lifecycleEnum.keyedSingleton({
|
||||
getInstanceKey: (
|
||||
di,
|
||||
{ extension, cluster }: ExtensionIsEnabledForCluster,
|
||||
) => `${extension.sanitizedExtensionId}-${cluster.getId()}`,
|
||||
}),
|
||||
});
|
||||
|
||||
export default extensionIsEnabledForClusterInjectable;
|
||||
@ -9,6 +9,9 @@ import { createExtensionInstanceInjectionToken } from "./create-extension-instan
|
||||
import extensionInstancesInjectable from "./extension-instances.injectable";
|
||||
import type { LensExtension } from "../lens-extension";
|
||||
import extensionInjectable from "./extension/extension.injectable";
|
||||
import type { LensRendererExtension } from "../lens-renderer-extension";
|
||||
import extensionIsEnabledForClusterInjectable from "./extension-is-enabled-for-cluster.injectable";
|
||||
import type { KubernetesCluster } from "../../common/catalog-entities";
|
||||
|
||||
const extensionLoaderInjectable = getInjectable({
|
||||
id: "extension-loader",
|
||||
@ -18,6 +21,11 @@ const extensionLoaderInjectable = getInjectable({
|
||||
createExtensionInstance: di.inject(createExtensionInstanceInjectionToken),
|
||||
extensionInstances: di.inject(extensionInstancesInjectable),
|
||||
getExtension: (instance: LensExtension) => di.inject(extensionInjectable, instance),
|
||||
|
||||
getExtensionIsEnabledForCluster: (extension: LensRendererExtension, cluster: KubernetesCluster) => di.inject(extensionIsEnabledForClusterInjectable, {
|
||||
extension,
|
||||
cluster,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ interface Dependencies {
|
||||
createExtensionInstance: CreateExtensionInstance;
|
||||
readonly extensionInstances: ObservableMap<LensExtensionId, LensExtension>;
|
||||
getExtension: (instance: LensExtension) => Extension;
|
||||
getExtensionIsEnabledForCluster: (extension: LensRendererExtension, cluster: KubernetesCluster) => Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface ExtensionLoading {
|
||||
@ -282,7 +283,7 @@ export class ExtensionLoader {
|
||||
const extension = ext as LensRendererExtension;
|
||||
|
||||
// getCluster must be a callback, as the entity might be available only after an extension has been loaded
|
||||
if ((await extension.isEnabledForCluster(entity)) === false) {
|
||||
if (await this.dependencies.getExtensionIsEnabledForCluster(extension, entity)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@ -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 catalogEntityRegistryInjectable from "../api/catalog/entity/registry.injectable";
|
||||
import { computed } from "mobx";
|
||||
import { isKubernetesCluster } from "../../common/catalog-entities";
|
||||
|
||||
const activeKubernetesClusterInjectable = getInjectable({
|
||||
id: "active-kubernetes-cluster",
|
||||
|
||||
instantiate: (di) => {
|
||||
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||
|
||||
return computed(() => {
|
||||
const activeEntity = catalogEntityRegistry.activeEntity;
|
||||
|
||||
if (!isKubernetesCluster(activeEntity)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return activeEntity;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default activeKubernetesClusterInjectable;
|
||||
@ -58,6 +58,8 @@ import { renderFor } from "./renderFor";
|
||||
import { RootFrame } from "../../frames/root-frame/root-frame";
|
||||
import { ClusterFrame } from "../../frames/cluster-frame/cluster-frame";
|
||||
import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluster-id.injectable";
|
||||
import activeKubernetesClusterInjectable from "../../cluster-frame-context/active-kubernetes-cluster.injectable";
|
||||
import { catalogEntityFromCluster } from "../../../main/cluster-manager";
|
||||
|
||||
type Callback = (dis: DiContainers) => void | Promise<void>;
|
||||
|
||||
@ -382,6 +384,10 @@ export const getApplicationBuilder = () => {
|
||||
accessibleNamespaces: [],
|
||||
} as unknown as Cluster;
|
||||
|
||||
rendererDi.override(activeKubernetesClusterInjectable, () =>
|
||||
computed(() => catalogEntityFromCluster(clusterStub)),
|
||||
);
|
||||
|
||||
const namespaceStoreStub = {
|
||||
contextNamespaces: [],
|
||||
items: [],
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||
import type { LensRendererExtension } from "../../extensions/lens-renderer-extension";
|
||||
import type { KubernetesCluster } from "../../common/catalog-entities";
|
||||
import extensionIsEnabledForClusterInjectable from "../../extensions/extension-loader/extension-is-enabled-for-cluster.injectable";
|
||||
import activeKubernetesClusterInjectable from "../cluster-frame-context/active-kubernetes-cluster.injectable";
|
||||
|
||||
const extensionShouldBeEnabledForClusterFrameInjectable = getInjectable({
|
||||
id: "extension-should-be-enabled-for-cluster-frame",
|
||||
|
||||
instantiate: (di, extension: LensRendererExtension) => {
|
||||
const activeKubernetesCluster = di.inject(activeKubernetesClusterInjectable);
|
||||
|
||||
const getExtensionIsEnabledForCluster = (
|
||||
extension: LensRendererExtension,
|
||||
cluster: KubernetesCluster,
|
||||
) =>
|
||||
di.inject(extensionIsEnabledForClusterInjectable, { extension, cluster });
|
||||
|
||||
return asyncComputed(
|
||||
async () => {
|
||||
const cluster = activeKubernetesCluster.get();
|
||||
|
||||
if (!cluster) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getExtensionIsEnabledForCluster(
|
||||
extension,
|
||||
cluster,
|
||||
);
|
||||
},
|
||||
|
||||
false,
|
||||
);
|
||||
},
|
||||
|
||||
lifecycle: lifecycleEnum.keyedSingleton({
|
||||
getInstanceKey: (di, extension: LensRendererExtension) =>
|
||||
extension.sanitizedExtensionId,
|
||||
}),
|
||||
});
|
||||
|
||||
export default extensionShouldBeEnabledForClusterFrameInjectable;
|
||||
@ -69,6 +69,8 @@ import kubeObjectDetailsClusterFrameChildComponentInjectable from "./components/
|
||||
import kubeconfigDialogClusterFrameChildComponentInjectable from "./components/kubeconfig-dialog/kubeconfig-dialog-cluster-frame-child-component.injectable";
|
||||
import portForwardDialogClusterFrameChildComponentInjectable from "./port-forward/port-forward-dialog-cluster-frame-child-component.injectable";
|
||||
import setupSystemCaInjectable from "./frames/root-frame/setup-system-ca.injectable";
|
||||
import extensionShouldBeEnabledForClusterFrameInjectable from "./extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||
|
||||
export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {}) => {
|
||||
const {
|
||||
@ -119,6 +121,11 @@ export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {})
|
||||
shouldRender: computed(() => false),
|
||||
}));
|
||||
|
||||
// TODO: Remove after "LensRendererExtension.isEnabledForCluster" is removed
|
||||
di.override(extensionShouldBeEnabledForClusterFrameInjectable, () =>
|
||||
asyncComputed(async () => true, true),
|
||||
);
|
||||
|
||||
// TODO: Remove side-effects and shared global state
|
||||
const clusterFrameChildComponentInjectables: Injectable<any, any, any>[] = [
|
||||
commandContainerClusterFrameChildComponentInjectable,
|
||||
|
||||
@ -14,9 +14,11 @@ import { extensionRegistratorInjectionToken } from "../../extensions/extension-l
|
||||
import { SiblingsInTabLayout } from "../components/layout/siblings-in-tab-layout";
|
||||
import extensionPageParametersInjectable from "./extension-page-parameters.injectable";
|
||||
import { routeSpecificComponentInjectionToken } from "./route-specific-component-injection-token";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { computed } from "mobx";
|
||||
import { frontEndRouteInjectionToken } from "../../common/front-end-routing/front-end-route-injection-token";
|
||||
import { getExtensionRoutePath } from "./for-extension";
|
||||
import extensionShouldBeEnabledForClusterFrameInjectable from "../extension-loader/extension-should-be-enabled-for-cluster-frame.injectable";
|
||||
|
||||
const extensionRouteRegistratorInjectable = getInjectable({
|
||||
id: "extension-route-registrator",
|
||||
@ -24,14 +26,27 @@ const extensionRouteRegistratorInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
return (ext) => {
|
||||
const extension = ext as LensRendererExtension;
|
||||
const toRouteInjectable = toRouteInjectableFor(
|
||||
di,
|
||||
const toRouteInjectable = toRouteInjectableFor(di, extension);
|
||||
|
||||
const extensionShouldBeEnabledForClusterFrame = di.inject(
|
||||
extensionShouldBeEnabledForClusterFrameInjectable,
|
||||
extension,
|
||||
);
|
||||
|
||||
return [
|
||||
...extension.globalPages.map(toRouteInjectable(false)),
|
||||
...extension.clusterPages.map(toRouteInjectable(true)),
|
||||
...extension.globalPages.map(
|
||||
toRouteInjectable(
|
||||
false,
|
||||
computed(() => true),
|
||||
),
|
||||
),
|
||||
|
||||
...extension.clusterPages.map(
|
||||
toRouteInjectable(
|
||||
true,
|
||||
computed(() => extensionShouldBeEnabledForClusterFrame.value.get()),
|
||||
),
|
||||
),
|
||||
].flat();
|
||||
};
|
||||
},
|
||||
@ -46,7 +61,7 @@ const toRouteInjectableFor =
|
||||
di: DiContainerForInjection,
|
||||
extension: LensRendererExtension,
|
||||
) =>
|
||||
(clusterFrame: boolean) =>
|
||||
(clusterFrame: boolean, isEnabled: IComputedValue<boolean>) =>
|
||||
(registration: PageRegistration) => {
|
||||
const routeInjectable = getInjectable({
|
||||
id: `route-${registration.id}-for-extension-${extension.sanitizedExtensionId}`,
|
||||
@ -54,7 +69,7 @@ const toRouteInjectableFor =
|
||||
instantiate: () => ({
|
||||
path: getExtensionRoutePath(extension, registration.id),
|
||||
clusterFrame,
|
||||
isEnabled: computed(() => true),
|
||||
isEnabled,
|
||||
extension,
|
||||
}),
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user