diff --git a/src/extensions/__tests__/extension-discovery.test.ts b/src/extensions/__tests__/extension-discovery.test.ts index d0066c3a7e..9bfd5a000a 100644 --- a/src/extensions/__tests__/extension-discovery.test.ts +++ b/src/extensions/__tests__/extension-discovery.test.ts @@ -1,9 +1,11 @@ +import mockFs from "mock-fs"; import { watch } from "chokidar"; -import { join, normalize } from "path"; -import { ExtensionDiscovery, InstalledExtension } from "../extension-discovery"; +import path from "path"; +import { ExtensionDiscovery } from "../extension-discovery"; +import os from "os"; +import { Console } from "console"; jest.mock("../../common/ipc"); -jest.mock("fs-extra"); jest.mock("chokidar", () => ({ watch: jest.fn() })); @@ -14,50 +16,62 @@ jest.mock("../extension-installer", () => ({ } })); +console = new Console(process.stdout, process.stderr); // fix mockFS const mockedWatch = watch as jest.MockedFunction; describe("ExtensionDiscovery", () => { - it("emits add for added extension", async done => { - globalThis.__non_webpack_require__.mockImplementation(() => ({ - name: "my-extension" - })); - let addHandler: (filePath: string) => void; - - const mockWatchInstance: any = { - on: jest.fn((event: string, handler: typeof addHandler) => { - if (event === "add") { - addHandler = handler; - } - - return mockWatchInstance; - }) - }; - - mockedWatch.mockImplementationOnce(() => - (mockWatchInstance) as any - ); - const extensionDiscovery = new ExtensionDiscovery(); - - // Need to force isLoaded to be true so that the file watching is started - extensionDiscovery.isLoaded = true; - - await extensionDiscovery.watchExtensions(); - - extensionDiscovery.events.on("add", (extension: InstalledExtension) => { - expect(extension).toEqual({ - absolutePath: expect.any(String), - id: normalize("node_modules/my-extension/package.json"), - isBundled: false, - isEnabled: false, - manifest: { - name: "my-extension", - }, - manifestPath: normalize("node_modules/my-extension/package.json"), + describe("with mockFs", () => { + beforeEach(() => { + mockFs({ + [`${os.homedir()}/.k8slens/extensions/my-extension/package.json`]: JSON.stringify({ + name: "my-extension" + }), }); - done(); }); - addHandler(join(extensionDiscovery.localFolderPath, "/my-extension/package.json")); + afterEach(() => { + mockFs.restore(); + }); + + it("emits add for added extension", async (done) => { + let addHandler: (filePath: string) => void; + + const mockWatchInstance: any = { + on: jest.fn((event: string, handler: typeof addHandler) => { + if (event === "add") { + addHandler = handler; + } + + return mockWatchInstance; + }) + }; + + mockedWatch.mockImplementationOnce(() => + (mockWatchInstance) as any + ); + const extensionDiscovery = new ExtensionDiscovery(); + + // Need to force isLoaded to be true so that the file watching is started + extensionDiscovery.isLoaded = true; + + await extensionDiscovery.watchExtensions(); + + extensionDiscovery.events.on("add", extension => { + expect(extension).toEqual({ + absolutePath: expect.any(String), + id: path.normalize("node_modules/my-extension/package.json"), + isBundled: false, + isEnabled: false, + manifest: { + name: "my-extension", + }, + manifestPath: path.normalize("node_modules/my-extension/package.json"), + }); + done(); + }); + + addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/package.json")); + }); }); it("doesn't emit add for added file under extension", async done => { @@ -87,7 +101,7 @@ describe("ExtensionDiscovery", () => { extensionDiscovery.events.on("add", onAdd); - addHandler(join(extensionDiscovery.localFolderPath, "/my-extension/node_modules/dep/package.json")); + addHandler(path.join(extensionDiscovery.localFolderPath, "/my-extension/node_modules/dep/package.json")); setTimeout(() => { expect(onAdd).not.toHaveBeenCalled(); diff --git a/src/extensions/extension-discovery.ts b/src/extensions/extension-discovery.ts index db43a70459..f079af1531 100644 --- a/src/extensions/extension-discovery.ts +++ b/src/extensions/extension-discovery.ts @@ -66,11 +66,7 @@ export class ExtensionDiscovery { // IPC channel to broadcast changes to extension-discovery from main protected static readonly extensionDiscoveryChannel = "extension-discovery:main"; - public events: EventEmitter; - - constructor() { - this.events = new EventEmitter(); - } + public events = new EventEmitter(); get localFolderPath(): string { return path.join(os.homedir(), ".k8slens", "extensions"); @@ -172,7 +168,7 @@ export class ExtensionDiscovery { if (extension) { // Remove a broken symlink left by a previous installation if it exists. - await this.removeSymlinkByManifestPath(manifestPath); + await fse.remove(extension.manifestPath); // Install dependencies for the new extension await this.installPackage(extension.absolutePath); @@ -231,16 +227,6 @@ export class ExtensionDiscovery { return fse.remove(this.getInstalledPath(name)); } - /** - * Remove the symlink under node_modules if it exists. - * @param manifestPath Path to package.json - */ - removeSymlinkByManifestPath(manifestPath: string) { - const manifestJson = __non_webpack_require__(manifestPath); - - return this.removeSymlinkByPackageName(manifestJson.name); - } - /** * Uninstalls extension. * The application will detect the folder unlink and remove the extension from the UI automatically. @@ -325,7 +311,10 @@ export class ExtensionDiscovery { */ protected async getByManifest(manifestPath: string, { isBundled = false } = {}): Promise { try { + console.log(manifestPath); const manifest = await fse.readJson(manifestPath); + + console.log(manifest); const installedManifestPath = this.getInstalledManifestPath(manifest.name); const isEnabled = isBundled || extensionsStore.isEnabled(installedManifestPath);