diff --git a/src/common/fs/read-dir.injectable.ts b/src/common/fs/read-dir.injectable.ts new file mode 100644 index 0000000000..501ecc1cdd --- /dev/null +++ b/src/common/fs/read-dir.injectable.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import fsInjectable from "./fs.injectable"; + +const readDirInjectable = getInjectable({ + instantiate: (di) => di.inject(fsInjectable).readdir, + lifecycle: lifecycleEnum.singleton, +}); + +export default readDirInjectable; diff --git a/src/common/fs/read-file.injectable.ts b/src/common/fs/read-file.injectable.ts new file mode 100644 index 0000000000..5e2871a03d --- /dev/null +++ b/src/common/fs/read-file.injectable.ts @@ -0,0 +1,13 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; +import fsInjectable from "./fs.injectable"; + +const readFileInjectable = getInjectable({ + instantiate: (di) => di.inject(fsInjectable).readFile, + lifecycle: lifecycleEnum.singleton, +}); + +export default readFileInjectable; diff --git a/src/common/fs/read-json-file/read-json-file.injectable.ts b/src/common/fs/read-json-file.injectable.ts similarity index 66% rename from src/common/fs/read-json-file/read-json-file.injectable.ts rename to src/common/fs/read-json-file.injectable.ts index b94c904885..b944decadc 100644 --- a/src/common/fs/read-json-file/read-json-file.injectable.ts +++ b/src/common/fs/read-json-file.injectable.ts @@ -2,15 +2,11 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { readJsonFile } from "./read-json-file"; import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; -import fsInjectable from "../fs.injectable"; +import fsInjectable from "./fs.injectable"; const readJsonFileInjectable = getInjectable({ - instantiate: (di) => readJsonFile({ - fs: di.inject(fsInjectable), - }), - + instantiate: (di) => di.inject(fsInjectable).readJson, lifecycle: lifecycleEnum.singleton, }); diff --git a/src/common/fs/read-json-file/read-json-file.ts b/src/common/fs/read-json-file/read-json-file.ts deleted file mode 100644 index cb22e78ad3..0000000000 --- a/src/common/fs/read-json-file/read-json-file.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import type { JsonObject } from "type-fest"; - -interface Dependencies { - fs: { - readJson: (filePath: string) => Promise; - }; -} - -export const readJsonFile = - ({ fs }: Dependencies) => - (filePath: string) => - fs.readJson(filePath); diff --git a/src/common/fs/write-json-file/write-json-file.injectable.ts b/src/common/fs/write-json-file.injectable.ts similarity index 67% rename from src/common/fs/write-json-file/write-json-file.injectable.ts rename to src/common/fs/write-json-file.injectable.ts index 5ff6cbaec3..c6581f9195 100644 --- a/src/common/fs/write-json-file/write-json-file.injectable.ts +++ b/src/common/fs/write-json-file.injectable.ts @@ -3,11 +3,10 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; -import { writeJsonFile } from "./write-json-file"; -import fsInjectable from "../fs.injectable"; +import fsInjectable from "./fs.injectable"; const writeJsonFileInjectable = getInjectable({ - instantiate: (di) => writeJsonFile({ fs: di.inject(fsInjectable) }), + instantiate: (di) => di.inject(fsInjectable).writeJson, lifecycle: lifecycleEnum.singleton, }); diff --git a/src/common/fs/write-json-file/write-json-file.ts b/src/common/fs/write-json-file/write-json-file.ts deleted file mode 100644 index 8db664593e..0000000000 --- a/src/common/fs/write-json-file/write-json-file.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import path from "path"; -import type { JsonObject } from "type-fest"; - -interface Dependencies { - fs: { - ensureDir: ( - directoryName: string, - options: { mode: number } - ) => Promise; - - writeJson: ( - filePath: string, - contentObject: JsonObject, - options: { spaces: number } - ) => Promise; - }; -} - -export const writeJsonFile = - ({ fs }: Dependencies) => - async (filePath: string, contentObject: JsonObject) => { - const directoryName = path.dirname(filePath); - - await fs.ensureDir(directoryName, { mode: 0o755 }); - - await fs.writeJson(filePath, contentObject, { spaces: 2 }); - }; diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts index 54db181333..ae71fb9618 100644 --- a/src/main/getDiForUnitTesting.ts +++ b/src/main/getDiForUnitTesting.ts @@ -12,8 +12,8 @@ import getElectronAppPathInjectable from "./app-paths/get-electron-app-path/get- import setElectronAppPathInjectable from "./app-paths/set-electron-app-path/set-electron-app-path.injectable"; import appNameInjectable from "./app-paths/app-name/app-name.injectable"; import registerChannelInjectable from "./app-paths/register-channel/register-channel.injectable"; -import writeJsonFileInjectable from "../common/fs/write-json-file/write-json-file.injectable"; -import readJsonFileInjectable from "../common/fs/read-json-file/read-json-file.injectable"; +import writeJsonFileInjectable from "../common/fs/write-json-file.injectable"; +import readJsonFileInjectable from "../common/fs/read-json-file.injectable"; export const getDiForUnitTesting = ( { doGeneralOverrides } = { doGeneralOverrides: false }, diff --git a/src/renderer/components/dock/create-resource/lens-templates.injectable.ts b/src/renderer/components/dock/create-resource/lens-templates.injectable.ts index 85fbc82977..ed984c52e4 100644 --- a/src/renderer/components/dock/create-resource/lens-templates.injectable.ts +++ b/src/renderer/components/dock/create-resource/lens-templates.injectable.ts @@ -4,19 +4,26 @@ */ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import path from "path"; -import { readdir, readFile } from "fs/promises"; import { hasCorrectExtension } from "./has-correct-extension"; import type { RawTemplates } from "./create-resource-templates.injectable"; +import "../../../../common/vars"; +import readFileInjectable from "../../../../common/fs/read-file.injectable"; +import readDirInjectable from "../../../../common/fs/read-dir.injectable"; -const templatesFolder = path.resolve(__static, "../templates/create-resource"); +interface Dependencies { + readDir: (dirPath: string) => Promise; + readFile: (filePath: string, encoding: "utf-8") => Promise; +} + +async function getTemplates({ readDir, readFile }: Dependencies) { + const templatesFolder = path.resolve(__static, "../templates/create-resource"); -async function getTemplates() { /** * Mapping between file names and their contents */ const templates: [file: string, contents: string][] = []; - for (const dirEntry of await readdir(templatesFolder)) { + for (const dirEntry of await readDir(templatesFolder)) { if (hasCorrectExtension(dirEntry)) { templates.push([path.parse(dirEntry).name, await readFile(path.join(templatesFolder, dirEntry), "utf-8")]); } @@ -28,8 +35,11 @@ async function getTemplates() { let lensTemplatePaths: RawTemplates; const lensCreateResourceTemplatesInjectable = getInjectable({ - setup: async () => { - lensTemplatePaths = ["lens", await getTemplates()]; + setup: async (di) => { + lensTemplatePaths = ["lens", await getTemplates({ + readFile: di.inject(readFileInjectable), + readDir: di.inject(readDirInjectable), + })]; }, instantiate: () => lensTemplatePaths, lifecycle: lifecycleEnum.singleton, diff --git a/src/renderer/components/dock/create-resource/user-templates.injectable.ts b/src/renderer/components/dock/create-resource/user-templates.injectable.ts index ac0bd290ed..ee4f917ee6 100644 --- a/src/renderer/components/dock/create-resource/user-templates.injectable.ts +++ b/src/renderer/components/dock/create-resource/user-templates.injectable.ts @@ -21,8 +21,8 @@ function groupTemplates(templates: Map): RawTemplates[] { for (const [filePath, contents] of templates) { const rawRelative = path.dirname(path.relative(userTemplatesFolder, filePath)); const title = rawRelative === "." - ? "ungrouped" - : rawRelative; + ? "ungrouped" + : rawRelative; getOrInsert(res, title, []).push([path.parse(filePath).name, contents]); } diff --git a/src/renderer/components/dock/logs/__test__/log-resource-selector.test.tsx b/src/renderer/components/dock/logs/__test__/log-resource-selector.test.tsx index 33754310a3..755a265b89 100644 --- a/src/renderer/components/dock/logs/__test__/log-resource-selector.test.tsx +++ b/src/renderer/components/dock/logs/__test__/log-resource-selector.test.tsx @@ -83,7 +83,11 @@ const getFewPodsTabData = (tabId: TabId, deps: Partial ({ - ownerId: "uuid", + owner: { + uid: "uuid", + kind: "Deployment", + name: "super-deployment", + }, selectedPodId: selectedPod.getId(), selectedContainer: selectedPod.getContainers()[0].name, namespace: selectedPod.getNs(), @@ -181,12 +185,13 @@ describe("", () => { expect(await findByText("init-node-exporter-1")).toBeInTheDocument(); }); - it("renders pod owner as dropdown title", async () => { + it("renders pod owner as badge", async () => { const model = getFewPodsTabData("foobar"); - const { findByText, container } = render(); + const { findByText } = render(); - selectEvent.openMenu(container.querySelector(".pod-selector")); - expect(await findByText("super-deployment")).toBeInTheDocument(); + expect(await findByText("super-deployment", { + exact: false, + })).toBeInTheDocument(); }); it("updates tab name if selected pod changes", async () => { @@ -197,6 +202,6 @@ describe("", () => { selectEvent.openMenu(container.querySelector(".pod-selector")); userEvent.click(await findByText("deploymentPod2", { selector: ".pod-selector-menu .Select__option" })); - expect(renameTab).toBeCalledWith("foobar", "Pod deploymentPod1"); + expect(renameTab).toBeCalledWith("foobar", "Pod deploymentPod2"); }); }); diff --git a/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx b/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx index 0190adcc71..9b557a2f6c 100644 --- a/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx +++ b/src/renderer/components/layout/top-bar/top-bar-win-linux.test.tsx @@ -20,15 +20,14 @@ jest.mock("../../../../common/ipc"); jest.mock("../../../ipc"); jest.mock("../../../../common/vars", () => { - const SemVer = require("semver").SemVer; - - const versionStub = new SemVer("1.0.0"); + const { SemVer } = require("semver"); return { + ...jest.requireActual<{}>("../../../../common/vars"), __esModule: true, isWindows: null, isLinux: null, - appSemVer: versionStub, + appSemVer: new SemVer("1.0.0"), }; }); diff --git a/src/renderer/components/layout/top-bar/top-bar.test.tsx b/src/renderer/components/layout/top-bar/top-bar.test.tsx index e5d491401c..507706c06d 100644 --- a/src/renderer/components/layout/top-bar/top-bar.test.tsx +++ b/src/renderer/components/layout/top-bar/top-bar.test.tsx @@ -16,13 +16,12 @@ import directoryForUserDataInjectable from "../../../../common/app-paths/directo import mockFs from "mock-fs"; jest.mock("../../../../common/vars", () => { - const SemVer = require("semver").SemVer; - - const versionStub = new SemVer("1.0.0"); + const { SemVer } = require("semver"); return { + ...jest.requireActual<{}>("../../../../common/vars"), isMac: true, - appSemVer: versionStub, + appSemVer: new SemVer("1.0.0"), }; }); diff --git a/src/renderer/getDiForUnitTesting.tsx b/src/renderer/getDiForUnitTesting.tsx index 901b7edbf8..ee80d0d8e3 100644 --- a/src/renderer/getDiForUnitTesting.tsx +++ b/src/renderer/getDiForUnitTesting.tsx @@ -8,8 +8,10 @@ import { memoize } from "lodash/fp"; import { createContainer } from "@ogre-tools/injectable"; import { setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import getValueFromRegisteredChannelInjectable from "./app-paths/get-value-from-registered-channel/get-value-from-registered-channel.injectable"; -import writeJsonFileInjectable from "../common/fs/write-json-file/write-json-file.injectable"; -import readJsonFileInjectable from "../common/fs/read-json-file/read-json-file.injectable"; +import writeJsonFileInjectable from "../common/fs/write-json-file.injectable"; +import readJsonFileInjectable from "../common/fs/read-json-file.injectable"; +import readDirInjectable from "../common/fs/read-dir.injectable"; +import readFileInjectable from "../common/fs/read-file.injectable"; export const getDiForUnitTesting = ({ doGeneralOverrides } = { doGeneralOverrides: false }) => { const di = createContainer(); @@ -31,6 +33,12 @@ export const getDiForUnitTesting = ({ doGeneralOverrides } = { doGeneralOverride if (doGeneralOverrides) { di.override(getValueFromRegisteredChannelInjectable, () => () => undefined); + di.override(readDirInjectable, () => () => Promise.resolve([])); + + di.override(readFileInjectable, () => () => { + throw new Error("Tried to read a file from file system without specifying explicit overrride"); + }); + di.override(writeJsonFileInjectable, () => () => { throw new Error("Tried to write JSON file to file system without specifying explicit override."); }); diff --git a/src/renderer/utils/create-storage/create-storage.injectable.ts b/src/renderer/utils/create-storage/create-storage.injectable.ts index 1f665bd002..729123a3ad 100644 --- a/src/renderer/utils/create-storage/create-storage.injectable.ts +++ b/src/renderer/utils/create-storage/create-storage.injectable.ts @@ -5,8 +5,8 @@ import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable"; import directoryForLensLocalStorageInjectable from "../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; import { createStorage } from "./create-storage"; -import readJsonFileInjectable from "../../../common/fs/read-json-file/read-json-file.injectable"; -import writeJsonFileInjectable from "../../../common/fs/write-json-file/write-json-file.injectable"; +import readJsonFileInjectable from "../../../common/fs/read-json-file.injectable"; +import writeJsonFileInjectable from "../../../common/fs/write-json-file.injectable"; const createStorageInjectable = getInjectable({ instantiate: (di) =>