1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/getDiForUnitTesting.tsx
Sebastian Malton 76066c5ebf
Making apiBase injectable (#6022)
* Making apiBase injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Convert all of Helm functions to be DI

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Make PortForward's use of apiBase fully injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Convert all metric requests to be injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Replace resource applier with injectables

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Switch KubeJsonApi.forCluster to be injectable but do not use

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Convert the rest of shell sessions to be DI-ed

- This is a prerequesit for using the new
  createKubeJsonApiForClusterInjectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Use new createKubeJsonApiForClusterInjectable for openNodeShellSession

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Make KubeconfigDialog injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove jest-fetch-mock and make fetch injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests with new global override

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Add new injectable for create KubeJsonApi and JsonApi instances

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix showing-details-for-helm-release behavioural tests

- Remove HelmChartStore in favour of all injectables

- Create a model for UpgradeChartDockTab

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix show details and updating helm releases tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix residual typing issues related to metrics

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix crash on load due to circular dependency

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix create resource tab not working

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove legacy apiBase global

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Introduce and use isDebuggingInjectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Introduce and use windowLocationInjectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove global legacy apiKube

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Improve injectable filenames compared to the injectables inside

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove modifying input in requestActivePortForwardInjectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Introduce and use get(Milli)SecondsFromUnixEpochInjectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Switch to non-reactive way of gettting possible helm release versions

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix typo

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix bug in KubeApi constructor

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Convert all KubeApi related tests to use asyncFn

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix unit tests after introducing new injectables that have side effects

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix bad rebase causing tests to fail

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Improve expects for multiple field values

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix crash will looking up api refs

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix breaking change on KubeApi.list

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Better fix for formatting urls

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove injectable for time since we should just use useMockTime

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Add happy path behavioural tests for upgrade chart tab

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove debug message

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* fix showing-details-for-helm-release tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix installing-helm-chart-from-new-tab tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests relating to hosted cluster id

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots to recent changes in master

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>

* Reupdated upgrade chart new tab test snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix flakiness in unit test when using <Animated>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix flakiness and improve tests for DeleteClusterDialog

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix kubeconfig-sync tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix <Extensions> tests by removing mockFs and making everything injectable

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix build issues

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix getElectronAppPathInjectable override not returning absolute paths

- Also fixes the listing-active-helm-repos-in-prefs tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Replace all uses of getAbsolutePath with joinPaths as it is more correct and less confusing

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix opening application window tests by making override properly absolute

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots relating no longer using getAbsolutePath

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix and add behavioural tests for RenderDelay

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix extension discovery tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix test flakiness because of path side effects, propagate uses to as many places

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix extension-discovery tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Add global override to fix some tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Rewrite and fix implementation of KubeconfigManager and its tests

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests by global override pathExists

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix unit tests failing on windows by using injectable verions of path functions

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Attempt to fix test timeout by using runInAction

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots after rebase

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots after rebase

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix tests after rebase

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix setupIpcMainHandlers usage

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>
Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>
Co-authored-by: Iku-turso <mikko.aspiala@gmail.com>
2022-10-05 08:10:36 -04:00

219 lines
11 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { noop, chunk } from "lodash/fp";
import type { DiContainer, Injectable } from "@ogre-tools/injectable";
import {
createContainer,
} from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import requestFromChannelInjectable from "./utils/channel/request-from-channel.injectable";
import loggerInjectable from "../common/logger.injectable";
import { overrideFsWithFakes } from "../test-utils/override-fs-with-fakes";
import { createMemoryHistory } from "history";
import focusWindowInjectable from "./navigation/focus-window.injectable";
import extensionsStoreInjectable from "../extensions/extensions-store/extensions-store.injectable";
import type { ExtensionsStore } from "../extensions/extensions-store/extensions-store";
import fileSystemProvisionerStoreInjectable from "../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.injectable";
import type { FileSystemProvisionerStore } from "../extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store";
import userStoreInjectable from "../common/user-store/user-store.injectable";
import type { UserStore } from "../common/user-store";
import hotbarStoreInjectable from "../common/hotbars/store.injectable";
import terminalSpawningPoolInjectable from "./components/dock/terminal/terminal-spawning-pool.injectable";
import hostedClusterIdInjectable from "./cluster-frame-context/hosted-cluster-id.injectable";
import historyInjectable from "./navigation/history.injectable";
import { ApiManager } from "../common/k8s-api/api-manager";
import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable";
import broadcastMessageInjectable from "../common/ipc/broadcast-message.injectable";
import apiManagerInjectable from "../common/k8s-api/api-manager/manager.injectable";
import { observable, computed, runInAction } from "mobx";
import defaultShellInjectable from "./components/+preferences/default-shell.injectable";
import requestAnimationFrameInjectable from "./components/animate/request-animation-frame.injectable";
import getRandomIdInjectable from "../common/utils/get-random-id.injectable";
import getFilePathsInjectable from "./components/+preferences/kubernetes/helm-charts/adding-of-custom-helm-repository/helm-file-input/get-file-paths.injectable";
import callForPublicHelmRepositoriesInjectable from "./components/+preferences/kubernetes/helm-charts/adding-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
import platformInjectable from "../common/vars/platform.injectable";
import startTopbarStateSyncInjectable from "./components/layout/top-bar/start-state-sync.injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import watchHistoryStateInjectable from "./remote-helpers/watch-history-state.injectable";
import openAppContextMenuInjectable from "./components/layout/top-bar/open-app-context-menu.injectable";
import goBackInjectable from "./components/layout/top-bar/go-back.injectable";
import goForwardInjectable from "./components/layout/top-bar/go-forward.injectable";
import closeWindowInjectable from "./components/layout/top-bar/close-window.injectable";
import maximizeWindowInjectable from "./components/layout/top-bar/maximize-window.injectable";
import toggleMaximizeWindowInjectable from "./components/layout/top-bar/toggle-maximize-window.injectable";
import type { HotbarStore } from "../common/hotbars/store";
import cronJobTriggerDialogClusterFrameChildComponentInjectable from "./components/+workloads-cronjobs/cron-job-trigger-dialog-cluster-frame-child-component.injectable";
import deploymentScaleDialogClusterFrameChildComponentInjectable from "./components/+workloads-deployments/scale/deployment-scale-dialog-cluster-frame-child-component.injectable";
import replicasetScaleDialogClusterFrameChildComponentInjectable from "./components/+workloads-replicasets/scale-dialog/replicaset-scale-dialog-cluster-frame-child-component.injectable";
import statefulsetScaleDialogClusterFrameChildComponentInjectable from "./components/+workloads-statefulsets/scale/statefulset-scale-dialog-cluster-frame-child-component.injectable";
import kubeObjectDetailsClusterFrameChildComponentInjectable from "./components/kube-object-details/kube-object-details-cluster-frame-child-component.injectable";
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";
import forceUpdateModalRootFrameComponentInjectable from "./application-update/force-update-modal/force-update-modal-root-frame-component.injectable";
import legacyOnChannelListenInjectable from "./ipc/legacy-channel-listen.injectable";
import getEntitySettingCommandsInjectable from "./components/command-palette/registered-commands/get-entity-setting-commands.injectable";
import storageSaveDelayInjectable from "./utils/create-storage/storage-save-delay.injectable";
import environmentVariablesInjectable from "../common/utils/environment-variables.injectable";
import type { GlobalOverride } from "../common/test-utils/get-global-override";
import type { PartialDeep } from "type-fest";
export const getDiForUnitTesting = (
opts: { doGeneralOverrides?: boolean } = {},
) => {
const { doGeneralOverrides = false } = opts;
const di = createContainer("renderer");
di.preventSideEffects();
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
const injectables: Injectable<any, any, any>[] = (
global as any
).rendererInjectablePaths.map(
(filePath: string) => require(filePath).default,
);
runInAction(() => {
registerMobX(di);
chunk(100)(injectables).forEach((chunkInjectables) => {
di.register(...chunkInjectables);
});
});
if (doGeneralOverrides) {
const globalOverrides: GlobalOverride[] = (global as any).rendererGlobalOverridePaths.map(
(filePath: string) => require(filePath).default,
);
globalOverrides.forEach(globalOverride => {
di.override(globalOverride.injectable, globalOverride.overridingInstantiate);
});
di.override(getRandomIdInjectable, () => () => "some-irrelevant-random-id");
di.override(platformInjectable, () => "darwin");
[
startTopbarStateSyncInjectable,
setupSystemCaInjectable,
].forEach((injectable) => {
di.override(injectable, () => ({
id: injectable.id,
run: () => {},
}));
});
di.override(terminalSpawningPoolInjectable, () => document.createElement("div"));
di.override(hostedClusterIdInjectable, () => undefined);
di.override(historyInjectable, () => createMemoryHistory());
di.override(legacyOnChannelListenInjectable, () => () => noop);
di.override(storageSaveDelayInjectable, () => 0);
di.override(requestAnimationFrameInjectable, () => (callback) => callback());
di.override(lensResourcesDirInjectable, () => "/irrelevant");
// TODO: remove when entity settings registry is refactored
di.override(getEntitySettingCommandsInjectable, () => () => []);
di.override(forceUpdateModalRootFrameComponentInjectable, () => ({
id: "force-update-modal",
Component: () => null,
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>[] = [
cronJobTriggerDialogClusterFrameChildComponentInjectable,
deploymentScaleDialogClusterFrameChildComponentInjectable,
replicasetScaleDialogClusterFrameChildComponentInjectable,
statefulsetScaleDialogClusterFrameChildComponentInjectable,
kubeObjectDetailsClusterFrameChildComponentInjectable,
kubeconfigDialogClusterFrameChildComponentInjectable,
portForwardDialogClusterFrameChildComponentInjectable,
];
clusterFrameChildComponentInjectables.forEach((injectable) => {
di.override(injectable, () => ({
Component: () => null,
id: injectable.id,
shouldRender: computed(() => false),
}));
});
di.override(environmentVariablesInjectable, () => ({}));
di.override(watchHistoryStateInjectable, () => () => () => {});
di.override(openAppContextMenuInjectable, () => () => {});
di.override(goBackInjectable, () => () => {});
di.override(goForwardInjectable, () => () => {});
di.override(closeWindowInjectable, () => () => {});
di.override(maximizeWindowInjectable, () => () => {});
di.override(toggleMaximizeWindowInjectable, () => () => {});
overrideFunctionalInjectables(di, [
broadcastMessageInjectable,
getFilePathsInjectable,
callForPublicHelmRepositoriesInjectable,
]);
// eslint-disable-next-line unused-imports/no-unused-vars-ts
di.override(extensionsStoreInjectable, () => ({ isEnabled: ({ id, isBundled }) => false }) as ExtensionsStore);
di.override(hotbarStoreInjectable, () => ({
getActive: () => ({ name: "some-hotbar", items: [] }),
getDisplayIndex: () => "0",
}) as unknown as HotbarStore);
di.override(fileSystemProvisionerStoreInjectable, () => ({}) as FileSystemProvisionerStore);
di.override(defaultShellInjectable, () => "some-default-shell");
di.override(userStoreInjectable, () => ({
isTableColumnHidden: () => false,
extensionRegistryUrl: { customUrl: "some-custom-url" },
syncKubeconfigEntries: observable.map(),
terminalConfig: { fontSize: 42 },
editorConfiguration: { minimap: {}, tabSize: 42, fontSize: 42 },
load: () => {},
} as PartialDeep<UserStore> as UserStore));
di.override(apiManagerInjectable, () => new ApiManager());
di.override(requestFromChannelInjectable, () => () => Promise.resolve(undefined as never));
overrideFsWithFakes(di);
di.override(focusWindowInjectable, () => () => {});
di.override(loggerInjectable, () => ({
warn: noop,
debug: noop,
error: noop,
info: noop,
silly: noop,
}));
}
return di;
};
const overrideFunctionalInjectables = (di: DiContainer, injectables: Injectable<any, any, any>[]) => {
injectables.forEach(injectable => {
di.override(injectable, () => () => {
throw new Error(`Tried to run "${injectable.id}" without explicit override.`);
});
});
};