From 0824800dff7976053f0887af92691f0bf111133c Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Tue, 26 Sep 2023 14:33:42 +0100 Subject: [PATCH] fix(editor): Fix issue that double incoming connection often does not resolve expression (no-changelog) (#7257) Cherry-picked from AI Tool Creation branch --------- Co-authored-by: Jan Oberhauser --- .../mixins/__tests__/workflowHelpers.spec.ts | 232 ++++++++++++++++++ .../editor-ui/src/mixins/workflowHelpers.ts | 14 +- 2 files changed, 238 insertions(+), 8 deletions(-) create mode 100644 packages/editor-ui/src/mixins/__tests__/workflowHelpers.spec.ts diff --git a/packages/editor-ui/src/mixins/__tests__/workflowHelpers.spec.ts b/packages/editor-ui/src/mixins/__tests__/workflowHelpers.spec.ts new file mode 100644 index 0000000000..4142097d4e --- /dev/null +++ b/packages/editor-ui/src/mixins/__tests__/workflowHelpers.spec.ts @@ -0,0 +1,232 @@ +import { createPinia, setActivePinia } from 'pinia'; +import { useSettingsStore, useWorkflowsStore } from '@/stores'; +import { setupServer } from '@/__tests__/server'; +import { executeData } from '@/mixins/workflowHelpers'; +import type { IExecutionResponse } from '@/Interface'; + +describe('workflowHelpers', () => { + let server: ReturnType; + let pinia: ReturnType; + let workflowsStore: ReturnType; + let settingsStore: ReturnType; + + beforeAll(() => { + server = setupServer(); + }); + + beforeEach(async () => { + pinia = createPinia(); + setActivePinia(pinia); + + workflowsStore = useWorkflowsStore(); + settingsStore = useSettingsStore(); + + await settingsStore.getSettings(); + }); + + afterAll(() => { + server.shutdown(); + }); + + describe('executeData()', () => { + it('should return empty execute data if no parent nodes', () => { + const parentNodes: string[] = []; + const currentNode = 'Set'; + const inputName = 'main'; + const runIndex = 0; + + const result = executeData(parentNodes, currentNode, inputName, runIndex); + + expect(result).toEqual({ + node: {}, + data: {}, + source: null, + }); + }); + + it('should return the correct execution data with one parent node', () => { + const parentNodes = ['Start']; + const currentNode = 'Set'; + const inputName = 'main'; + const runIndex = 0; + const jsonData = { + name: 'Test', + }; + + workflowsStore.workflowExecutionData = { + data: { + resultData: { + runData: { + [parentNodes[0]]: [ + { + startTime: 0, + executionTime: 0, + data: { + main: [ + { + json: jsonData, + index: 0, + }, + ], + }, + source: [], + }, + ], + }, + }, + }, + } as unknown as IExecutionResponse; + + const result = executeData(parentNodes, currentNode, inputName, runIndex); + + expect(result).toEqual({ + node: {}, + data: { + main: [ + { + index: 0, + json: jsonData, + }, + ], + }, + source: { + main: [ + { + previousNode: parentNodes[0], + }, + ], + }, + }); + }); + + it('should return the correct execution data with multiple parent nodes, only one with execution data', () => { + const parentNodes = ['Parent A', 'Parent B']; + const currentNode = 'Set'; + const inputName = 'main'; + const runIndex = 0; + const jsonData = { + name: 'Test', + }; + + workflowsStore.workflowExecutionData = { + data: { + resultData: { + runData: { + [parentNodes[1]]: [ + { + startTime: 0, + executionTime: 0, + data: { + main: [ + { + json: jsonData, + index: 0, + }, + ], + }, + source: [], + }, + ], + }, + }, + }, + } as unknown as IExecutionResponse; + + const result = executeData(parentNodes, currentNode, inputName, runIndex); + + expect(result).toEqual({ + node: {}, + data: { + main: [ + { + index: 0, + json: jsonData, + }, + ], + }, + source: { + main: [ + { + previousNode: parentNodes[1], + }, + ], + }, + }); + }); + + it('should return the correct execution data with multiple parent nodes, all with execution data', () => { + const parentNodes = ['Parent A', 'Parent B']; + const currentNode = 'Set'; + const inputName = 'main'; + const runIndex = 0; + + const jsonDataA = { + name: 'Test A', + }; + + const jsonDataB = { + name: 'Test B', + }; + + workflowsStore.workflowExecutionData = { + data: { + resultData: { + runData: { + [parentNodes[0]]: [ + { + startTime: 0, + executionTime: 0, + data: { + main: [ + { + json: jsonDataA, + index: 0, + }, + ], + }, + source: [], + }, + ], + [parentNodes[1]]: [ + { + startTime: 0, + executionTime: 0, + data: { + main: [ + { + json: jsonDataB, + index: 0, + }, + ], + }, + source: [], + }, + ], + }, + }, + }, + } as unknown as IExecutionResponse; + + const result = executeData(parentNodes, currentNode, inputName, runIndex); + + expect(result).toEqual({ + node: {}, + data: { + main: [ + { + index: 0, + json: jsonDataA, + }, + ], + }, + source: { + main: [ + { + previousNode: parentNodes[0], + }, + ], + }, + }); + }); + }); +}); diff --git a/packages/editor-ui/src/mixins/workflowHelpers.ts b/packages/editor-ui/src/mixins/workflowHelpers.ts index 4dba373ba1..01f2714fad 100644 --- a/packages/editor-ui/src/mixins/workflowHelpers.ts +++ b/packages/editor-ui/src/mixins/workflowHelpers.ts @@ -305,8 +305,8 @@ function connectionInputData( return connectionInputData; } -function executeData( - parentNode: string[], +export function executeData( + parentNodes: string[], currentNode: string, inputName: string, runIndex: number, @@ -317,12 +317,10 @@ function executeData( source: null, } as IExecuteData; - if (parentNode.length) { - // Add the input data to be able to also resolve the short expression format - // which does not use the node name - const parentNodeName = parentNode[0]; - const workflowsStore = useWorkflowsStore(); + const workflowsStore = useWorkflowsStore(); + // Find the parent node which has data + for (const parentNodeName of parentNodes) { if (workflowsStore.shouldReplaceInputDataWithPinData) { const parentPinData = workflowsStore.getPinData![parentNodeName]; @@ -337,7 +335,6 @@ function executeData( } // populate `executeData` from `runData` - const workflowRunData = workflowsStore.getWorkflowRunData; if (workflowRunData === null) { return executeData; @@ -368,6 +365,7 @@ function executeData( ], }; } + return executeData; } }