diff --git a/client/src/components/WorkflowInvocationState/WorkflowInvocationHeader.test.ts b/client/src/components/WorkflowInvocationState/WorkflowInvocationHeader.test.ts
index b0ff5d2b050d..a0d325455b81 100644
--- a/client/src/components/WorkflowInvocationState/WorkflowInvocationHeader.test.ts
+++ b/client/src/components/WorkflowInvocationState/WorkflowInvocationHeader.test.ts
@@ -1,5 +1,6 @@
import { createTestingPinia } from "@pinia/testing";
import { shallowMount } from "@vue/test-utils";
+import flushPromises from "flush-promises";
import { getLocalVue } from "tests/jest/helpers";
import sampleInvocation from "@/components/Workflow/test/json/invocation.json";
@@ -10,12 +11,16 @@ import WorkflowInvocationHeader from "./WorkflowInvocationHeader.vue";
// Constants
const WORKFLOW_OWNER = "test-user";
const OTHER_USER = "other-user";
+const UNIMPORTABLE_WORKFLOW_ID = "invalid-workflow-id";
+const UNIMPORTABLE_WORKFLOW_INSTANCE_ID = "invalid-instance-id";
const SAMPLE_WORKFLOW = {
id: "workflow-id",
name: "workflow-name",
owner: WORKFLOW_OWNER,
version: 1,
};
+const IMPORT_ERROR_MESSAGE = "Failed to import workflow";
+
const SELECTORS = {
INVOKED_WORKFLOW_HEADING: "anonymous-stub[h1='true']",
RETURN_TO_INVOCATIONS_LIST_BUTTON: "bbutton-stub[title='Return to Invocations List']",
@@ -23,27 +28,52 @@ const SELECTORS = {
EDIT_WORKFLOW_BUTTON: `bbutton-stub[title='Edit
${SAMPLE_WORKFLOW.name}']`,
IMPORT_WORKFLOW_BUTTON: "anonymous-stub[title='Import this workflow']",
RUN_WORKFLOW_BUTTON: `anonymous-stub[id='${SAMPLE_WORKFLOW.id}']`,
+ ALERT_MESSAGE: "balert-stub",
};
-// Mock the workflow store to return the expected workflow data given the stored workflow ID
+// Mock the copyWorkflow function for importing a workflow
+jest.mock("components/Workflow/workflows.services", () => ({
+ copyWorkflow: jest.fn().mockImplementation((workflowId: string) => {
+ if (workflowId === UNIMPORTABLE_WORKFLOW_ID) {
+ throw new Error(IMPORT_ERROR_MESSAGE);
+ }
+ return SAMPLE_WORKFLOW;
+ }),
+}));
+
+// Mock the workflow store to return the sample workflow
jest.mock("@/stores/workflowStore", () => {
const originalModule = jest.requireActual("@/stores/workflowStore");
return {
...originalModule,
useWorkflowStore: () => ({
...originalModule.useWorkflowStore(),
- getStoredWorkflowByInstanceId: jest.fn().mockImplementation(() => SAMPLE_WORKFLOW),
- fetchWorkflowForInstanceId: jest.fn().mockImplementation(() => {}),
+ getStoredWorkflowByInstanceId: jest.fn().mockImplementation((instanceId: string) => {
+ if (instanceId === UNIMPORTABLE_WORKFLOW_INSTANCE_ID) {
+ return { ...SAMPLE_WORKFLOW, id: UNIMPORTABLE_WORKFLOW_ID };
+ }
+ return SAMPLE_WORKFLOW;
+ }),
}),
};
});
const localVue = getLocalVue();
-async function mountWorkflowRunButton(ownsWorkflow = true, hasReturnBtn = false) {
+/**
+ * Mounts the WorkflowInvocationHeader component with props/stores adjusted given the parameters
+ * @param ownsWorkflow Whether the user owns the workflow associated with the invocation
+ * @param hasReturnBtn Whether the component should have a return to invocations list button
+ * @param unimportableWorkflow Whether the workflow import should fail
+ * @returns The wrapper object
+ */
+async function mountWorkflowRunButton(ownsWorkflow = true, hasReturnBtn = false, unimportableWorkflow = false) {
const wrapper = shallowMount(WorkflowInvocationHeader as object, {
propsData: {
- invocation: sampleInvocation,
+ invocation: {
+ ...sampleInvocation,
+ workflow_id: !unimportableWorkflow ? sampleInvocation.workflow_id : UNIMPORTABLE_WORKFLOW_INSTANCE_ID,
+ },
fromPanel: !hasReturnBtn,
},
localVue,
@@ -53,7 +83,7 @@ async function mountWorkflowRunButton(ownsWorkflow = true, hasReturnBtn = false)
const userStore = useUserStore();
userStore.currentUser = {
id: "1",
- email: "",
+ email: "test@mail.test",
tags_used: [],
isAnonymous: false,
total_disk_usage: 0,
@@ -99,25 +129,32 @@ describe("WorkflowInvocationHeader renders", () => {
});
});
-// describe("Importing a workflow in WorkflowInvocationHeader", () => {
-// it("should show a confirmation dialog when the import is successful", async () => {
-// const { wrapper } = await mountWorkflowRunButton(false);
-// const actionsGroup = wrapper.find(SELECTORS.ACTIONS_BUTTON_GROUP);
-// const importButton = actionsGroup.find(SELECTORS.IMPORT_WORKFLOW_BUTTON);
-// // await importButton.trigger("click");
-// // await flushPromises();
-
-// // Clicking doesn't work because the button is an anonymous-stub which has a child button
-// // So we need to call the function the action="[Function]" event which is the attributes("action") of the anonymous-stub
-// const action = importButton.attributes("action");
-// // await (action as any)();
-// // await flushPromises();
-// // logging action just gives [Function], print the actual function
-// if (typeof action === "string") {
-// console.log(action.toString());
-// } else {
-// console.log("Action is not a string");
-// }
-// console.log(wrapper.html());
-// });
-// });
+describe("Importing a workflow in WorkflowInvocationHeader", () => {
+ it("should show a confirmation dialog when the import is successful", async () => {
+ const { wrapper } = await mountWorkflowRunButton(false);
+ const actionsGroup = wrapper.find(SELECTORS.ACTIONS_BUTTON_GROUP);
+ const importButton = actionsGroup.find(SELECTORS.IMPORT_WORKFLOW_BUTTON);
+
+ // Cannot `.trigger("click")` on `AsyncButton` because it is a stubbed custom component
+ await importButton.props().action();
+ await flushPromises();
+
+ const alert = wrapper.find(SELECTORS.ALERT_MESSAGE);
+ expect(alert.attributes("variant")).toBe("info");
+ expect(alert.text()).toContain(`Workflow ${SAMPLE_WORKFLOW.name} imported successfully`);
+ });
+
+ it("should show an error dialog when the import fails", async () => {
+ const { wrapper } = await mountWorkflowRunButton(false, false, true);
+ const actionsGroup = wrapper.find(SELECTORS.ACTIONS_BUTTON_GROUP);
+ const importButton = actionsGroup.find(SELECTORS.IMPORT_WORKFLOW_BUTTON);
+
+ // Cannot `.trigger("click")` on `AsyncButton` because it is a stubbed custom component
+ await importButton.props().action();
+ await flushPromises();
+
+ const alert = wrapper.find(SELECTORS.ALERT_MESSAGE);
+ expect(alert.attributes("variant")).toBe("danger");
+ expect(alert.text()).toContain(IMPORT_ERROR_MESSAGE);
+ });
+});