From 26f0d57f5fb71a06c92968a4997cceae62f32312 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Wed, 13 Dec 2023 15:57:01 +0100 Subject: [PATCH] fix(editor): Fix bug with node names with certain characters (#8013) ## Summary Fixes the issue that dots and other special characters can not be used in node-names ## Related tickets and issues https://linear.app/n8n/issue/ADO-1244/nodes-wont-output-data-if-the-name-contains-some-characters https://community.n8n.io/t/bug-report-name-of-node-affects-output-data/31674 https://community.n8n.io/t/stripe-output-data/32418/1 https://community.n8n.io/t/monday-com-returning-items-but-no-data/31834 https://community.n8n.io/t/no-data-while-there-is-actually-data/32563 https://community.n8n.io/t/bug-report-periods-in-node-names/34119 https://github.com/n8n-io/n8n/issues/7896 ## Review / Merge checklist - [ ] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [ ] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. > A feature is not complete without tests. --------- Co-authored-by: Alex Grozav --- .../__tests__/useNodeHelpers.test.ts | 182 ++++++++++++++++++ .../src/composables/useNodeHelpers.ts | 2 +- 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 packages/editor-ui/src/composables/__tests__/useNodeHelpers.test.ts diff --git a/packages/editor-ui/src/composables/__tests__/useNodeHelpers.test.ts b/packages/editor-ui/src/composables/__tests__/useNodeHelpers.test.ts new file mode 100644 index 0000000000000..1969b3d5b8192 --- /dev/null +++ b/packages/editor-ui/src/composables/__tests__/useNodeHelpers.test.ts @@ -0,0 +1,182 @@ +import { setActivePinia } from 'pinia'; +import { createTestingPinia } from '@pinia/testing'; +import { useNodeHelpers } from '@/composables/useNodeHelpers'; +import { createTestNode } from '@/__tests__/mocks'; +import { useWorkflowsStore } from '@/stores/workflows.store'; + +vi.mock('@/stores/workflows.store', () => ({ + useWorkflowsStore: vi.fn(), +})); + +describe('useNodeHelpers()', () => { + beforeAll(() => { + setActivePinia(createTestingPinia()); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('getNodeInputData()', () => { + it('should return an empty array when node is null', () => { + const { getNodeInputData } = useNodeHelpers(); + + const result = getNodeInputData(null); + expect(result).toEqual([]); + }); + + it('should return an empty array when workflowsStore.getWorkflowExecution() is null', () => { + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: null, + } as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: 'test', + type: 'test', + }); + + const result = getNodeInputData(node); + expect(result).toEqual([]); + }); + + it('should return an empty array when workflowsStore.getWorkflowExecution() is null', () => { + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: null, + } as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: 'test', + type: 'test', + }); + + const result = getNodeInputData(node); + expect(result).toEqual([]); + }); + + it('should return an empty array when resultData is not available', () => { + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: { + data: { + resultData: null, + }, + }, + } as unknown as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: 'test', + type: 'test', + }); + + const result = getNodeInputData(node); + expect(result).toEqual([]); + }); + + it('should return an empty array when taskData is unavailable', () => { + const nodeName = 'Code'; + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: { + data: { + resultData: { + runData: { + [nodeName]: [], + }, + }, + }, + }, + } as unknown as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: nodeName, + type: 'test', + }); + + const result = getNodeInputData(node); + expect(result).toEqual([]); + }); + + it('should return an empty array when taskData.data is unavailable', () => { + const nodeName = 'Code'; + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: { + data: { + resultData: { + runData: { + [nodeName]: [{ data: undefined }], + }, + }, + }, + }, + } as unknown as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: nodeName, + type: 'test', + }); + + const result = getNodeInputData(node); + expect(result).toEqual([]); + }); + + it('should return input data from inputOverride', () => { + const nodeName = 'Code'; + const data = { hello: 'world' }; + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: { + data: { + resultData: { + runData: { + [nodeName]: [ + { + inputOverride: { + main: [data], + }, + }, + ], + }, + }, + }, + }, + } as unknown as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: nodeName, + type: 'test', + }); + + const result = getNodeInputData(node, 0, 0, 'input'); + expect(result).toEqual(data); + }); + + it.each(['example', 'example.withdot', 'example.with.dots', 'example.with.dots and spaces'])( + 'should return input data for "%s" node name, with given connection type and output index', + (nodeName) => { + const data = { hello: 'world' }; + vi.mocked(useWorkflowsStore).mockReturnValue({ + getWorkflowExecution: { + data: { + resultData: { + runData: { + [nodeName]: [ + { + data: { + main: [data], + }, + }, + ], + }, + }, + }, + }, + } as unknown as ReturnType); + const { getNodeInputData } = useNodeHelpers(); + const node = createTestNode({ + name: nodeName, + type: 'test', + }); + + const result = getNodeInputData(node); + expect(result).toEqual(data); + }, + ); + }); +}); diff --git a/packages/editor-ui/src/composables/useNodeHelpers.ts b/packages/editor-ui/src/composables/useNodeHelpers.ts index e801a5ab95913..fda8a2fa35bc1 100644 --- a/packages/editor-ui/src/composables/useNodeHelpers.ts +++ b/packages/editor-ui/src/composables/useNodeHelpers.ts @@ -539,7 +539,7 @@ export function useNodeHelpers() { } const runData = executionData.resultData.runData; - const taskData = get(runData, `[${node.name}][${runIndex}]`); + const taskData = get(runData, [node.name, runIndex]); if (!taskData) { return []; }