From 432b00b8cce7797318406e858d9041f387aa9503 Mon Sep 17 00:00:00 2001 From: Panu Horsmalahti Date: Thu, 3 Dec 2020 11:43:33 +0200 Subject: [PATCH] Refactor ExtensionsStore (#1620) Signed-off-by: Panu Horsmalahti --- .../__tests__/extension-loader.test.ts | 34 +++++++++++++++++++ src/extensions/extension-loader.ts | 18 +++++++++- src/extensions/extensions-store.ts | 31 ++++------------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/extensions/__tests__/extension-loader.test.ts b/src/extensions/__tests__/extension-loader.test.ts index 06d4feb23d..335eb50912 100644 --- a/src/extensions/__tests__/extension-loader.test.ts +++ b/src/extensions/__tests__/extension-loader.test.ts @@ -1,9 +1,18 @@ import { ExtensionLoader } from "../extension-loader"; +import { ipcRenderer } from "electron"; +import { extensionsStore } from "../extensions-store"; const manifestPath = "manifest/path"; const manifestPath2 = "manifest/path2"; const manifestPath3 = "manifest/path3"; +jest.mock("../extensions-store", () => ({ + extensionsStore: { + whenLoaded: Promise.resolve(true), + mergeState: jest.fn() + } +})); + jest.mock( "electron", () => ({ @@ -129,4 +138,29 @@ describe("ExtensionLoader", () => { done(); }, 10); }); + + it("updates ExtensionsStore after isEnabled is changed", async () => { + (extensionsStore.mergeState as any).mockClear(); + + // Disable sending events in this test + (ipcRenderer.on as any).mockImplementation(); + + const extensionLoader = new ExtensionLoader(); + + await extensionLoader.init(); + + expect(extensionsStore.mergeState).not.toHaveBeenCalled(); + + Array.from(extensionLoader.userExtensions.values())[0].isEnabled = false; + + expect(extensionsStore.mergeState).toHaveBeenCalledWith({ + "manifest/path": { + enabled: false, + name: "TestExtension" + }, + "manifest/path2": { + enabled: true, + name: "TestExtension2" + }}); + }); }); diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index 30ef1157ec..966289f157 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -51,6 +51,17 @@ export class ExtensionLoader { return extensions; } + // Transform userExtensions to a state object for storing into ExtensionsStore + @computed get storeState() { + return Object.fromEntries( + Array.from(this.userExtensions) + .map(([extId, extension]) => [extId, { + enabled: extension.isEnabled, + name: extension.manifest.name, + }]) + ); + } + @action async init() { if (ipcRenderer) { @@ -59,7 +70,12 @@ export class ExtensionLoader { await this.initMain(); } - extensionsStore.manageState(this); + await Promise.all([this.whenLoaded, extensionsStore.whenLoaded]); + + // save state on change `extension.isEnabled` + reaction(() => this.storeState, extensionsState => { + extensionsStore.mergeState(extensionsState); + }); } initExtensions(extensions?: Map) { diff --git a/src/extensions/extensions-store.ts b/src/extensions/extensions-store.ts index 07edb20453..0885bbb730 100644 --- a/src/extensions/extensions-store.ts +++ b/src/extensions/extensions-store.ts @@ -1,7 +1,6 @@ import type { LensExtensionId } from "./lens-extension"; -import type { ExtensionLoader } from "./extension-loader"; import { BaseStore } from "../common/base-store"; -import { action, computed, observable, reaction, toJS } from "mobx"; +import { action, computed, observable, toJS } from "mobx"; export interface LensExtensionsStoreModel { extensions: Record; @@ -28,29 +27,6 @@ export class ExtensionsStore extends BaseStore { protected state = observable.map(); - protected getState(extensionLoader: ExtensionLoader) { - const state: Record = {}; - - return Array.from(extensionLoader.userExtensions).reduce((state, [extId, ext]) => { - state[extId] = { - enabled: ext.isEnabled, - name: ext.manifest.name, - }; - - return state; - }, state); - } - - async manageState(extensionLoader: ExtensionLoader) { - await extensionLoader.whenLoaded; - await this.whenLoaded; - - // save state on change `extension.isEnabled` - reaction(() => this.getState(extensionLoader), extensionsState => { - this.state.merge(extensionsState); - }); - } - isEnabled(extId: LensExtensionId) { const state = this.state.get(extId); @@ -59,6 +35,11 @@ export class ExtensionsStore extends BaseStore { return Boolean(state?.enabled); } + @action + mergeState(extensionsState: Record) { + this.state.merge(extensionsState); + } + @action protected fromStore({ extensions }: LensExtensionsStoreModel) { this.state.merge(extensions);