From 2887f3997b9cd9ff6dd3dc4f4648854c6d3363bd Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 11:35:16 -0500 Subject: [PATCH 01/22] Fix console.error in upload-queue.test.js. I don't think the test meant to issue the error so I fixed the call and I instrumented the queue to ensure errors don't happen in any of the tests. --- client/src/utils/upload-queue.test.js | 49 +++++++++++++++++++-------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/client/src/utils/upload-queue.test.js b/client/src/utils/upload-queue.test.js index 3e5a72588132..ce38d572ea30 100644 --- a/client/src/utils/upload-queue.test.js +++ b/client/src/utils/upload-queue.test.js @@ -9,52 +9,66 @@ function StubFile(name = null, size = 0, mode = "local") { return { name, size, mode }; } +function instrumentedUploadQueue(options = {}) { + const uploadQueue = new UploadQueue(options); + uploadQueue.encountedErrors = false; + uploadQueue.opts.error = function (d, m) { + uploadQueue.encountedErrors = true; + }; + return uploadQueue; +} + describe("UploadQueue", () => { test("a queue is initialized to correct state", () => { - const q = new UploadQueue({ foo: 1 }); + const q = instrumentedUploadQueue({ foo: 1 }); expect(q.size).toEqual(0); expect(q.isRunning).toBe(false); expect(q.opts.foo).toEqual(1); // passed as options expect(q.opts.multiple).toBe(true); // default value + expect(q.encountedErrors).toBeFalsy(); }); test("resetting the queue removes all files from it", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); q.add([StubFile("a"), StubFile("b")]); expect(q.size).toEqual(2); q.reset(); expect(q.size).toEqual(0); + expect(q.encountedErrors).toBeFalsy(); }); test("calling configure updates options", () => { - const q = new UploadQueue({ foo: 1 }); + const q = instrumentedUploadQueue({ foo: 1 }); expect(q.opts.foo).toEqual(1); expect(q.opts.bar).toBeUndefined(); q.configure({ bar: 2 }); // overwrite bar expect(q.opts.foo).toEqual(1); // value unchangee expect(q.opts.bar).toEqual(2); // value overwritten + expect(q.encountedErrors).toBeFalsy(); }); test("calling start sets isRunning to true", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); q._process = jest.fn(); // mock this, otherwise it'll reset isRunning after it's done. expect(q.isRunning).toBe(false); q.start(); expect(q.isRunning).toBe(true); + expect(q.encountedErrors).toBeFalsy(); }); test("calling start is a noop if queue is running", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); const mockedProcess = jest.fn(); q._process = mockedProcess(); q.isRunning = true; q.start(); expect(mockedProcess.mock.calls.length === 0); // function was not called + expect(q.encountedErrors).toBeFalsy(); }); test("calling start processes all files in queue", () => { const fileEntries = {}; - const q = new UploadQueue({ + const q = instrumentedUploadQueue({ get: (index) => fileEntries[index], announce: (index, file) => { fileEntries[index] = { @@ -62,6 +76,7 @@ describe("UploadQueue", () => { fileName: file.name, fileSize: file.size, fileContent: "fileContent", + targetHistoryId: "mockhistoryid", }; }, }); @@ -71,12 +86,13 @@ describe("UploadQueue", () => { q.add([StubFile("a"), StubFile("b")]); q.start(); expect(q.size).toEqual(0); + expect(q.encountedErrors).toBeFalsy(); expect(spy.mock.calls.length).toEqual(3); // called for 2, 1, 0 files. spy.mockRestore(); // not necessary, but safer, in case we later modify implementation. }); test("calling stop sets isPaused to true", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); q.start(); expect(q.isPaused).toBe(false); q.stop(); @@ -84,7 +100,7 @@ describe("UploadQueue", () => { }); test("adding files increases the queue size by the number of files", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); expect(q.size).toEqual(0); q.add([StubFile("a"), StubFile("b")]); expect(q.nextIndex).toEqual(2); @@ -94,14 +110,14 @@ describe("UploadQueue", () => { }); test("adding files increases the next index by the number of files", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); expect(q.nextIndex).toEqual(0); q.add([StubFile("a"), StubFile("b")]); expect(q.nextIndex).toEqual(2); }); test("duplicate files are not added to the queue, unless the mode is set to 'new'", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); const file1 = StubFile("a", 1); const file2 = StubFile("a", 1); const file3 = StubFile("a", 1, "new"); @@ -115,7 +131,7 @@ describe("UploadQueue", () => { test("adding a file calls opts.announce with correct arguments", () => { const mockAnnounce = jest.fn(); - const q = new UploadQueue({ announce: mockAnnounce }); + const q = instrumentedUploadQueue({ announce: mockAnnounce }); const file = StubFile("a"); expect(mockAnnounce.mock.calls.length).toBe(0); q.add([file]); @@ -126,7 +142,7 @@ describe("UploadQueue", () => { test("removing a file reduces the queue size by 1", () => { const fileEntries = {}; - const q = new UploadQueue({ + const q = instrumentedUploadQueue({ announce: (index, file) => { fileEntries[index] = file; }, @@ -138,7 +154,7 @@ describe("UploadQueue", () => { }); test("removing a file by index out of sequence is allowed", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); const file1 = StubFile("a"); const file2 = StubFile("b"); const file3 = StubFile("c"); @@ -149,10 +165,11 @@ describe("UploadQueue", () => { expect(q.queue.get("0")).toBe(file1); expect(q.queue.get("1")).toBeUndefined(); expect(q.queue.get("2")).toBe(file3); + expect(q.encountedErrors).toBeFalsy(); }); test("removing a file via _processIndex, obeys FIFO protocol", () => { - const q = new UploadQueue(); + const q = instrumentedUploadQueue(); q.add([StubFile("a"), StubFile("b")]); let nextIndex = q._processIndex(); expect(nextIndex).toEqual("0"); @@ -161,11 +178,12 @@ describe("UploadQueue", () => { expect(nextIndex).toEqual("1"); q.remove(nextIndex); expect(q._processIndex()).toBeUndefined(); + expect(q.encountedErrors).toBeFalsy(); }); test("remote file batch", () => { const fileEntries = {}; - const q = new UploadQueue({ + const q = instrumentedUploadQueue({ historyId: "historyId", announce: (index, file) => { fileEntries[index] = { @@ -227,5 +245,6 @@ describe("UploadQueue", () => { }, ], }); + expect(q.encountedErrors).toBeFalsy(); }); }); From 1f817142aa26605f65cdd2aac59ca800a19c5024 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 11:59:43 -0500 Subject: [PATCH 02/22] Drop console errors and warnings around NodeOutput.test.ts. --- .../components/Workflow/Editor/NodeOutput.test.ts | 3 +++ client/src/composables/useMagicKeys.js | 15 +++++++++++++++ client/src/stores/workflowEditorToolbarStore.ts | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 client/src/composables/useMagicKeys.js diff --git a/client/src/components/Workflow/Editor/NodeOutput.test.ts b/client/src/components/Workflow/Editor/NodeOutput.test.ts index 414ebd7e42f3..db7f46221b85 100644 --- a/client/src/components/Workflow/Editor/NodeOutput.test.ts +++ b/client/src/components/Workflow/Editor/NodeOutput.test.ts @@ -37,6 +37,9 @@ function propsForStep(step: Step) { scroll: { x: ref(0), y: ref(0) }, scale: 1, datatypesMapper: testDatatypesMapper, + parentNode: null, + readonly: true, + blank: false, }; } diff --git a/client/src/composables/useMagicKeys.js b/client/src/composables/useMagicKeys.js new file mode 100644 index 000000000000..1d2338ce6c00 --- /dev/null +++ b/client/src/composables/useMagicKeys.js @@ -0,0 +1,15 @@ +import { useMagicKeys as wrappedUseMagicKeys } from "@vueuse/core"; +import Vue from "vue"; + +export function useMagicKeys() { + // a version of useMagicKeys from vueuse/core that doesn't console.error the + // the message [Vue warn]: Vue 2 does not support reactive collection types such as Map or Set. + // in all our tests. This can be dropped after the migration to Vue3. + const oldSlientConfig = Vue.config.silent; + try { + Vue.config.silent = true; + return wrappedUseMagicKeys(); + } finally { + Vue.config.silent = oldSlientConfig; + } +} diff --git a/client/src/stores/workflowEditorToolbarStore.ts b/client/src/stores/workflowEditorToolbarStore.ts index 3bb36ea75cda..901a823943b8 100644 --- a/client/src/stores/workflowEditorToolbarStore.ts +++ b/client/src/stores/workflowEditorToolbarStore.ts @@ -1,7 +1,7 @@ -import { useMagicKeys } from "@vueuse/core"; import { computed, onScopeDispose, reactive, ref, watch } from "vue"; import { type Rectangle } from "@/components/Workflow/Editor/modules/geometry"; +import { useMagicKeys } from "@/composables/useMagicKeys"; import { useUserLocalStorage } from "@/composables/userLocalStorage"; import { defineScopedStore } from "./scopedStore"; From 66b821ade6e40d0a9697c5510d763bac751efcbb Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 12:19:40 -0500 Subject: [PATCH 03/22] Suppress known console.debug in Index.test.ts. --- .../src/components/Toolshed/RepositoryDetails/Index.test.ts | 4 +++- client/tests/jest/helpers.js | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/src/components/Toolshed/RepositoryDetails/Index.test.ts b/client/src/components/Toolshed/RepositoryDetails/Index.test.ts index b2a8cc0b19a7..e733ed052b9b 100644 --- a/client/src/components/Toolshed/RepositoryDetails/Index.test.ts +++ b/client/src/components/Toolshed/RepositoryDetails/Index.test.ts @@ -1,7 +1,7 @@ import { shallowMount } from "@vue/test-utils"; import flushPromises from "flush-promises"; import { createPinia } from "pinia"; -import { getLocalVue } from "tests/jest/helpers"; +import { getLocalVue, suppressDebugConsole } from "tests/jest/helpers"; import { HttpResponse, useServerMock } from "@/api/client/__mocks__"; @@ -10,6 +10,8 @@ import Index from "./Index.vue"; const { server, http } = useServerMock(); describe("RepositoryDetails", () => { + suppressDebugConsole(); // we issue a debug warning when a repo has no revisions + it("test repository details index", async () => { server.use( http.get("/api/configuration", ({ response }) => { diff --git a/client/tests/jest/helpers.js b/client/tests/jest/helpers.js index ff5f1e716919..3e48c2e5d384 100644 --- a/client/tests/jest/helpers.js +++ b/client/tests/jest/helpers.js @@ -273,3 +273,7 @@ export function injectTestRouter(localVue) { const router = new VueRouter(); return router; } + +export function suppressDebugConsole() { + jest.spyOn(console, "debug").mockImplementation(jest.fn()); +} From 913c04f8b057af83facfb21f2fc240d3f0ae50e6 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 12:31:25 -0500 Subject: [PATCH 04/22] Fix extraneous output in Workflow/Editor/Index.test.ts. An actual bug and the hack to work around Vue 2 warning in useMagicKeys. --- client/src/components/Workflow/Editor/Index.test.ts | 2 +- client/src/components/Workflow/Editor/Index.vue | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/components/Workflow/Editor/Index.test.ts b/client/src/components/Workflow/Editor/Index.test.ts index 62e9673f3673..7262d2d72956 100644 --- a/client/src/components/Workflow/Editor/Index.test.ts +++ b/client/src/components/Workflow/Editor/Index.test.ts @@ -38,7 +38,7 @@ describe("Index", () => { const datatypesStore = useDatatypesMapperStore(); datatypesStore.datatypesMapper = testDatatypesMapper; mockLoadWorkflow.mockResolvedValue({ steps: {} }); - MockGetVersions.mockResolvedValue(() => []); + MockGetVersions.mockResolvedValue([]); mockGetStateUpgradeMessages.mockImplementation(() => []); mockGetAppRoot.mockImplementation(() => "prefix/"); Object.defineProperty(window, "onbeforeunload", { diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue index 99087e09d500..1943de38e215 100644 --- a/client/src/components/Workflow/Editor/Index.vue +++ b/client/src/components/Workflow/Editor/Index.vue @@ -190,7 +190,7 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faArrowLeft, faArrowRight, faHistory } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; -import { useMagicKeys, whenever } from "@vueuse/core"; +import { whenever } from "@vueuse/core"; import { logicAnd, logicNot, logicOr } from "@vueuse/math"; import { Toast } from "composables/toast"; import { storeToRefs } from "pinia"; @@ -199,6 +199,7 @@ import Vue, { computed, nextTick, onUnmounted, ref, unref, watch } from "vue"; import { getUntypedWorkflowParameters } from "@/components/Workflow/Editor/modules/parameters"; import { ConfirmDialog } from "@/composables/confirmDialog"; import { useDatatypesMapper } from "@/composables/datatypesMapper"; +import { useMagicKeys } from "@/composables/useMagicKeys"; import { useUid } from "@/composables/utils/uid"; import { provideScopedWorkflowStores } from "@/composables/workflowStores"; import { hide_modal } from "@/layout/modal"; From 8bfe85d38364f518878dc3a5a005a9c76ca45ac2 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 13:09:16 -0500 Subject: [PATCH 05/22] stub help popovers in formdata to eliminate extra logging --- .../Form/Elements/FormData/FormData.test.js | 2 ++ .../components/JobInformation/JobInformation.test.js | 2 ++ .../Tool/ToolSelectPreferredObjectStore.test.js | 1 + client/tests/jest/mockHelpPopovers.js | 11 +++++++++++ 4 files changed, 16 insertions(+) create mode 100644 client/tests/jest/mockHelpPopovers.js diff --git a/client/src/components/Form/Elements/FormData/FormData.test.js b/client/src/components/Form/Elements/FormData/FormData.test.js index 709f2910a791..25ed1945588f 100644 --- a/client/src/components/Form/Elements/FormData/FormData.test.js +++ b/client/src/components/Form/Elements/FormData/FormData.test.js @@ -1,3 +1,5 @@ +import "tests/jest/mockHelpPopovers"; + import { createTestingPinia } from "@pinia/testing"; import { mount } from "@vue/test-utils"; import { PiniaVuePlugin } from "pinia"; diff --git a/client/src/components/JobInformation/JobInformation.test.js b/client/src/components/JobInformation/JobInformation.test.js index 68602a1b6ffd..8cc65b9499c3 100644 --- a/client/src/components/JobInformation/JobInformation.test.js +++ b/client/src/components/JobInformation/JobInformation.test.js @@ -1,3 +1,5 @@ +import "tests/jest/mockHelpPopovers"; + import { mount } from "@vue/test-utils"; import flushPromises from "flush-promises"; import { getLocalVue } from "tests/jest/helpers"; diff --git a/client/src/components/Tool/ToolSelectPreferredObjectStore.test.js b/client/src/components/Tool/ToolSelectPreferredObjectStore.test.js index 2bbad3ab37ca..fecb40c60226 100644 --- a/client/src/components/Tool/ToolSelectPreferredObjectStore.test.js +++ b/client/src/components/Tool/ToolSelectPreferredObjectStore.test.js @@ -1,6 +1,7 @@ import { mount } from "@vue/test-utils"; import flushPromises from "flush-promises"; import { getLocalVue } from "tests/jest/helpers"; +import "tests/jest/mockHelpPopovers"; import { useServerMock } from "@/api/client/__mocks__"; import { setupSelectableMock } from "@/components/ObjectStore/mockServices"; diff --git a/client/tests/jest/mockHelpPopovers.js b/client/tests/jest/mockHelpPopovers.js new file mode 100644 index 000000000000..8c72aec63c05 --- /dev/null +++ b/client/tests/jest/mockHelpPopovers.js @@ -0,0 +1,11 @@ +// bootstrap vue will try to match targets to actual HTML elements in DOM but there +// may be no DOM for jest tests, just stub out an alternative minimal implementation. +jest.mock("@/components/Help/HelpPopover.vue", () => ({ + name: "HelpPopover", + render: (h) => h("div", "Mocked Popover"), +})); + +jest.mock("@/components/ObjectStore/ObjectStoreSelectButtonPopover.vue", () => ({ + name: "ObjectStoreSelectButtonPopover", + render: (h) => h("div", "Mocked Popover"), +})); From c83c4cfa300d8177c519d097d7f310844b1dd43f Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 13:09:47 -0500 Subject: [PATCH 06/22] This really stablizes these tests - they sort of runaway without this. --- client/src/components/History/HistoryView.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/components/History/HistoryView.test.js b/client/src/components/History/HistoryView.test.js index 85dc95106ede..b00e2647f7a9 100644 --- a/client/src/components/History/HistoryView.test.js +++ b/client/src/components/History/HistoryView.test.js @@ -17,6 +17,11 @@ jest.mock("stores/services/history.services"); const { server, http } = useServerMock(); +jest.mock("vue-router/composables", () => ({ + useRoute: jest.fn(() => ({})), + useRouter: jest.fn(() => ({})), +})); + function create_history(historyId, userId, purged = false, archived = false) { const historyName = `${userId}'s History ${historyId}`; return { From 752063b201f316e11700c61cec0b1cf77116e21e Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 13:10:35 -0500 Subject: [PATCH 07/22] Eliminate a extraneous logging event in HistoryView.test.js. --- client/tests/jest/jest.setup.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/tests/jest/jest.setup.js b/client/tests/jest/jest.setup.js index 505e186fd517..bf547952dc9f 100644 --- a/client/tests/jest/jest.setup.js +++ b/client/tests/jest/jest.setup.js @@ -4,6 +4,9 @@ import "fake-indexeddb/auto"; import Vue from "vue"; +// not available in jsdom, mock it out +Element.prototype.scrollIntoView = jest.fn(); + // Set Vue to suppress production / devtools / etc. warnings Vue.config.productionTip = false; Vue.config.devtools = false; From be6aad901021efbd8a9c1fbec2c91279efbbec0f Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 13:40:30 -0500 Subject: [PATCH 08/22] Mock out popover to clean test logging for SelectPreferredStore. --- .../History/CurrentHistory/SelectPreferredStore.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/src/components/History/CurrentHistory/SelectPreferredStore.test.ts b/client/src/components/History/CurrentHistory/SelectPreferredStore.test.ts index 7638ef43b918..c500afa2af64 100644 --- a/client/src/components/History/CurrentHistory/SelectPreferredStore.test.ts +++ b/client/src/components/History/CurrentHistory/SelectPreferredStore.test.ts @@ -3,6 +3,7 @@ import axios from "axios"; import MockAdapter from "axios-mock-adapter"; import flushPromises from "flush-promises"; import { getLocalVue } from "tests/jest/helpers"; +import { h } from "vue"; import { useServerMock } from "@/api/client/__mocks__"; import { ROOT_COMPONENT } from "@/utils/navigation/schema"; @@ -42,6 +43,13 @@ async function mountComponent() { const PREFERENCES = ROOT_COMPONENT.preferences; +// bootstrap vue will try to match targets to actual HTML elements in DOM but there +// may be no DOM for jest tests, just stub out an alternative minimal implementation. +jest.mock("@/components/ObjectStore/ObjectStoreSelectButtonPopover.vue", () => ({ + name: "ObjectStoreSelectButtonPopover", + render: () => h("div", "Mocked Popover"), +})); + describe("SelectPreferredStore.vue", () => { let axiosMock: MockAdapter; From be8043a9cb8d7ef0cd849630fd6982186f044e82 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 14:09:39 -0500 Subject: [PATCH 09/22] Fix up FormTool.test.js. --- .../Workflow/Editor/Forms/FormTool.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/client/src/components/Workflow/Editor/Forms/FormTool.test.js b/client/src/components/Workflow/Editor/Forms/FormTool.test.js index 72ce85fddec6..56c65045504d 100644 --- a/client/src/components/Workflow/Editor/Forms/FormTool.test.js +++ b/client/src/components/Workflow/Editor/Forms/FormTool.test.js @@ -2,8 +2,11 @@ import { createTestingPinia } from "@pinia/testing"; import { mount } from "@vue/test-utils"; import axios from "axios"; import MockAdapter from "axios-mock-adapter"; +import flushPromises from "flush-promises"; import { getLocalVue } from "tests/jest/helpers"; +import { useServerMock } from "@/api/client/__mocks__"; + import FormTool from "./FormTool"; jest.mock("@/api/schema"); @@ -17,10 +20,20 @@ jest.mock("@/composables/config", () => ({ const localVue = getLocalVue(); +const { server, http } = useServerMock(); + describe("FormTool", () => { const axiosMock = new MockAdapter(axios); axiosMock.onGet(`/api/webhooks`).reply(200, []); + beforeEach(() => { + server.use( + http.get("/api/configuration", ({ response }) => { + return response(200).json({}); + }) + ); + }); + function mountTarget() { return mount(FormTool, { propsData: { @@ -35,6 +48,7 @@ describe("FormTool", () => { description: "description", inputs: [{ name: "input", label: "input", type: "text", value: "value" }], help: "help_text", + help_format: "restructuredtext", versions: ["1.0", "2.0", "3.0"], citations: false, }, @@ -71,5 +85,6 @@ describe("FormTool", () => { state = wrapper.emitted().onSetData[1][1]; expect(state.tool_version).toEqual("3.0"); expect(state.tool_id).toEqual("tool_id+3.0"); + await flushPromises(); }); }); From 7a2dea09284ea528b5660092c45fdc31f5d4e2c8 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 15:42:03 -0500 Subject: [PATCH 10/22] remove unused option to clean up test output --- client/src/components/Workflow/Editor/Options.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/components/Workflow/Editor/Options.vue b/client/src/components/Workflow/Editor/Options.vue index 4cc7932e9966..e288489a0364 100644 --- a/client/src/components/Workflow/Editor/Options.vue +++ b/client/src/components/Workflow/Editor/Options.vue @@ -38,7 +38,6 @@ const props = defineProps<{ hasChanges?: boolean; hasInvalidConnections?: boolean; requiredReindex?: boolean; - currentActivePanel: string; }>(); const { confirm } = useConfirmDialog(); From 7e03dedddcd153042837d5a5ac530f576c229f1d Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 15:52:24 -0500 Subject: [PATCH 11/22] Should not call onScopeDispose when jest testing. --- client/src/stores/workflowEditorToolbarStore.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/stores/workflowEditorToolbarStore.ts b/client/src/stores/workflowEditorToolbarStore.ts index 901a823943b8..c2db1be8f8fb 100644 --- a/client/src/stores/workflowEditorToolbarStore.ts +++ b/client/src/stores/workflowEditorToolbarStore.ts @@ -1,4 +1,4 @@ -import { computed, onScopeDispose, reactive, ref, watch } from "vue"; +import { computed, getCurrentScope, onScopeDispose, reactive, ref, watch } from "vue"; import { type Rectangle } from "@/components/Workflow/Editor/modules/geometry"; import { useMagicKeys } from "@/composables/useMagicKeys"; @@ -66,9 +66,11 @@ export const useWorkflowEditorToolbarStore = defineScopedStore("workflowEditorTo inputCatcherEventListeners.add(listener); - onScopeDispose(() => { - inputCatcherEventListeners.delete(listener); - }); + if (getCurrentScope()) { + onScopeDispose(() => { + inputCatcherEventListeners.delete(listener); + }); + } } onInputCatcherEvent("pointerdown", () => (inputCatcherPressed.value = true)); From 1fbaea7256210d6e317d79a3d0c22ca8b7e1a93d Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 19 Nov 2024 15:54:47 -0500 Subject: [PATCH 12/22] Fix unregistered component in test for Details.vue. --- client/src/components/Toolshed/InstalledList/Details.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/components/Toolshed/InstalledList/Details.vue b/client/src/components/Toolshed/InstalledList/Details.vue index 1dc166b64756..6be8e38dbf85 100644 --- a/client/src/components/Toolshed/InstalledList/Details.vue +++ b/client/src/components/Toolshed/InstalledList/Details.vue @@ -3,9 +3,9 @@
{{ error }}
- + - +
@@ -14,6 +14,7 @@