From 27ec0573a3e24d36e33a4b57460708c5b8daf574 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 20 Apr 2022 17:09:11 -0400 Subject: [PATCH] try and fix behavioural tests Signed-off-by: Sebastian Malton --- ...debar-and-tab-navigation-for-core.test.tsx | 42 ++++++----- ...and-tab-navigation-for-extensions.test.tsx | 70 +++++++++---------- .../visibility-of-sidebar-items.test.tsx | 10 +-- src/behaviours/utils.ts | 12 ++++ src/common/k8s-api/kube-api.ts | 21 +++--- src/extensions/common-api/k8s-api.ts | 5 +- ...stom-resource-sidebar-items.injectable.tsx | 26 +++---- .../components/layout/main-layout.tsx | 17 ++--- .../components/layout/sidebar-item.tsx | 16 ++--- .../test-utils/get-application-builder.tsx | 19 ++--- .../utils/create-storage/create-storage.ts | 13 ++-- src/renderer/utils/storageHelper.ts | 19 +++-- src/test-utils/override-fs-with-fakes.ts | 47 ++++--------- 13 files changed, 141 insertions(+), 176 deletions(-) create mode 100644 src/behaviours/utils.ts diff --git a/src/behaviours/cluster/sidebar-and-tab-navigation-for-core.test.tsx b/src/behaviours/cluster/sidebar-and-tab-navigation-for-core.test.tsx index aad53c4fd9..2889ba17fc 100644 --- a/src/behaviours/cluster/sidebar-and-tab-navigation-for-core.test.tsx +++ b/src/behaviours/cluster/sidebar-and-tab-navigation-for-core.test.tsx @@ -21,6 +21,9 @@ import writeJsonFileInjectable from "../../common/fs/write-json-file.injectable" import pathExistsInjectable from "../../common/fs/path-exists.injectable"; import readJsonFileInjectable from "../../common/fs/read-json-file.injectable"; import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token"; +import { getSidebarItem } from "../utils"; +import createStoresAndApisInjectable from "../../renderer/create-stores-apis.injectable"; +import sidebarStorageInjectable from "../../renderer/components/layout/sidebar-storage/sidebar-storage.injectable"; describe("cluster - sidebar and tab navigation for core", () => { let applicationBuilder: ApplicationBuilder; @@ -33,8 +36,8 @@ describe("cluster - sidebar and tab navigation for core", () => { applicationBuilder = getApplicationBuilder(); rendererDi = applicationBuilder.dis.rendererDi; + rendererDi.override(createStoresAndApisInjectable, () => true); applicationBuilder.setEnvironmentToClusterFrame(); - applicationBuilder.beforeSetups(({ rendererDi }) => { rendererDi.override( directoryForLensLocalStorageInjectable, @@ -72,13 +75,13 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent is highlighted", () => { const parent = getSidebarItem(rendered, "some-parent-id"); - expect(parent.dataset.isActiveTest).toBe("true"); + expect(parent?.dataset.isActiveTest).toBe("true"); }); it("parent sidebar item is not expanded", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); it("child page is shown", () => { @@ -101,6 +104,12 @@ describe("cluster - sidebar and tab navigation for core", () => { }, ); }); + applicationBuilder.beforeRender(async ({ rendererDi }) => { + const sidebarStorage = rendererDi.inject(sidebarStorageInjectable); + + await sidebarStorage.whenReady; + console.log({ ...sidebarStorage.get() }); + }); rendered = await applicationBuilder.render(); }); @@ -112,13 +121,13 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent sidebar item is not highlighted", () => { const parent = getSidebarItem(rendered, "some-parent-id"); - expect(parent.dataset.isActiveTest).toBe("false"); + expect(parent?.dataset.isActiveTest).toBe("false"); }); it("parent sidebar item is expanded", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child).not.toBe(null); + expect(child).not.toBeUndefined(); }); }); @@ -148,7 +157,7 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent sidebar item is not expanded", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); }); @@ -175,7 +184,7 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent sidebar item is not expanded", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); }); @@ -191,13 +200,13 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent sidebar item is not highlighted", () => { const parent = getSidebarItem(rendered, "some-parent-id"); - expect(parent.dataset.isActiveTest).toBe("false"); + expect(parent?.dataset.isActiveTest).toBe("false"); }); it("parent sidebar item is not expanded", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); describe("when a parent sidebar item is expanded", () => { @@ -216,13 +225,13 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent sidebar item is not highlighted", () => { const parent = getSidebarItem(rendered, "some-parent-id"); - expect(parent.dataset.isActiveTest).toBe("false"); + expect(parent?.dataset.isActiveTest).toBe("false"); }); it("parent sidebar item is expanded", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child).not.toBe(null); + expect(child).not.toBeUndefined(); }); describe("when a child of the parent is selected", () => { @@ -241,13 +250,13 @@ describe("cluster - sidebar and tab navigation for core", () => { it("parent is highlighted", () => { const parent = getSidebarItem(rendered, "some-parent-id"); - expect(parent.dataset.isActiveTest).toBe("true"); + expect(parent?.dataset.isActiveTest).toBe("true"); }); it("child is highlighted", () => { const child = getSidebarItem(rendered, "some-child-id"); - expect(child.dataset.isActiveTest).toBe("true"); + expect(child?.dataset.isActiveTest).toBe("true"); }); it("child page is shown", () => { @@ -288,11 +297,6 @@ describe("cluster - sidebar and tab navigation for core", () => { }); }); -const getSidebarItem = (rendered: RenderResult, itemId: string) => - rendered - .queryAllByTestId("sidebar-item") - .find((x) => x.dataset.idTest === itemId) || null; - const testSidebarItemsInjectable = getInjectable({ id: "some-sidebar-items-injectable", @@ -325,7 +329,7 @@ const testSidebarItemsInjectable = getInjectable({ injectionToken: sidebarItemsInjectionToken, }); -const testRouteInjectable = getInjectable({ +const testRouteInjectable = getInjectable({ id: "some-route-injectable-id", instantiate: () => ({ diff --git a/src/behaviours/cluster/sidebar-and-tab-navigation-for-extensions.test.tsx b/src/behaviours/cluster/sidebar-and-tab-navigation-for-extensions.test.tsx index 273a19840c..3d5762b8f8 100644 --- a/src/behaviours/cluster/sidebar-and-tab-navigation-for-extensions.test.tsx +++ b/src/behaviours/cluster/sidebar-and-tab-navigation-for-extensions.test.tsx @@ -6,7 +6,7 @@ import React from "react"; import type { RenderResult } from "@testing-library/react"; import { fireEvent } from "@testing-library/react"; import { getRendererExtensionFake } from "../../renderer/components/test-utils/get-renderer-extension-fake"; -import type { LensRendererExtension } from "../../extensions/lens-renderer-extension"; +import { LensRendererExtension } from "../../extensions/lens-renderer-extension"; import directoryForLensLocalStorageInjectable from "../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; import routesInjectable from "../../renderer/routes/routes.injectable"; import { matches } from "lodash/fp"; @@ -17,6 +17,8 @@ import pathExistsInjectable from "../../common/fs/path-exists.injectable"; import readJsonFileInjectable from "../../common/fs/read-json-file.injectable"; import type { DiContainer } from "@ogre-tools/injectable"; import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token"; +import assert from "assert"; +import { getSidebarItem } from "../utils"; describe("cluster - sidebar and tab navigation for extensions", () => { let applicationBuilder: ApplicationBuilder; @@ -41,9 +43,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { describe("given extension with cluster pages and cluster page menus", () => { beforeEach(async () => { - const testExtension = getRendererExtensionFake( - extensionStubWithSidebarItems, - ); + const testExtension = getRendererExtensionFake(extensionStubWithSidebarItems); await applicationBuilder.addExtensions(testExtension); }); @@ -51,9 +51,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { describe("given no state for expanded sidebar items exists, and navigated to child sidebar item, when rendered", () => { beforeEach(async () => { applicationBuilder.beforeRender(({ rendererDi }) => { - const navigateToRoute = rendererDi.inject( - navigateToRouteInjectionToken, - ); + const navigateToRoute = rendererDi.inject(navigateToRouteInjectionToken); const route = rendererDi .inject(routesInjectable) @@ -64,6 +62,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { }), ); + assert(route); navigateToRoute(route); }); @@ -80,7 +79,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-parent-id", ); - expect(parent.dataset.isActiveTest).toBe("true"); + expect(parent?.dataset.isActiveTest).toBe("true"); }); it("parent sidebar item is not expanded", () => { @@ -89,7 +88,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); it("child page is shown", () => { @@ -126,7 +125,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-parent-id", ); - expect(parent.dataset.isActiveTest).toBe("false"); + expect(parent?.dataset.isActiveTest).toBe("false"); }); it("parent sidebar item is expanded", () => { @@ -135,7 +134,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child).not.toBe(null); + expect(child).not.toBeUndefined(); }); }); @@ -168,7 +167,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); }); @@ -198,7 +197,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); }); @@ -217,7 +216,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-parent-id", ); - expect(parent.dataset.isActiveTest).toBe("false"); + expect(parent?.dataset.isActiveTest).toBe("false"); }); it("parent sidebar item is not expanded", () => { @@ -226,7 +225,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child).toBe(null); + expect(child).toBeUndefined(); }); describe("when a parent sidebar item is expanded", () => { @@ -248,7 +247,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-parent-id", ); - expect(parent.dataset.isActiveTest).toBe("false"); + expect(parent?.dataset.isActiveTest).toBe("false"); }); it("parent sidebar item is expanded", () => { @@ -257,7 +256,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child).not.toBe(null); + expect(child).not.toBeUndefined(); }); describe("when a child of the parent is selected", () => { @@ -279,7 +278,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-parent-id", ); - expect(parent.dataset.isActiveTest).toBe("true"); + expect(parent?.dataset.isActiveTest).toBe("true"); }); it("child is highlighted", () => { @@ -288,7 +287,7 @@ describe("cluster - sidebar and tab navigation for extensions", () => { "some-extension-id-some-child-id", ); - expect(child.dataset.isActiveTest).toBe("true"); + expect(child?.dataset.isActiveTest).toBe("true"); }); it("child page is shown", () => { @@ -385,10 +384,8 @@ describe("cluster - sidebar and tab navigation for extensions", () => { }); }); -const extensionStubWithSidebarItems: Partial = { - id: "some-extension-id", - - clusterPages: [ +const extensionStubWithSidebarItems = new (class extends LensRendererExtension { + clusterPages = [ { components: { Page: () => { @@ -396,7 +393,6 @@ const extensionStubWithSidebarItems: Partial = { }, }, }, - { id: "some-child-page-id", @@ -404,7 +400,6 @@ const extensionStubWithSidebarItems: Partial = { Page: () =>
Some child page
, }, }, - { id: "some-other-child-page-id", @@ -414,9 +409,9 @@ const extensionStubWithSidebarItems: Partial = { ), }, }, - ], + ]; - clusterPageMenus: [ + clusterPageMenus = [ { id: "some-parent-id", title: "Parent", @@ -433,7 +428,7 @@ const extensionStubWithSidebarItems: Partial = { title: "Child 1", components: { - Icon: null, + Icon: null as never, }, }, @@ -444,13 +439,16 @@ const extensionStubWithSidebarItems: Partial = { title: "Child 2", components: { - Icon: null, + Icon: null as never, }, }, - ], -}; - -const getSidebarItem = (rendered: RenderResult, itemId: string) => - rendered - .queryAllByTestId("sidebar-item") - .find((x) => x.dataset.idTest === itemId) || null; + ]; +})({ + absolutePath: "/some/absolute/path", + id: "some-extension-id", + isBundled: true, + isCompatible: true, + isEnabled: true, + manifest: null as never, + manifestPath: "/some/manifest/path", +}); diff --git a/src/behaviours/cluster/visibility-of-sidebar-items.test.tsx b/src/behaviours/cluster/visibility-of-sidebar-items.test.tsx index 14f575b493..1a815d2aaa 100644 --- a/src/behaviours/cluster/visibility-of-sidebar-items.test.tsx +++ b/src/behaviours/cluster/visibility-of-sidebar-items.test.tsx @@ -14,6 +14,7 @@ import { routeInjectionToken } from "../../common/front-end-routing/route-inject import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { navigateToRouteInjectionToken } from "../../common/front-end-routing/navigate-to-route-injection-token"; +import { getSidebarItem } from "../utils"; describe("cluster - visibility of sidebar items", () => { let applicationBuilder: ApplicationBuilder; @@ -43,7 +44,7 @@ describe("cluster - visibility of sidebar items", () => { it("related sidebar item does not exist", () => { const item = getSidebarItem(rendered, "some-item-id"); - expect(item).toBeNull(); + expect(item).toBeUndefined(); }); describe("when kube resource becomes allowed", () => { @@ -58,17 +59,12 @@ describe("cluster - visibility of sidebar items", () => { it("related sidebar item exists", () => { const item = getSidebarItem(rendered, "some-item-id"); - expect(item).not.toBeNull(); + expect(item).not.toBeUndefined(); }); }); }); }); -const getSidebarItem = (rendered: RenderResult, itemId: string) => - rendered - .queryAllByTestId("sidebar-item") - .find((x) => x.dataset.idTest === itemId) || null; - const testRouteInjectable = getInjectable({ id: "some-route-injectable-id", diff --git a/src/behaviours/utils.ts b/src/behaviours/utils.ts new file mode 100644 index 0000000000..1a20ab249b --- /dev/null +++ b/src/behaviours/utils.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import type { RenderResult } from "@testing-library/react"; + +export function getSidebarItem(rendered: RenderResult, itemId: string) { + return rendered + .queryAllByTestId("sidebar-item") + .find((x) => x.dataset.idTest === itemId); +} diff --git a/src/common/k8s-api/kube-api.ts b/src/common/k8s-api/kube-api.ts index 31ff29149d..8ee1800930 100644 --- a/src/common/k8s-api/kube-api.ts +++ b/src/common/k8s-api/kube-api.ts @@ -26,9 +26,7 @@ import { Agent } from "https"; import type { Patch } from "rfc6902"; import assert from "assert"; import type { PartialDeep } from "type-fest"; -import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; -import loggerInjectable from "../logger.injectable"; -import type { Logger } from "../logger"; +import logger from "../logger"; /** * The options used for creating a `KubeApi` @@ -330,7 +328,6 @@ export class KubeApi< protected readonly doCheckPreferredVersion: boolean; protected readonly fullApiPathname: string; protected readonly fallbackApiBases: string[] | undefined; - protected readonly logger: Logger; constructor({ objectConstructor, @@ -345,12 +342,10 @@ export class KubeApi< assert(request, "request MUST be provided if not in a cluster page frame context"); const { apiBase, apiPrefix, apiGroup, apiVersion, resource } = parseKubeApi(fullApiPathname); - const di = getLegacyGlobalDiForExtensionApi(); assert(kind, "kind MUST be provied either via KubeApiOptions.kind or KubeApiOptions.objectConstructor.kind"); assert(apiPrefix, "apiBase MUST be parsable as a kubeApi selfLink style string"); - this.logger = di.inject(loggerInjectable); this.doCheckPreferredVersion = doCheckPreferredVersion; this.fallbackApiBases = fallbackApiBases; this.fullApiPathname = fullApiPathname; @@ -414,7 +409,7 @@ export class KubeApi< return await this.getLatestApiPrefixGroup(); } catch (error) { // If valid API wasn't found, log the error and return defaults below - this.logger.error(`[KUBE-API]: ${error}`); + logger.error(`[KUBE-API]: ${error}`); } } @@ -679,7 +674,7 @@ export class KubeApi< const abortController = new WrappedAbortController(opts.abortController); abortController.signal.addEventListener("abort", () => { - this.logger.info(`[KUBE-API] watch (${watchId}) aborted ${watchUrl}`); + logger.info(`[KUBE-API] watch (${watchId}) aborted ${watchUrl}`); clearTimeout(timedRetry); }); @@ -690,7 +685,7 @@ export class KubeApi< timeout: 600_000, }); - this.logger.info(`[KUBE-API] watch (${watchId}) ${retry === true ? "retried" : "started"} ${watchUrl}`); + logger.info(`[KUBE-API] watch (${watchId}) ${retry === true ? "retried" : "started"} ${watchUrl}`); responsePromise .then(response => { @@ -698,7 +693,7 @@ export class KubeApi< let requestRetried = false; if (!response.ok) { - this.logger.warn(`[KUBE-API] watch (${watchId}) error response ${watchUrl}`, { status: response.status }); + logger.warn(`[KUBE-API] watch (${watchId}) error response ${watchUrl}`, { status: response.status }); return callback(null, response); } @@ -715,7 +710,7 @@ export class KubeApi< // Close current request abortController.abort(); - this.logger.info(`[KUBE-API] Watch timeout set, but not retried, retrying now`); + logger.info(`[KUBE-API] Watch timeout set, but not retried, retrying now`); requestRetried = true; @@ -734,7 +729,7 @@ export class KubeApi< return; } - this.logger.info(`[KUBE-API] watch (${watchId}) ${eventName} ${watchUrl}`); + logger.info(`[KUBE-API] watch (${watchId}) ${eventName} ${watchUrl}`); requestRetried = true; @@ -763,7 +758,7 @@ export class KubeApi< }); }) .catch(error => { - this.logger.error(`[KUBE-API] watch (${watchId}) throwed ${watchUrl}`, error); + logger.error(`[KUBE-API] watch (${watchId}) throwed ${watchUrl}`, error); callback(null, error); }); diff --git a/src/extensions/common-api/k8s-api.ts b/src/extensions/common-api/k8s-api.ts index a477aeab2f..79db6110d0 100644 --- a/src/extensions/common-api/k8s-api.ts +++ b/src/extensions/common-api/k8s-api.ts @@ -8,7 +8,10 @@ // and to `Renderer` export { ResourceStack } from "../../common/k8s/resource-stack"; -export { apiManager } from "../../common/k8s-api/api-manager"; +import apiManagerInjectable from "../../common/k8s-api/api-manager/manager.injectable"; +import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api"; + +export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable); export { KubeApi, diff --git a/src/renderer/components/+custom-resources/custom-resource-sidebar-items.injectable.tsx b/src/renderer/components/+custom-resources/custom-resource-sidebar-items.injectable.tsx index a6e331ea09..973a0756e6 100644 --- a/src/renderer/components/+custom-resources/custom-resource-sidebar-items.injectable.tsx +++ b/src/renderer/components/+custom-resources/custom-resource-sidebar-items.injectable.tsx @@ -5,15 +5,10 @@ import { getInjectable } from "@ogre-tools/injectable"; import { noop } from "lodash/fp"; import { computed } from "mobx"; - -import type { - SidebarItemRegistration } from "../layout/sidebar-items.injectable"; -import { - sidebarItemsInjectionToken, -} from "../layout/sidebar-items.injectable"; +import type { SidebarItemRegistration } from "../layout/sidebar-items.injectable"; +import { sidebarItemsInjectionToken } from "../layout/sidebar-items.injectable"; import { Icon } from "../icon"; import React from "react"; - import crdListRouteInjectable from "../../../common/front-end-routing/routes/cluster/custom-resources/crd-list/crd-list-route.injectable"; import sidebarItemsForDefinitionGroupsInjectable from "./sidebar-items-for-definition-groups.injectable"; import routeIsActiveInjectable from "../../routes/route-is-active.injectable"; @@ -26,10 +21,7 @@ const customResourceSidebarItemsInjectable = getInjectable({ const navigateToCrdList = di.inject(navigateToCrdListInjectable); const crdListRoute = di.inject(crdListRouteInjectable); const crdListRouteIsActive = di.inject(routeIsActiveInjectable, crdListRoute); - - const definitionGroupSidebarItems = di.inject( - sidebarItemsForDefinitionGroupsInjectable, - ); + const definitionGroupSidebarItems = di.inject(sidebarItemsForDefinitionGroupsInjectable); return computed((): SidebarItemRegistration[] => { const definitionsItem = { @@ -42,12 +34,10 @@ const customResourceSidebarItemsInjectable = getInjectable({ orderNumber: 10, }; - const definitionGroupItems = definitionGroupSidebarItems.get(); - - const childrenAndGrandChildren = [ + const childrenAndGrandChildren = computed(() => [ definitionsItem, - ...definitionGroupItems, - ]; + ...definitionGroupSidebarItems.get(), + ]); const parentItem: SidebarItemRegistration = { id: "custom-resources", @@ -55,11 +45,11 @@ const customResourceSidebarItemsInjectable = getInjectable({ title: "Custom Resources", getIcon: () => , onClick: noop, - isVisible: computed(() => childrenAndGrandChildren.some(item => item.isVisible?.get())), + isVisible: computed(() => childrenAndGrandChildren.get().some(item => item.isVisible?.get())), orderNumber: 110, }; - return [parentItem, definitionsItem, ...definitionGroupItems]; + return [parentItem, definitionsItem, ...definitionGroupSidebarItems.get()]; }); }, diff --git a/src/renderer/components/layout/main-layout.tsx b/src/renderer/components/layout/main-layout.tsx index d123ffab56..30d6bc568e 100755 --- a/src/renderer/components/layout/main-layout.tsx +++ b/src/renderer/components/layout/main-layout.tsx @@ -69,15 +69,10 @@ class NonInjectedMainLayout extends React.Component( - NonInjectedMainLayout, - - { - getProps: (di, props) => ({ - sidebarStorage: di.inject(sidebarStorageInjectable), - - ...props, - }), - }, -); +export const MainLayout = withInjectables(NonInjectedMainLayout, { + getProps: (di, props) => ({ + ...props, + sidebarStorage: di.inject(sidebarStorageInjectable), + }), +}); diff --git a/src/renderer/components/layout/sidebar-item.tsx b/src/renderer/components/layout/sidebar-item.tsx index 36570131bc..605c08d10f 100644 --- a/src/renderer/components/layout/sidebar-item.tsx +++ b/src/renderer/components/layout/sidebar-item.tsx @@ -123,13 +123,9 @@ class NonInjectedSidebarItem extends React.Component< } } -export const SidebarItem = withInjectables( - NonInjectedSidebarItem, - - { - getProps: (di, props) => ({ - sidebarStorage: di.inject(sidebarStorageInjectable), - ...props, - }), - }, -); +export const SidebarItem = withInjectables(NonInjectedSidebarItem, { + getProps: (di, props) => ({ + ...props, + sidebarStorage: di.inject(sidebarStorageInjectable), + }), +}); diff --git a/src/renderer/components/test-utils/get-application-builder.tsx b/src/renderer/components/test-utils/get-application-builder.tsx index 544b183fd7..6151e48b55 100644 --- a/src/renderer/components/test-utils/get-application-builder.tsx +++ b/src/renderer/components/test-utils/get-application-builder.tsx @@ -25,7 +25,6 @@ import type { DiContainer } from "@ogre-tools/injectable"; import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable"; import type { ClusterStore } from "../../../common/cluster-store/cluster-store"; import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable"; -import type { LensMainExtension } from "../../../extensions/lens-main-extension"; import currentRouteComponentInjectable from "../../routes/current-route-component.injectable"; import { pipeline } from "@ogre-tools/fp"; import { flatMap, compact, join, get, filter } from "lodash/fp"; @@ -91,7 +90,7 @@ export const getApplicationBuilder = () => { rendererDi.override(subscribeStoresInjectable, () => () => () => {}); - const environments: Record = { + const environments = { application: { renderSidebar: () => null, @@ -100,12 +99,12 @@ export const getApplicationBuilder = () => { "Tried to allow kube resource when environment is not cluster frame.", ); }, - }, + } as Environment, clusterFrame: { renderSidebar: () => , onAllowKubeResource: () => {}, - }, + } as Environment, }; let environment = environments.application; @@ -120,7 +119,7 @@ export const getApplicationBuilder = () => { ); mainDi.override(mainExtensionsInjectable, () => - computed((): LensMainExtension[] => []), + computed(() => []), ); let allowedResourcesState: IObservableArray; @@ -182,9 +181,7 @@ export const getApplicationBuilder = () => { .map(get("id")); throw new Error( - `Tried to click navigation item "${id}" which does not exist in preferences. Available IDs are "${availableIds.join( - '", "', - )}"`, + `Tried to click navigation item "${id}" which does not exist in preferences. Available IDs are "${availableIds.join('", "')}"`, ); } @@ -268,12 +265,8 @@ export const getApplicationBuilder = () => { await runSetups(); const render = renderFor(rendererDi); - const history = rendererDi.inject(observableHistoryInjectable); - - const currentRouteComponent = rendererDi.inject( - currentRouteComponentInjectable, - ); + const currentRouteComponent = rendererDi.inject(currentRouteComponentInjectable); for (const callback of beforeRenderCallbacks) { await callback(dis); diff --git a/src/renderer/utils/create-storage/create-storage.ts b/src/renderer/utils/create-storage/create-storage.ts index f2d7b47e05..f9c7150769 100755 --- a/src/renderer/utils/create-storage/create-storage.ts +++ b/src/renderer/utils/create-storage/create-storage.ts @@ -39,20 +39,21 @@ export const createStorage = ({ }: Dependencies): CreateStorage => (key, defaultValue) => { const { logPrefix } = StorageHelper; + console.log("createStorage", { key, defaultValue }); + if (!storage.initialized) { storage.initialized = true; (async () => { const filePath = getAbsolutePath(directoryForLensLocalStorage, `${hostedClusterId || "app"}.json`); + console.log("reading from", filePath); + try { storage.data = (await readJsonFile(filePath)) as JsonObject; - } - - // eslint-disable-next-line no-empty - catch {} - - finally { + } catch { + // do nothing + } finally { if (!isTestEnv) { logger.info(`${logPrefix} loading finished for ${filePath}`); } diff --git a/src/renderer/utils/storageHelper.ts b/src/renderer/utils/storageHelper.ts index 99a5486448..6a690654da 100755 --- a/src/renderer/utils/storageHelper.ts +++ b/src/renderer/utils/storageHelper.ts @@ -4,18 +4,24 @@ */ // Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.) -import { action, comparer, computed, makeObservable, observable, toJS, when } from "mobx"; +import { action, comparer, computed, makeObservable, observable, observe, toJS, when } from "mobx"; import type { Draft } from "immer"; import { produce, isDraft } from "immer"; import { isEqual, isPlainObject } from "lodash"; import logger from "../../main/logger"; +export interface StorageChange { + key: string; + value: T | undefined; + oldValue: T | undefined; +} + export interface StorageAdapter { - [metadata: string]: any; + [metadata: string]: unknown; getItem(key: string): T | Promise; setItem(key: string, value: T): void; removeItem(key: string): void; - onChange?(change: { key: string; value: T; oldValue?: T }): void; + onChange?(change: StorageChange): void; } export interface StorageHelperOptions { @@ -61,9 +67,8 @@ export class StorageHelper implements StorageLayer { this.storage = storage; - // TODO: This code uses undocumented MobX internal to criminally permit exotic mutations without encapsulation. - this.data.observe_(({ newValue, oldValue }) => { - this.onChange(newValue as T, oldValue as T); + observe(this.data, (change) => { + this.onChange(change.newValue as T | undefined, change.oldValue as T | undefined); }); if (autoInit) { @@ -109,7 +114,7 @@ export class StorageHelper implements StorageLayer { return isEqual(value, this.defaultValue); } - protected onChange(value: T, oldValue?: T) { + protected onChange(value: T | undefined, oldValue: T | undefined) { if (!this.initialized) return; try { diff --git a/src/test-utils/override-fs-with-fakes.ts b/src/test-utils/override-fs-with-fakes.ts index ff88cff3f7..1064a36d27 100644 --- a/src/test-utils/override-fs-with-fakes.ts +++ b/src/test-utils/override-fs-with-fakes.ts @@ -8,46 +8,23 @@ import writeJsonFileInjectable from "../common/fs/write-json-file.injectable"; import readJsonFileInjectable from "../common/fs/read-json-file.injectable"; import pathExistsInjectable from "../common/fs/path-exists.injectable"; -type Override = (di: DiContainer) => void; - export const overrideFsWithFakes = (di: DiContainer) => { const state = new Map(); const readFile = readFileFor(state); - const overrides: Override[] = [ - (di) => { - di.override(readFileInjectable, () => readFile); - }, - - (di) => { - di.override( - writeJsonFileInjectable, - () => (filePath, contents) => { - state.set(filePath, JSON.stringify(contents)); - - return Promise.resolve(); - }, - ); - }, - - (di) => { - di.override(readJsonFileInjectable, () => async (filePath: string) => { - const fileContent = await readFile(filePath); - - return JSON.parse(fileContent.toString()); - }); - }, - - (di) => { - di.override( - pathExistsInjectable, - () => async (filePath: string) => Promise.resolve(state.has(filePath)), - ); - }, - ]; - - overrides.forEach(callback => callback(di)); + di.override(readFileInjectable, () => readFile); + di.override(writeJsonFileInjectable, () => ( + async (filePath, contents) => { + state.set(filePath, JSON.stringify(contents)); + } + )); + di.override(readJsonFileInjectable, () => ( + async (filePath: string) => JSON.parse(await readFile(filePath)) + )); + di.override(pathExistsInjectable, () => ( + (filePath: string) => Promise.resolve(state.has(filePath)) + )); }; const readFileFor = (state: Map) => (filePath: string) => {