From f18926ab66c06eec940764b4e89726ec42bffedf Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Tue, 19 Apr 2022 13:19:22 +0300 Subject: [PATCH] Adapt code and unit tests to recent changes in application setup and event handling Co-authored-by: Mikko Aspiala Signed-off-by: Janne Savolainen --- src/common/__tests__/cluster-store.test.ts | 37 +++--- src/common/__tests__/hotbar-store.test.ts | 107 +++++++++--------- .../extension-discovery.injectable.ts | 12 +- src/extensions/lens-main-extension.ts | 15 ++- src/extensions/main-api/catalog.ts | 9 +- .../__test__/kubeconfig-sync.test.ts | 6 +- .../kubeconfig-sync-manager.injectable.ts | 2 + .../kubeconfig-sync-manager.ts | 23 ++-- src/main/catalog-sources/weblinks.ts | 8 +- .../catalog-entity-registry.injectable.ts | 11 +- src/main/catalog/catalog-entity-registry.ts | 6 - src/main/cluster-manager.injectable.ts | 2 + src/main/cluster-manager.ts | 15 +-- ...request-single-instance-lock.injectable.ts | 18 +++ .../should-start-hidden.injectable.ts | 27 +++++ src/main/getDiForUnitTesting.ts | 45 ++++++-- .../terminal-shell-env-modifiers.ts | 9 +- .../terminal-shell-env-modify.injectable.ts | 2 + ...single-application-instance.injectable.ts} | 12 +- .../initialize-extensions.injectable.ts | 2 + .../setup-ipc-main-handlers.injectable.ts | 3 + .../setup-ipc-main-handlers.ts | 5 +- .../setup-syncing-of-weblinks.injectable.ts | 4 +- .../start-main-window.injectable.ts | 17 +-- .../setup-system-ca.injectable.ts | 2 + src/migrations/hotbar-store/5.0.0-beta.5.ts | 8 +- .../+extensions/__tests__/extensions.test.tsx | 6 +- .../test-utils/get-application-builder.tsx | 1 + 28 files changed, 259 insertions(+), 155 deletions(-) create mode 100644 src/main/electron-app/request-single-instance-lock.injectable.ts create mode 100644 src/main/electron-app/should-start-hidden.injectable.ts rename src/main/start-main-application/after-application-is-ready/implementations/{setup-single-instance-lock.injectable.ts => enforce-single-application-instance.injectable.ts} (60%) diff --git a/src/common/__tests__/cluster-store.test.ts b/src/common/__tests__/cluster-store.test.ts index c367b91728..8ddce07c18 100644 --- a/src/common/__tests__/cluster-store.test.ts +++ b/src/common/__tests__/cluster-store.test.ts @@ -83,17 +83,16 @@ describe("cluster-store", () => { beforeEach(async () => { mainDi = getDiForUnitTesting({ doGeneralOverrides: true }); - await runSetups(mainDi); - mockFs(); - mainDi.override(clusterStoreInjectable, (di) => ClusterStore.createInstance({ createCluster: di.inject(createClusterInjectionToken) })); mainDi.override(directoryForUserDataInjectable, () => "some-directory-for-user-data"); mainDi.permitSideEffects(getConfigurationFileModelInjectable); mainDi.permitSideEffects(appVersionInjectable); + mainDi.permitSideEffects(clusterStoreInjectable); - createCluster = mainDi.inject(createClusterInjectionToken); + // @ts-ignore + mainDi.unoverride(clusterStoreInjectable); }); afterEach(() => { @@ -108,10 +107,6 @@ describe("cluster-store", () => { getCustomKubeConfigDirectoryInjectable, ); - // TODO: Remove these by removing Singleton base-class from BaseStore - ClusterStore.getInstance(false)?.unregisterIpcListener(); - ClusterStore.resetInstance(); - const mockOpts = { "some-directory-for-user-data": { "lens-cluster-store.json": JSON.stringify({}), @@ -120,7 +115,13 @@ describe("cluster-store", () => { mockFs(mockOpts); + await runSetups(mainDi); + + createCluster = mainDi.inject(createClusterInjectionToken); + clusterStore = mainDi.inject(clusterStoreInjectable); + + clusterStore.unregisterIpcListener(); }); afterEach(() => { @@ -199,9 +200,7 @@ describe("cluster-store", () => { }); describe("config with existing clusters", () => { - beforeEach(() => { - ClusterStore.resetInstance(); - + beforeEach(async () => { const mockOpts = { "temp-kube-config": kubeconfig, "some-directory-for-user-data": { @@ -240,6 +239,10 @@ describe("cluster-store", () => { mockFs(mockOpts); + await runSetups(mainDi); + + createCluster = mainDi.inject(createClusterInjectionToken); + clusterStore = mainDi.inject(clusterStoreInjectable); }); @@ -267,7 +270,7 @@ describe("cluster-store", () => { }); describe("config with invalid cluster kubeconfig", () => { - beforeEach(() => { + beforeEach(async () => { const invalidKubeconfig = ` apiVersion: v1 clusters: @@ -322,6 +325,10 @@ users: mockFs(mockOpts); + await runSetups(mainDi); + + createCluster = mainDi.inject(createClusterInjectionToken); + clusterStore = mainDi.inject(clusterStoreInjectable); }); @@ -337,7 +344,7 @@ users: }); describe("pre 3.6.0-beta.1 config with an existing cluster", () => { - beforeEach(() => { + beforeEach(async () => { ClusterStore.resetInstance(); const mockOpts = { "some-directory-for-user-data": { @@ -364,6 +371,10 @@ users: mockFs(mockOpts); + await runSetups(mainDi); + + createCluster = mainDi.inject(createClusterInjectionToken); + clusterStore = mainDi.inject(clusterStoreInjectable); }); diff --git a/src/common/__tests__/hotbar-store.test.ts b/src/common/__tests__/hotbar-store.test.ts index 4254df15ee..cf570478e5 100644 --- a/src/common/__tests__/hotbar-store.test.ts +++ b/src/common/__tests__/hotbar-store.test.ts @@ -15,60 +15,8 @@ import hotbarStoreInjectable from "../hotbar-store.injectable"; import { HotbarStore } from "../hotbar-store"; import catalogCatalogEntityInjectable from "../catalog-entities/general-catalog-entities/implementations/catalog-catalog-entity.injectable"; import { runSetups } from "../setupable-injection-token/run-setups"; +import catalogEntityRegistryInjectable from "../../main/catalog/catalog-entity-registry.injectable"; -jest.mock("../../main/catalog/catalog-entity-registry", () => ({ - catalogEntityRegistry: { - items: [ - getMockCatalogEntity({ - apiVersion: "v1", - kind: "Cluster", - - status: { - phase: "Running", - }, - - metadata: { - uid: "1dfa26e2ebab15780a3547e9c7fa785c", - name: "mycluster", - source: "local", - labels: {}, - }, - }), - - getMockCatalogEntity({ - apiVersion: "v1", - kind: "Cluster", - - status: { - phase: "Running", - }, - - metadata: { - uid: "55b42c3c7ba3b04193416cda405269a5", - name: "my_shiny_cluster", - source: "remote", - labels: {}, - }, - }), - - getMockCatalogEntity({ - apiVersion: "v1", - kind: "Cluster", - - status: { - phase: "Running", - }, - - metadata: { - uid: "catalog-entity", - name: "Catalog", - source: "app", - labels: {}, - }, - }), - ], - }, -})); function getMockCatalogEntity(data: Partial & CatalogEntityKindData): CatalogEntity { return { @@ -134,6 +82,59 @@ describe("HotbarStore", () => { di.permitSideEffects(getConfigurationFileModelInjectable); di.permitSideEffects(appVersionInjectable); + di.override(catalogEntityRegistryInjectable, () => ({ + addComputedSource: (id, source) => {}, + items: [ + getMockCatalogEntity({ + apiVersion: "v1", + kind: "Cluster", + + status: { + phase: "Running", + }, + + metadata: { + uid: "1dfa26e2ebab15780a3547e9c7fa785c", + name: "mycluster", + source: "local", + labels: {}, + }, + }), + + getMockCatalogEntity({ + apiVersion: "v1", + kind: "Cluster", + + status: { + phase: "Running", + }, + + metadata: { + uid: "55b42c3c7ba3b04193416cda405269a5", + name: "my_shiny_cluster", + source: "remote", + labels: {}, + }, + }), + + getMockCatalogEntity({ + apiVersion: "v1", + kind: "Cluster", + + status: { + phase: "Running", + }, + + metadata: { + uid: "catalog-entity", + name: "Catalog", + source: "app", + labels: {}, + }, + }), + ], + })); + di.override(hotbarStoreInjectable, () => { HotbarStore.resetInstance(); diff --git a/src/extensions/extension-discovery/extension-discovery.injectable.ts b/src/extensions/extension-discovery/extension-discovery.injectable.ts index 6df2677beb..6833dda3a8 100644 --- a/src/extensions/extension-discovery/extension-discovery.injectable.ts +++ b/src/extensions/extension-discovery/extension-discovery.injectable.ts @@ -16,8 +16,8 @@ import installExtensionsInjectable from "../extension-installer/install-extensio const extensionDiscoveryInjectable = getInjectable({ id: "extension-discovery", - instantiate: (di) => { - const extensionDiscovery = new ExtensionDiscovery({ + instantiate: (di) => + new ExtensionDiscovery({ extensionLoader: di.inject(extensionLoaderInjectable), extensionsStore: di.inject(extensionsStoreInjectable), @@ -37,13 +37,7 @@ const extensionDiscoveryInjectable = getInjectable({ extensionPackageRootDirectory: di.inject( extensionPackageRootDirectoryInjectable, ), - }); - - // TODO: Missing await - extensionDiscovery.init(); - - return extensionDiscovery; - }, + }), }); export default extensionDiscoveryInjectable; diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index 9e5ddb7f4a..556691d8be 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -4,17 +4,14 @@ */ import { LensExtension } from "./lens-extension"; -import { catalogEntityRegistry } from "../main/catalog"; import type { CatalogEntity } from "../common/catalog"; import type { IObservableArray } from "mobx"; import type { MenuRegistration } from "../main/menu/menu-registration"; import type { TrayMenuRegistration } from "../main/tray/tray-menu-registration"; import type { ShellEnvModifier } from "../main/shell-session/shell-env-modifier/shell-env-modifier-registration"; -import { - Environments, - getEnvironmentSpecificLegacyGlobalDiForExtensionApi, -} from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; +import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "./as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import windowManagerInjectable from "../main/window-manager.injectable"; +import catalogEntityRegistryInjectable from "../main/catalog/catalog-entity-registry.injectable"; export class LensMainExtension extends LensExtension { appMenus: MenuRegistration[] = []; @@ -44,10 +41,18 @@ export class LensMainExtension extends LensExtension { } addCatalogSource(id: string, source: IObservableArray) { + const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main); + + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + catalogEntityRegistry.addObservableSource(`${this.name}:${id}`, source); } removeCatalogSource(id: string) { + const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main); + + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + catalogEntityRegistry.removeSource(`${this.name}:${id}`); } } diff --git a/src/extensions/main-api/catalog.ts b/src/extensions/main-api/catalog.ts index 1881f9fe85..cf2429d074 100644 --- a/src/extensions/main-api/catalog.ts +++ b/src/extensions/main-api/catalog.ts @@ -4,13 +4,18 @@ */ import type { CatalogEntity } from "../../common/catalog"; -import { catalogEntityRegistry as registry } from "../../main/catalog"; +import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; +import catalogEntityRegistryInjectable from "../../main/catalog/catalog-entity-registry.injectable"; export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog/catalog-category-registry"; export class CatalogEntityRegistry { getItemsForApiKind(apiVersion: string, kind: string): T[] { - return registry.getItemsForApiKind(apiVersion, kind); + const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main); + + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + + return catalogEntityRegistry.getItemsForApiKind(apiVersion, kind); } } diff --git a/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts b/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts index 0a736cff33..5da47128b1 100644 --- a/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts +++ b/src/main/catalog-sources/__test__/kubeconfig-sync.test.ts @@ -48,6 +48,9 @@ describe("kubeconfig-sync.source tests", () => { ClusterStore.createInstance({ createCluster: () => null }), ); + di.permitSideEffects(getConfigurationFileModelInjectable); + di.permitSideEffects(appVersionInjectable); + await runSetups(di); computeDiff = computeDiffFor({ @@ -56,9 +59,6 @@ describe("kubeconfig-sync.source tests", () => { clusterManager: di.inject(clusterManagerInjectable), }); - di.permitSideEffects(getConfigurationFileModelInjectable); - di.permitSideEffects(appVersionInjectable); - di.inject(clusterStoreInjectable); }); diff --git a/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.injectable.ts b/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.injectable.ts index 0baf1c5fcd..374c7340a9 100644 --- a/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.injectable.ts +++ b/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.injectable.ts @@ -7,6 +7,7 @@ import directoryForKubeConfigsInjectable from "../../../common/app-paths/directo import { KubeconfigSyncManager } from "./kubeconfig-sync-manager"; import { createClusterInjectionToken } from "../../../common/cluster/create-cluster-injection-token"; import clusterManagerInjectable from "../../cluster-manager.injectable"; +import catalogEntityRegistryInjectable from "../../catalog/catalog-entity-registry.injectable"; const kubeconfigSyncManagerInjectable = getInjectable({ id: "kubeconfig-sync-manager", @@ -15,6 +16,7 @@ const kubeconfigSyncManagerInjectable = getInjectable({ directoryForKubeConfigs: di.inject(directoryForKubeConfigsInjectable), createCluster: di.inject(createClusterInjectionToken), clusterManager: di.inject(clusterManagerInjectable), + catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable), }), }); diff --git a/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.ts b/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.ts index 1cbeb6663f..9d6c544cd4 100644 --- a/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.ts +++ b/src/main/catalog-sources/kubeconfig-sync-manager/kubeconfig-sync-manager.ts @@ -6,7 +6,7 @@ import type { IComputedValue, ObservableMap } from "mobx"; import { action, observable, computed, runInAction, makeObservable, observe } from "mobx"; import type { CatalogEntity } from "../../../common/catalog"; -import { catalogEntityRegistry } from "../../catalog"; +import type { CatalogEntityRegistry } from "../../catalog"; import type { FSWatcher } from "chokidar"; import { watch } from "chokidar"; import fs from "fs"; @@ -50,10 +50,11 @@ const ignoreGlobs = [ const folderSyncMaxAllowedFileReadSize = 2 * 1024 * 1024; // 2 MiB const fileSyncMaxAllowedFileReadSize = 16 * folderSyncMaxAllowedFileReadSize; // 32 MiB -interface Dependencies { +interface KubeconfigSyncManagerDependencies { directoryForKubeConfigs: string; createCluster: (model: ClusterModel) => Cluster; clusterManager: ClusterManager; + catalogEntityRegistry: CatalogEntityRegistry; } const kubeConfigSyncName = "lens:kube-sync"; @@ -63,7 +64,7 @@ export class KubeconfigSyncManager { protected syncing = false; protected syncListDisposer?: Disposer; - constructor(private dependencies: Dependencies) { + constructor(private dependencies: KubeconfigSyncManagerDependencies) { makeObservable(this); } @@ -77,7 +78,7 @@ export class KubeconfigSyncManager { logger.info(`${logPrefix} starting requested syncs`); - catalogEntityRegistry.addComputedSource(kubeConfigSyncName, computed(() => ( + this.dependencies.catalogEntityRegistry.addComputedSource(kubeConfigSyncName, computed(() => ( Array.from(iter.flatMap( this.sources.values(), ([entities]) => entities.get(), @@ -111,7 +112,7 @@ export class KubeconfigSyncManager { this.stopOldSync(filePath); } - catalogEntityRegistry.removeSource(kubeConfigSyncName); + this.dependencies.catalogEntityRegistry.removeSource(kubeConfigSyncName); this.syncing = false; } @@ -164,8 +165,14 @@ export function configToModels(rootConfig: KubeConfig, filePath: string): Update type RootSourceValue = [Cluster, CatalogEntity]; type RootSource = ObservableMap; +interface ComputeDiffDependencies { + directoryForKubeConfigs: string; + createCluster: (model: ClusterModel) => Cluster; + clusterManager: ClusterManager; +} + // exported for testing -export const computeDiff = ({ directoryForKubeConfigs, createCluster, clusterManager }: Dependencies) => (contents: string, source: RootSource, filePath: string): void => { +export const computeDiff = ({ directoryForKubeConfigs, createCluster, clusterManager }: ComputeDiffDependencies) => (contents: string, source: RootSource, filePath: string): void => { runInAction(() => { try { const { config, error } = loadConfigFromString(contents); @@ -241,7 +248,7 @@ interface DiffChangedConfigArgs { maxAllowedFileReadSize: number; } -const diffChangedConfigFor = (dependencies: Dependencies) => ({ filePath, source, stats, maxAllowedFileReadSize }: DiffChangedConfigArgs): Disposer => { +const diffChangedConfigFor = (dependencies: ComputeDiffDependencies) => ({ filePath, source, stats, maxAllowedFileReadSize }: DiffChangedConfigArgs): Disposer => { logger.debug(`${logPrefix} file changed`, { filePath }); if (stats.size >= maxAllowedFileReadSize) { @@ -297,7 +304,7 @@ const diffChangedConfigFor = (dependencies: Dependencies) => ({ filePath, source return cleanup; }; -const watchFileChanges = (filePath: string, dependencies: Dependencies): [IComputedValue, Disposer] => { +const watchFileChanges = (filePath: string, dependencies: ComputeDiffDependencies): [IComputedValue, Disposer] => { const rootSource = observable.map>(); const derivedSource = computed(() => Array.from(iter.flatMap(rootSource.values(), from => iter.map(from.values(), child => child[1])))); diff --git a/src/main/catalog-sources/weblinks.ts b/src/main/catalog-sources/weblinks.ts index 3fd0b75187..ec8bf88d24 100644 --- a/src/main/catalog-sources/weblinks.ts +++ b/src/main/catalog-sources/weblinks.ts @@ -6,7 +6,7 @@ import { computed, observable, reaction } from "mobx"; import type { WeblinkStore } from "../../common/weblink-store"; import { WebLink } from "../../common/catalog-entities"; -import { catalogEntityRegistry } from "../catalog"; +import type { CatalogEntityRegistry } from "../catalog"; import got from "got"; import type { Disposer } from "../../common/utils"; import { random } from "lodash"; @@ -28,8 +28,12 @@ async function validateLink(link: WebLink) { } } +interface Dependencies { + weblinkStore: WeblinkStore; + catalogEntityRegistry: CatalogEntityRegistry; +} -export function syncWeblinks(weblinkStore: WeblinkStore) { +export function syncWeblinks({ weblinkStore, catalogEntityRegistry }: Dependencies) { const webLinkEntities = observable.map(); function periodicallyCheckLink(link: WebLink): Disposer { diff --git a/src/main/catalog/catalog-entity-registry.injectable.ts b/src/main/catalog/catalog-entity-registry.injectable.ts index 37584bab78..7bf78e764b 100644 --- a/src/main/catalog/catalog-entity-registry.injectable.ts +++ b/src/main/catalog/catalog-entity-registry.injectable.ts @@ -3,12 +3,17 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { catalogEntityRegistry } from "./catalog-entity-registry"; +import { CatalogEntityRegistry } from "./catalog-entity-registry"; +import catalogCategoryRegistryInjectable from "../../common/catalog/catalog-category-registry.injectable"; const catalogEntityRegistryInjectable = getInjectable({ id: "catalog-entity-registry", - instantiate: () => catalogEntityRegistry, - causesSideEffects: true, + + instantiate: (di) => { + const categoryRegistryRegistry = di.inject(catalogCategoryRegistryInjectable); + + return new CatalogEntityRegistry(categoryRegistryRegistry); + }, }); export default catalogEntityRegistryInjectable; diff --git a/src/main/catalog/catalog-entity-registry.ts b/src/main/catalog/catalog-entity-registry.ts index 30c4f37781..88470eeda8 100644 --- a/src/main/catalog/catalog-entity-registry.ts +++ b/src/main/catalog/catalog-entity-registry.ts @@ -5,7 +5,6 @@ import { action, computed, type IComputedValue, type IObservableArray, makeObservable, observable } from "mobx"; import type { CatalogCategoryRegistry, CatalogEntity, CatalogEntityConstructor } from "../../common/catalog"; -import { catalogCategoryRegistry } from "../../common/catalog"; import { iter } from "../../common/utils"; export class CatalogEntityRegistry { @@ -48,8 +47,3 @@ export class CatalogEntityRegistry { return this.items.filter((item) => item instanceof constructor) as T[]; } } - -/** - * @deprecated Switch to using catalogEntityRegistryInjectable - */ -export const catalogEntityRegistry = new CatalogEntityRegistry(catalogCategoryRegistry); diff --git a/src/main/cluster-manager.injectable.ts b/src/main/cluster-manager.injectable.ts index 6b27af864e..2d0c91bbdc 100644 --- a/src/main/cluster-manager.injectable.ts +++ b/src/main/cluster-manager.injectable.ts @@ -5,6 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { ClusterManager } from "./cluster-manager"; import clusterStoreInjectable from "../common/cluster-store/cluster-store.injectable"; +import catalogEntityRegistryInjectable from "./catalog/catalog-entity-registry.injectable"; const clusterManagerInjectable = getInjectable({ id: "cluster-manager", @@ -12,6 +13,7 @@ const clusterManagerInjectable = getInjectable({ instantiate: (di) => { const clusterManager = new ClusterManager({ store: di.inject(clusterStoreInjectable), + catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable), }); clusterManager.init(); diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index df7c24769a..d9190264ad 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -10,7 +10,7 @@ import type { Cluster } from "../common/cluster/cluster"; import logger from "./logger"; import { apiKubePrefix } from "../common/vars"; import { getClusterIdFromHost } from "../common/utils"; -import { catalogEntityRegistry } from "./catalog"; +import type { CatalogEntityRegistry } from "./catalog"; import type { KubernetesClusterPrometheusMetrics } from "../common/catalog-entities/kubernetes-cluster"; import { KubernetesCluster, LensKubernetesClusterStatus } from "../common/catalog-entities/kubernetes-cluster"; import { ipcMainOn } from "../common/ipc"; @@ -24,6 +24,7 @@ const lensSpecificClusterStatuses: Set = new Set(Object.values(LensKuber interface Dependencies { store: ClusterStore; + catalogEntityRegistry: CatalogEntityRegistry; } export class ClusterManager { @@ -51,12 +52,12 @@ export class ClusterManager { ); reaction( - () => catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster) as KubernetesCluster[], + () => this.dependencies.catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster) as KubernetesCluster[], entities => this.syncClustersFromCatalog(entities), ); reaction(() => [ - catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster), + this.dependencies.catalogEntityRegistry.getItemsByEntityClass(KubernetesCluster), this.visibleCluster, ] as const, ([entities, visibleCluster]) => { for (const entity of entities) { @@ -70,7 +71,7 @@ export class ClusterManager { observe(this.deleting, change => { if (change.type === "add") { - this.updateEntityStatus(catalogEntityRegistry.getById(change.newValue)); + this.updateEntityStatus(this.dependencies.catalogEntityRegistry.getById(change.newValue)); } }); @@ -88,13 +89,13 @@ export class ClusterManager { } protected updateEntityFromCluster(cluster: Cluster) { - const index = catalogEntityRegistry.items.findIndex((entity) => entity.getId() === cluster.id); + const index = this.dependencies.catalogEntityRegistry.items.findIndex((entity) => entity.getId() === cluster.id); if (index === -1) { return; } - const entity = catalogEntityRegistry.items[index] as KubernetesCluster; + const entity = this.dependencies.catalogEntityRegistry.items[index] as KubernetesCluster; this.updateEntityStatus(entity, cluster); @@ -135,7 +136,7 @@ export class ClusterManager { cluster.preferences.icon = undefined; } - catalogEntityRegistry.items.splice(index, 1, entity); + this.dependencies.catalogEntityRegistry.items.splice(index, 1, entity); } @action diff --git a/src/main/electron-app/request-single-instance-lock.injectable.ts b/src/main/electron-app/request-single-instance-lock.injectable.ts new file mode 100644 index 0000000000..2ab28e4d9d --- /dev/null +++ b/src/main/electron-app/request-single-instance-lock.injectable.ts @@ -0,0 +1,18 @@ +/** + * 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 requestSingleInstanceLockInjectable = getInjectable({ + id: "request-single-instance-lock", + + instantiate: (di) => { + const app = di.inject(electronAppInjectable); + + return () => app.requestSingleInstanceLock(); + }, +}); + +export default requestSingleInstanceLockInjectable; diff --git a/src/main/electron-app/should-start-hidden.injectable.ts b/src/main/electron-app/should-start-hidden.injectable.ts new file mode 100644 index 0000000000..ae59ed8a75 --- /dev/null +++ b/src/main/electron-app/should-start-hidden.injectable.ts @@ -0,0 +1,27 @@ +/** + * 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"; +import isMacInjectable from "../../common/vars/is-mac.injectable"; +import commandLineArgumentsInjectable from "../utils/command-line-arguments.injectable"; + +const shouldStartHiddenInjectable = getInjectable({ + id: "should-start-hidden", + + instantiate: (di) => { + const app = di.inject(electronAppInjectable); + const isMac = di.inject(isMacInjectable); + const commandLineArguments = di.inject(commandLineArgumentsInjectable); + + // Start the app without showing the main window when auto starting on login + // (On Windows and Linux, we get a flag. On MacOS, we get special API.) + return ( + commandLineArguments.includes("--hidden") || + (isMac && app.getLoginItemSettings().wasOpenedAsHidden) + ); + }, +}); + +export default shouldStartHiddenInjectable; diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts index e1d0953df3..a177445cbf 100644 --- a/src/main/getDiForUnitTesting.ts +++ b/src/main/getDiForUnitTesting.ts @@ -54,12 +54,24 @@ import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.inject import registerFileProtocolInjectable from "./electron-app/register-file-protocol.injectable"; import environmentVariablesInjectable from "../common/utils/environment-variables.injectable"; import disableHardwareAccelerationInjectable from "./electron-app/disable-hardware-acceleration.injectable"; -import catalogEntityRegistryInjectable from "./catalog/catalog-entity-registry.injectable"; import { CatalogCategoryRegistry } from "../common/catalog"; -import { CatalogEntityRegistry } from "./catalog"; import catalogCategoryRegistryInjectable from "../common/catalog/catalog-category-registry.injectable"; import setupIpcMainHandlersInjectable from "./start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable"; import setupLensProxyInjectable from "./start-main-application/after-application-is-ready/implementations/setup-lens-proxy.injectable"; +import setupListenerForRootFrameRenderingInjectable from "./start-main-application/after-application-is-ready/implementations/setup-listener-for-root-frame-rendering.injectable"; +import setupOsThemeUpdatesInjectable from "./start-main-application/after-application-is-ready/implementations/setup-os-theme-updates.injectable"; +import setupSentryInjectable from "./start-main-application/after-application-is-ready/implementations/setup-sentry.injectable"; +import setupShellInjectable from "./start-main-application/after-application-is-ready/implementations/setup-shell.injectable"; +import requestSingleInstanceLockInjectable from "./electron-app/request-single-instance-lock.injectable"; +import setupSyncingOfWeblinksInjectable from "./start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable"; +import shouldStartHiddenInjectable from "./electron-app/should-start-hidden.injectable"; +import stopServicesAndExitAppInjectable from "./stop-services-and-exit-app.injectable"; +import trayInjectable from "./tray/tray.injectable"; +import applicationMenuInjectable from "./menu/application-menu.injectable"; +import windowManagerInjectable from "./window-manager.injectable"; +import isDevelopmentInjectable from "../common/vars/is-development.injectable"; +import setupSystemCaInjectable + from "./start-main-application/before-application-is-ready/implementations/setup-system-ca.injectable"; export const getDiForUnitTesting = ( { doGeneralOverrides } = { doGeneralOverrides: false }, @@ -84,6 +96,7 @@ export const getDiForUnitTesting = ( di.override(isMacInjectable, () => true); di.override(isWindowsInjectable, () => false); di.override(isLinuxInjectable, () => false); + di.override(isDevelopmentInjectable, () => false); di.override(getAbsolutePathInjectable, () => getAbsolutePathFake); di.override(joinPathsInjectable, () => joinPathsFake); @@ -98,21 +111,29 @@ export const getDiForUnitTesting = ( di.override(getCommandLineSwitchInjectable, () => () => "irrelevant"); di.override(isAutoUpdateEnabledInjectable, () => () => false); di.override(registerProtocolClientInjectable, () => () => {}); - di.override(initializeExtensionsInjectable, () => ({ run: () => {} })); di.override(lensResourcesDirInjectable, () => "/irrelevant"); di.override(registerFileProtocolInjectable, () => () => {}); + di.override(requestSingleInstanceLockInjectable, () => () => true); di.override(disableHardwareAccelerationInjectable, () => () => {}); + di.override(shouldStartHiddenInjectable, () => true); + di.override(stopServicesAndExitAppInjectable, () => () => {}); + di.override(windowManagerInjectable, () => ({ ensureMainWindow: () => Promise.resolve(null) })); + + di.override(initializeExtensionsInjectable, () => ({ run: () => {} })); di.override(setupIpcMainHandlersInjectable, () => ({ run: () => {} })); di.override(setupLensProxyInjectable, () => ({ run: () => {} })); + di.override(setupListenerForRootFrameRenderingInjectable, () => ({ run: () => {} })); + di.override(setupOsThemeUpdatesInjectable, () => ({ run: () => {} })); + di.override(setupSentryInjectable, () => ({ run: () => {} })); + di.override(setupShellInjectable, () => ({ run: () => {} })); + di.override(setupSyncingOfWeblinksInjectable, () => ({ run: () => {} })); + di.override(setupSystemCaInjectable, () => ({ run: () => {} })); + + di.override(trayInjectable, () => ({ start: () => {}, stop: () => {} })); + di.override(applicationMenuInjectable, () => ({ start: () => {}, stop: () => {} })); di.override(catalogCategoryRegistryInjectable, () => new CatalogCategoryRegistry()); - di.override(catalogEntityRegistryInjectable, (diForInstantiate) => { - const catalogCategoryRegistry = diForInstantiate.inject(catalogCategoryRegistryInjectable); - - return new CatalogEntityRegistry(catalogCategoryRegistry); - }); - di.override(environmentVariablesInjectable, () => ({})); di.override(commandLineArgumentsInjectable, () => []); @@ -122,13 +143,13 @@ export const getDiForUnitTesting = ( // eslint-disable-next-line unused-imports/no-unused-vars-ts di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore); - di.override(hotbarStoreInjectable, () => ({})); + di.override(hotbarStoreInjectable, () => ({ load: () => {} })); di.override(fileSystemProvisionerStoreInjectable, () => ({}) as FileSystemProvisionerStore); // eslint-disable-next-line unused-imports/no-unused-vars-ts - di.override(clusterStoreInjectable, () => ({ getById: (id): Cluster => ({}) as Cluster }) as ClusterStore); - di.override(userStoreInjectable, () => ({}) as UserStore); + di.override(clusterStoreInjectable, () => ({ provideInitialFromMain: () => {}, getById: (id): Cluster => ({}) as Cluster }) as ClusterStore); + di.override(userStoreInjectable, () => ({ startMainReactions: () => {} }) as UserStore); di.override( getElectronAppPathInjectable, diff --git a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts index f60631e554..4ee5ff516f 100644 --- a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts +++ b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modifiers.ts @@ -7,13 +7,14 @@ import type { IComputedValue } from "mobx"; import { computed } from "mobx"; import type { ClusterId } from "../../../common/cluster-types"; import type { LensMainExtension } from "../../../extensions/lens-main-extension"; -import { catalogEntityRegistry } from "../../catalog"; - +import type { CatalogEntityRegistry } from "../../catalog"; + interface Dependencies { extensions: IComputedValue; + catalogEntityRegistry: CatalogEntityRegistry; } - -export const terminalShellEnvModify = ({ extensions }: Dependencies) => + +export const terminalShellEnvModify = ({ extensions, catalogEntityRegistry }: Dependencies) => (clusterId: ClusterId, env: Record) => { const terminalShellEnvModifiers = computed(() => ( extensions.get() diff --git a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts index c9d345c3b2..ce87c8959d 100644 --- a/src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts +++ b/src/main/shell-session/shell-env-modifier/terminal-shell-env-modify.injectable.ts @@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import mainExtensionsInjectable from "../../../extensions/main-extensions.injectable"; import { terminalShellEnvModify } from "./terminal-shell-env-modifiers"; +import catalogEntityRegistryInjectable from "../../catalog/catalog-entity-registry.injectable"; const terminalShellEnvModifyInjectable = getInjectable({ id: "terminal-shell-env-modify", @@ -13,6 +14,7 @@ const terminalShellEnvModifyInjectable = getInjectable({ instantiate: (di) => terminalShellEnvModify({ extensions: di.inject(mainExtensionsInjectable), + catalogEntityRegistry: di.inject(catalogEntityRegistryInjectable), }), }); diff --git a/src/main/start-main-application/after-application-is-ready/implementations/setup-single-instance-lock.injectable.ts b/src/main/start-main-application/after-application-is-ready/implementations/enforce-single-application-instance.injectable.ts similarity index 60% rename from src/main/start-main-application/after-application-is-ready/implementations/setup-single-instance-lock.injectable.ts rename to src/main/start-main-application/after-application-is-ready/implementations/enforce-single-application-instance.injectable.ts index 9f883ddb63..2dfb77b9b3 100644 --- a/src/main/start-main-application/after-application-is-ready/implementations/setup-single-instance-lock.injectable.ts +++ b/src/main/start-main-application/after-application-is-ready/implementations/enforce-single-application-instance.injectable.ts @@ -5,18 +5,18 @@ import { getInjectable } from "@ogre-tools/injectable"; import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token"; import exitAppInjectable from "../../../electron-app/exit-app.injectable"; -import electronAppInjectable from "../../../electron-app/electron-app.injectable"; +import requestSingleInstanceLockInjectable from "../../../electron-app/request-single-instance-lock.injectable"; -const setupSingleInstanceLockInjectable = getInjectable({ - id: "setup-single-instance-lock", +const enforceSingleApplicationInstanceInjectable = getInjectable({ + id: "enforce-single-application-instance", instantiate: (di) => { const exitApp = di.inject(exitAppInjectable); - const app = di.inject(electronAppInjectable); + const requestSingleInstanceLock = di.inject(requestSingleInstanceLockInjectable); return { run: () => { - if (!app.requestSingleInstanceLock()) { + if (!requestSingleInstanceLock()) { exitApp(); return; @@ -28,4 +28,4 @@ const setupSingleInstanceLockInjectable = getInjectable({ injectionToken: afterApplicationIsReadyInjectionToken, }); -export default setupSingleInstanceLockInjectable; +export default enforceSingleApplicationInstanceInjectable; diff --git a/src/main/start-main-application/after-application-is-ready/implementations/initialize-extensions.injectable.ts b/src/main/start-main-application/after-application-is-ready/implementations/initialize-extensions.injectable.ts index 49f14d158b..b7677d3556 100644 --- a/src/main/start-main-application/after-application-is-ready/implementations/initialize-extensions.injectable.ts +++ b/src/main/start-main-application/after-application-is-ready/implementations/initialize-extensions.injectable.ts @@ -23,6 +23,8 @@ const initializeExtensionsInjectable = getInjectable({ run: async () => { logger.info("🧩 Initializing extensions"); + await extensionDiscovery.init(); + await extensionLoader.init(); try { diff --git a/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts b/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts index 2c5ba0a23a..fa0e3f1346 100644 --- a/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts +++ b/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable.ts @@ -10,6 +10,7 @@ import clusterManagerInjectable from "../../../../cluster-manager.injectable"; import applicationMenuItemsInjectable from "../../../../menu/application-menu-items.injectable"; import getAbsolutePathInjectable from "../../../../../common/path/get-absolute-path.injectable"; import { afterApplicationIsReadyInjectionToken } from "../../after-application-is-ready-injection-token"; +import catalogEntityRegistryInjectable from "../../../../catalog/catalog-entity-registry.injectable"; const setupIpcMainHandlersInjectable = getInjectable({ id: "setup-ipc-main-handlers", @@ -24,6 +25,7 @@ const setupIpcMainHandlersInjectable = getInjectable({ const clusterManager = di.inject(clusterManagerInjectable); const applicationMenuItems = di.inject(applicationMenuItemsInjectable); const getAbsolutePath = di.inject(getAbsolutePathInjectable); + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); return { run: () => { @@ -34,6 +36,7 @@ const setupIpcMainHandlersInjectable = getInjectable({ getAbsolutePath, directoryForLensLocalStorage, clusterManager, + catalogEntityRegistry, }); }, }; diff --git a/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.ts b/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.ts index 5466175c5b..f247028bf0 100644 --- a/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.ts +++ b/src/main/start-main-application/after-application-is-ready/implementations/setup-ipc-main-handlers/setup-ipc-main-handlers.ts @@ -10,7 +10,7 @@ import type { ClusterId } from "../../../../../common/cluster-types"; import { ClusterStore } from "../../../../../common/cluster-store/cluster-store"; import { appEventBus } from "../../../../../common/app-event-bus/event-bus"; import { broadcastMainChannel, broadcastMessage, ipcMainHandle, ipcMainOn } from "../../../../../common/ipc"; -import { catalogEntityRegistry } from "../../../../catalog"; +import type { CatalogEntityRegistry } from "../../../../catalog"; import { pushCatalogToRenderer } from "../../../../catalog-pusher"; import type { ClusterManager } from "../../../../cluster-manager"; import { ResourceApplier } from "../../../../resource-applier"; @@ -30,9 +30,10 @@ interface Dependencies { getAbsolutePath: GetAbsolutePath; applicationMenuItems: IComputedValue; clusterManager: ClusterManager; + catalogEntityRegistry: CatalogEntityRegistry; } -export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLocalStorage, getAbsolutePath, clusterManager }: Dependencies) => { +export const setupIpcMainHandlers = ({ applicationMenuItems, directoryForLensLocalStorage, getAbsolutePath, clusterManager, catalogEntityRegistry }: Dependencies) => { ipcMainHandle(clusterActivateHandler, (event, clusterId: ClusterId, force = false) => { return ClusterStore.getInstance() .getById(clusterId) diff --git a/src/main/start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable.ts b/src/main/start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable.ts index 4417ffe9db..4f6a49191a 100644 --- a/src/main/start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable.ts +++ b/src/main/start-main-application/after-application-is-ready/implementations/setup-syncing-of-weblinks.injectable.ts @@ -6,16 +6,18 @@ import { getInjectable } from "@ogre-tools/injectable"; import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token"; import { syncWeblinks } from "../../../catalog-sources"; import weblinkStoreInjectable from "../../../../common/weblink-store.injectable"; +import catalogEntityRegistryInjectable from "../../../catalog/catalog-entity-registry.injectable"; const setupSyncingOfWeblinksInjectable = getInjectable({ id: "setup-syncing-of-weblinks", instantiate: (di) => { const weblinkStore = di.inject(weblinkStoreInjectable); + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); return { run: () => { - syncWeblinks(weblinkStore); + syncWeblinks({ weblinkStore, catalogEntityRegistry }); }, }; }, diff --git a/src/main/start-main-application/after-application-is-ready/implementations/start-main-window.injectable.ts b/src/main/start-main-application/after-application-is-ready/implementations/start-main-window.injectable.ts index f32b446bee..8eeabc473a 100644 --- a/src/main/start-main-application/after-application-is-ready/implementations/start-main-window.injectable.ts +++ b/src/main/start-main-application/after-application-is-ready/implementations/start-main-window.injectable.ts @@ -4,34 +4,23 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import windowManagerInjectable from "../../../window-manager.injectable"; -import electronAppInjectable from "../../../electron-app/electron-app.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; -import isMacInjectable from "../../../../common/vars/is-mac.injectable"; import { afterApplicationIsReadyInjectionToken } from "../after-application-is-ready-injection-token"; -import commandLineArgumentsInjectable from "../../../utils/command-line-arguments.injectable"; +import shouldStartHiddenInjectable from "../../../electron-app/should-start-hidden.injectable"; const startMainWindowInjectable = getInjectable({ id: "start-main-window", instantiate: (di) => { const windowManager = di.inject(windowManagerInjectable); - const app = di.inject(electronAppInjectable); const logger = di.inject(loggerInjectable); - const isMac = di.inject(isMacInjectable); - const commandLineArguments = di.inject(commandLineArgumentsInjectable); + const shouldStartHidden = di.inject(shouldStartHiddenInjectable); return { run: async () => { - - // Start the app without showing the main window when auto starting on login - // (On Windows and Linux, we get a flag. On MacOS, we get special API.) - const startHidden = - commandLineArguments.includes("--hidden") || - (isMac && app.getLoginItemSettings().wasOpenedAsHidden); - logger.info("🖥️ Starting WindowManager"); - if (!startHidden) { + if (!shouldStartHidden) { await windowManager.ensureMainWindow(); } }, diff --git a/src/main/start-main-application/before-application-is-ready/implementations/setup-system-ca.injectable.ts b/src/main/start-main-application/before-application-is-ready/implementations/setup-system-ca.injectable.ts index ca4c4ebf59..b92f4b5b3e 100644 --- a/src/main/start-main-application/before-application-is-ready/implementations/setup-system-ca.injectable.ts +++ b/src/main/start-main-application/before-application-is-ready/implementations/setup-system-ca.injectable.ts @@ -15,6 +15,8 @@ const setupSystemCaInjectable = getInjectable({ }, }), + causesSideEffects: true, + injectionToken: beforeApplicationIsReadyInjectionToken, }); diff --git a/src/migrations/hotbar-store/5.0.0-beta.5.ts b/src/migrations/hotbar-store/5.0.0-beta.5.ts index bb7ceb2567..ca6807831e 100644 --- a/src/migrations/hotbar-store/5.0.0-beta.5.ts +++ b/src/migrations/hotbar-store/5.0.0-beta.5.ts @@ -4,8 +4,11 @@ */ import type { Hotbar } from "../../common/hotbar-types"; -import { catalogEntityRegistry } from "../../main/catalog"; import type { MigrationDeclaration } from "../helpers"; +import { + getLegacyGlobalDiForExtensionApi, +} from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; +import catalogEntityRegistryInjectable from "../../main/catalog/catalog-entity-registry.injectable"; export default { version: "5.0.0-beta.5", @@ -13,6 +16,9 @@ export default { const rawHotbars = store.get("hotbars"); const hotbars: Hotbar[] = Array.isArray(rawHotbars) ? rawHotbars : []; + const di = getLegacyGlobalDiForExtensionApi(); + const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); + for (const hotbar of hotbars) { for (let i = 0; i < hotbar.items.length; i += 1) { const item = hotbar.items[i]; diff --git a/src/renderer/components/+extensions/__tests__/extensions.test.tsx b/src/renderer/components/+extensions/__tests__/extensions.test.tsx index 857b2bb379..23088eddaf 100644 --- a/src/renderer/components/+extensions/__tests__/extensions.test.tsx +++ b/src/renderer/components/+extensions/__tests__/extensions.test.tsx @@ -21,10 +21,8 @@ import { renderFor } from "../../test-utils/renderFor"; import extensionDiscoveryInjectable from "../../../../extensions/extension-discovery/extension-discovery.injectable"; import directoryForUserDataInjectable from "../../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; import directoryForDownloadsInjectable from "../../../../common/app-paths/directory-for-downloads/directory-for-downloads.injectable"; -import getConfigurationFileModelInjectable - from "../../../../common/get-configuration-file-model/get-configuration-file-model.injectable"; -import appVersionInjectable - from "../../../../common/get-configuration-file-model/app-version/app-version.injectable"; +import getConfigurationFileModelInjectable from "../../../../common/get-configuration-file-model/get-configuration-file-model.injectable"; +import appVersionInjectable from "../../../../common/get-configuration-file-model/app-version/app-version.injectable"; mockWindow(); diff --git a/src/renderer/components/test-utils/get-application-builder.tsx b/src/renderer/components/test-utils/get-application-builder.tsx index deaa51eb0b..ee6dcda7ba 100644 --- a/src/renderer/components/test-utils/get-application-builder.tsx +++ b/src/renderer/components/test-utils/get-application-builder.tsx @@ -76,6 +76,7 @@ export const getApplicationBuilder = () => { const dis = { rendererDi, mainDi }; const clusterStoreStub = { + provideInitialFromMain: () => {}, getById: (): null => null, } as unknown as ClusterStore;