diff --git a/src/common/user-store/file-name-migration.injectable.ts b/src/common/user-store/file-name-migration.injectable.ts new file mode 100644 index 0000000000..8f2dcf1e23 --- /dev/null +++ b/src/common/user-store/file-name-migration.injectable.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import fse from "fs-extra"; +import path from "path"; +import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable"; +import { isErrnoException } from "../utils"; +import { getInjectable } from "@ogre-tools/injectable"; + +const userStoreFileNameMigrationInjectable = getInjectable({ + id: "user-store-file-name-migration", + instantiate: (di) => { + const userDataPath = di.inject(directoryForUserDataInjectable); + const configJsonPath = path.join(userDataPath, "config.json"); + const lensUserStoreJsonPath = path.join(userDataPath, "lens-user-store.json"); + + try { + fse.moveSync(configJsonPath, lensUserStoreJsonPath); + } catch (error) { + if (error instanceof Error && error.message === "dest already exists.") { + fse.removeSync(configJsonPath); + } else if (isErrnoException(error) && error.code === "ENOENT" && error.path === configJsonPath) { + // (No such file or directory) + return; // file already moved + } else { + // pass other errors along + throw error; + } + } + }, +}); + +export default userStoreFileNameMigrationInjectable; diff --git a/src/common/user-store/user-store.injectable.ts b/src/common/user-store/user-store.injectable.ts index 9a34144828..cd44cc60e5 100644 --- a/src/common/user-store/user-store.injectable.ts +++ b/src/common/user-store/user-store.injectable.ts @@ -3,14 +3,20 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; +import { ipcMain } from "electron"; +import userStoreFileNameMigrationInjectable from "./file-name-migration.injectable"; import { UserStore } from "./user-store"; const userStoreInjectable = getInjectable({ id: "user-store", - instantiate: () => { + instantiate: (di) => { UserStore.resetInstance(); + if (ipcMain) { + di.inject(userStoreFileNameMigrationInjectable); + } + return UserStore.createInstance(); }, diff --git a/src/main/index.ts b/src/main/index.ts index 864a0209fb..550fa10c4f 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -63,7 +63,6 @@ import hotbarStoreInjectable from "../common/hotbar-store.injectable"; import applicationMenuItemsInjectable from "./menu/application-menu-items.injectable"; import type { DiContainer } from "@ogre-tools/injectable"; import { init } from "@sentry/electron/main"; -import { userStoreFileNameMigration } from "../migrations/user-store"; async function main(di: DiContainer) { app.setName(appName); @@ -73,8 +72,6 @@ async function main(di: DiContainer) { */ initializeSentryReporting(init); - // TODO make this part of the UserStore setup - await userStoreFileNameMigration(); await di.runSetups(); await app.whenReady(); diff --git a/src/migrations/user-store/file-name-migration.ts b/src/migrations/user-store/file-name-migration.ts deleted file mode 100644 index b1f88b1cc4..0000000000 --- a/src/migrations/user-store/file-name-migration.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import fse from "fs-extra"; -import path from "path"; -import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; -import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; -import { isErrnoException } from "../../common/utils"; - -export async function userStoreFileNameMigration() { - const di = getLegacyGlobalDiForExtensionApi(); - - const userDataPath = di.inject(directoryForUserDataInjectable); - const configJsonPath = path.join(userDataPath, "config.json"); - const lensUserStoreJsonPath = path.join(userDataPath, "lens-user-store.json"); - - try { - await fse.move(configJsonPath, lensUserStoreJsonPath); - } catch (error) { - if (error instanceof Error && error.message === "dest already exists.") { - await fse.remove(configJsonPath); - } else if (isErrnoException(error) && error.code === "ENOENT" && error.path === configJsonPath) { - // (No such file or directory) - return; // file already moved - } else { - // pass other errors along - throw error; - } - } -} diff --git a/src/migrations/user-store/index.ts b/src/migrations/user-store/index.ts index 5f42eacc4a..557d367c63 100644 --- a/src/migrations/user-store/index.ts +++ b/src/migrations/user-store/index.ts @@ -10,11 +10,6 @@ import { joinMigrations } from "../helpers"; import version210Beta4 from "./2.1.0-beta.4"; import version500Alpha3 from "./5.0.0-alpha.3"; import version503Beta1 from "./5.0.3-beta.1"; -import { userStoreFileNameMigration } from "./file-name-migration"; - -export { - userStoreFileNameMigration, -}; export default joinMigrations( version210Beta4, diff --git a/src/renderer/components/+helm-charts/helm-chart-details.tsx b/src/renderer/components/+helm-charts/helm-chart-details.tsx index 6bd7c8592a..1b57b4d22d 100644 --- a/src/renderer/components/+helm-charts/helm-chart-details.tsx +++ b/src/renderer/components/+helm-charts/helm-chart-details.tsx @@ -47,7 +47,6 @@ class NonInjectedHelmChartDetails extends Component = {}): LogTabViewModel => { +function getOnePodViewModel(tabId: TabId, deps: Partial = {}): LogTabViewModel { const selectedPod = dockerPod; return mockLogTabViewModel(tabId, { @@ -84,7 +84,7 @@ const getOnePodViewModel = (tabId: TabId, deps: Partial = {}): LogTabViewModel => { const selectedPod = deploymentPod1; @@ -155,74 +155,83 @@ describe("", () => { mockFs.restore(); }); - it("renders w/o errors", () => { - const model = getOnePodViewModel("foobar"); - const { container } = render(); + describe.only("with one pod", () => { + let model: LogTabViewModel; - expect(container).toBeInstanceOf(HTMLElement); + beforeEach(() => { + model = getOnePodViewModel("foobar"); + }); + + it("renders w/o errors", () => { + const { container } = render(); + + expect(container).toBeInstanceOf(HTMLElement); + }); + + it("renders proper namespace", async () => { + const { findByTestId } = render(); + const ns = await findByTestId("namespace-badge"); + + expect(ns).toHaveTextContent("default"); + }); + + it.only("renders proper selected items within dropdowns", async () => { + const { findByText } = render(); + + expect(await findByText("dockerExporter")).toBeInTheDocument(); + expect(await findByText("docker-exporter")).toBeInTheDocument(); + }); }); - it("renders proper namespace", async () => { - const model = getOnePodViewModel("foobar"); - const { findByTestId } = render(); - const ns = await findByTestId("namespace-badge"); + describe("with several pods", () => { + let model: LogTabViewModel; - expect(ns).toHaveTextContent("default"); - }); + beforeEach(() => { + model = getFewPodsTabData("foobar"); + }); - it("renders proper selected items within dropdowns", async () => { - const model = getOnePodViewModel("foobar"); - const { findByText } = render(); + it("renders sibling pods in dropdown", async () => { + const { container, findByText } = render(); + const selector = container.querySelector(".pod-selector"); - expect(await findByText("dockerExporter")).toBeInTheDocument(); - expect(await findByText("docker-exporter")).toBeInTheDocument(); - }); + assert(selector); - it("renders sibling pods in dropdown", async () => { - const model = getFewPodsTabData("foobar"); - const { container, findByText } = render(); - const selector = container.querySelector(".pod-selector"); + selectEvent.openMenu(selector); + expect(await findByText("deploymentPod2", { selector: ".pod-selector-menu .Select__option" })).toBeInTheDocument(); + expect(await findByText("deploymentPod1", { selector: ".pod-selector-menu .Select__option" })).toBeInTheDocument(); + }); - assert(selector); + it("renders sibling containers in dropdown", async () => { + const { findByText, container } = render(); + const selector = container.querySelector(".container-selector"); - selectEvent.openMenu(selector); - expect(await findByText("deploymentPod2", { selector: ".pod-selector-menu .Select__option" })).toBeInTheDocument(); - expect(await findByText("deploymentPod1", { selector: ".pod-selector-menu .Select__option" })).toBeInTheDocument(); - }); + assert(selector); - it("renders sibling containers in dropdown", async () => { - const model = getFewPodsTabData("foobar"); - const { findByText, container } = render(); - const selector = container.querySelector(".container-selector"); + selectEvent.openMenu(selector); - assert(selector); + expect(await findByText("node-exporter-1")).toBeInTheDocument(); + expect(await findByText("init-node-exporter")).toBeInTheDocument(); + expect(await findByText("init-node-exporter-1")).toBeInTheDocument(); + }); - selectEvent.openMenu(selector); + it("renders pod owner as badge", async () => { + const { findByText } = render(); - expect(await findByText("node-exporter-1")).toBeInTheDocument(); - expect(await findByText("init-node-exporter")).toBeInTheDocument(); - expect(await findByText("init-node-exporter-1")).toBeInTheDocument(); - }); + expect(await findByText("super-deployment", { + exact: false, + })).toBeInTheDocument(); + }); - it("renders pod owner as badge", async () => { - const model = getFewPodsTabData("foobar"); - const { findByText } = render(); + it("updates tab name if selected pod changes", async () => { + const renameTab = jest.fn(); + const { findByText, container } = render(); + const selector = container.querySelector(".pod-selector"); - expect(await findByText("super-deployment", { - exact: false, - })).toBeInTheDocument(); - }); + assert(selector); - it("updates tab name if selected pod changes", async () => { - const renameTab = jest.fn(); - const model = getFewPodsTabData("foobar", { renameTab }); - const { findByText, container } = render(); - const selector = container.querySelector(".pod-selector"); - - assert(selector); - - selectEvent.openMenu(selector); - userEvent.click(await findByText("deploymentPod2", { selector: ".pod-selector-menu .Select__option" })); - expect(renameTab).toBeCalledWith("foobar", "Pod deploymentPod2"); + selectEvent.openMenu(selector); + userEvent.click(await findByText("deploymentPod2", { selector: ".pod-selector-menu .Select__option" })); + expect(renameTab).toBeCalledWith("foobar", "Pod deploymentPod2"); + }); }); }); diff --git a/src/renderer/components/dock/logs/resource-selector.tsx b/src/renderer/components/dock/logs/resource-selector.tsx index 40ecc3761a..04bef66db2 100644 --- a/src/renderer/components/dock/logs/resource-selector.tsx +++ b/src/renderer/components/dock/logs/resource-selector.tsx @@ -11,17 +11,13 @@ import { observer } from "mobx-react"; import { Badge } from "../../badge"; import { Select } from "../../select"; import type { LogTabViewModel } from "./logs-view-model"; -import type { IPodContainer, Pod } from "../../../../common/k8s-api/endpoints"; +import type { Pod } from "../../../../common/k8s-api/endpoints"; import type { GroupBase } from "react-select"; export interface LogResourceSelectorProps { model: LogTabViewModel; } -function getSelectOptions(containers: IPodContainer[]) { - return containers.map(container => container.name); -} - export const LogResourceSelector = observer(({ model }: LogResourceSelectorProps) => { const tabData = model.logTabData.get(); @@ -64,23 +60,23 @@ export const LogResourceSelector = observer(({ model }: LogResourceSelectorProps const containerSelectOptions = [ { label: "Containers", - options: getSelectOptions(pod.getContainers()), + options: pod.getContainers().map(container => container.name), }, { label: "Init Containers", - options: getSelectOptions(pod.getInitContainers()), + options: pod.getInitContainers().map(container => container.name), }, ]; return (
- Namespace + Namespace {" "} { owner && ( <> - Owner + Owner {" "} @@ -90,6 +86,7 @@ export const LogResourceSelector = observer(({ model }: LogResourceSelectorProps