From 9454a851bb92b5aa45b8b002a33e54b6819e9a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Thu, 27 Jun 2024 11:20:59 +0200 Subject: [PATCH] refactor(core): Add more unit tests for `Workflow.ts` (no-changelog) (#9868) Co-authored-by: Danny Martini --- packages/workflow/src/Workflow.ts | 47 +- packages/workflow/test/Workflow.test.ts | 701 ++++++++++++++---------- 2 files changed, 438 insertions(+), 310 deletions(-) diff --git a/packages/workflow/src/Workflow.ts b/packages/workflow/src/Workflow.ts index 26d2c30a82..9b2042d7f8 100644 --- a/packages/workflow/src/Workflow.ts +++ b/packages/workflow/src/Workflow.ts @@ -63,6 +63,18 @@ function dedupe(arr: T[]): T[] { return [...new Set(arr)]; } +export interface WorkflowParameters { + id?: string; + name?: string; + nodes: INode[]; + connections: IConnections; + active: boolean; + nodeTypes: INodeTypes; + staticData?: IDataObject; + settings?: IWorkflowSettings; + pinData?: IPinData; +} + export class Workflow { id: string; @@ -90,18 +102,7 @@ export class Workflow { pinData?: IPinData; - // constructor(id: string | undefined, nodes: INode[], connections: IConnections, active: boolean, nodeTypes: INodeTypes, staticData?: IDataObject, settings?: IWorkflowSettings) { - constructor(parameters: { - id?: string; - name?: string; - nodes: INode[]; - connections: IConnections; - active: boolean; - nodeTypes: INodeTypes; - staticData?: IDataObject; - settings?: IWorkflowSettings; - pinData?: IPinData; - }) { + constructor(parameters: WorkflowParameters) { this.id = parameters.id as string; // @tech_debt Ensure this is not optional this.name = parameters.name; this.nodeTypes = parameters.nodeTypes; @@ -251,16 +252,14 @@ export class Workflow { * is fine. If there are issues it returns the issues * which have been found for the different nodes. * TODO: Does currently not check for credential issues! - * */ - checkReadyForExecution(inputData: { - startNode?: string; - destinationNode?: string; - pinDataNodeNames?: string[]; - }): IWorkflowIssues | null { - let node: INode; - let nodeType: INodeType | undefined; - let nodeIssues: INodeIssues | null = null; + checkReadyForExecution( + inputData: { + startNode?: string; + destinationNode?: string; + pinDataNodeNames?: string[]; + } = {}, + ): IWorkflowIssues | null { const workflowIssues: IWorkflowIssues = {}; let checkNodes: string[] = []; @@ -277,14 +276,14 @@ export class Workflow { } for (const nodeName of checkNodes) { - nodeIssues = null; - node = this.nodes[nodeName]; + let nodeIssues: INodeIssues | null = null; + const node = this.nodes[nodeName]; if (node.disabled === true) { continue; } - nodeType = this.nodeTypes.getByNameAndVersion(node.type, node.typeVersion); + const nodeType = this.nodeTypes.getByNameAndVersion(node.type, node.typeVersion); if (nodeType === undefined) { // Node type is not known diff --git a/packages/workflow/test/Workflow.test.ts b/packages/workflow/test/Workflow.test.ts index 28bac2c13b..ba2873e485 100644 --- a/packages/workflow/test/Workflow.test.ts +++ b/packages/workflow/test/Workflow.test.ts @@ -1,3 +1,5 @@ +import { mock } from 'jest-mock-extended'; +import { NodeConnectionType } from '@/Interfaces'; import type { IBinaryKeyData, IConnections, @@ -5,10 +7,14 @@ import type { INode, INodeExecutionData, INodeParameters, + INodeType, + INodeTypeDescription, + INodeTypes, IRunExecutionData, NodeParameterValueType, } from '@/Interfaces'; -import { Workflow } from '@/Workflow'; +import { Workflow, type WorkflowParameters } from '@/Workflow'; +import * as NodeHelpers from '@/NodeHelpers'; process.env.TEST_VARIABLE_1 = 'valueEnvVariable1'; @@ -20,303 +26,426 @@ interface StubNode { } describe('Workflow', () => { - describe('renameNodeInParameterValue for expressions', () => { - const tests = [ - { - description: 'do nothing if there is no expression', - input: { - currentName: 'Node1', - newName: 'Node1New', - parameters: { + describe('checkIfWorkflowCanBeActivated', () => { + const disabledNode = mock({ type: 'triggerNode', disabled: true }); + const unknownNode = mock({ type: 'unknownNode' }); + const noTriggersNode = mock({ type: 'noTriggersNode' }); + const pollNode = mock({ type: 'pollNode' }); + const triggerNode = mock({ type: 'triggerNode' }); + const webhookNode = mock({ type: 'webhookNode' }); + + const nodeTypes = mock(); + nodeTypes.getByNameAndVersion.mockImplementation((type) => { + // TODO: getByNameAndVersion signature needs to be updated to allow returning undefined + if (type === 'unknownNode') return undefined as unknown as INodeType; + const partial: Partial = { + poll: undefined, + trigger: undefined, + webhook: undefined, + description: mock({ + properties: [], + }), + }; + if (type === 'pollNode') partial.poll = jest.fn(); + if (type === 'triggerNode') partial.trigger = jest.fn(); + if (type === 'webhookNode') partial.webhook = jest.fn(); + return mock(partial); + }); + + test.each([ + ['should skip disabled nodes', disabledNode, [], false], + ['should skip nodes marked as ignored', triggerNode, ['triggerNode'], false], + ['should skip unknown nodes', unknownNode, [], false], + ['should skip nodes with no trigger method', noTriggersNode, [], false], + ['should activate if poll method exists', pollNode, [], true], + ['should activate if trigger method exists', triggerNode, [], true], + ['should activate if webhook method exists', webhookNode, [], true], + ])('%s', async (_, node, ignoredNodes, expected) => { + const params = mock({ nodeTypes }); + params.nodes = [node]; + const workflow = new Workflow(params); + expect(workflow.checkIfWorkflowCanBeActivated(ignoredNodes)).toBe(expected); + }); + }); + + describe('checkReadyForExecution', () => { + const disabledNode = mock({ name: 'Disabled Node', disabled: true }); + const startNode = mock({ name: 'Start Node' }); + const unknownNode = mock({ name: 'Unknown Node', type: 'unknownNode' }); + + const nodeParamIssuesSpy = jest.spyOn(NodeHelpers, 'getNodeParametersIssues'); + + const nodeTypes = mock(); + nodeTypes.getByNameAndVersion.mockImplementation((type) => { + // TODO: getByNameAndVersion signature needs to be updated to allow returning undefined + if (type === 'unknownNode') return undefined as unknown as INodeType; + return mock({ + description: { + properties: [], + }, + }); + }); + + beforeEach(() => jest.clearAllMocks()); + + it('should return null if there are no nodes', () => { + const workflow = new Workflow({ + nodes: [], + connections: {}, + active: false, + nodeTypes, + }); + + const issues = workflow.checkReadyForExecution(); + expect(issues).toBe(null); + expect(nodeTypes.getByNameAndVersion).not.toHaveBeenCalled(); + expect(nodeParamIssuesSpy).not.toHaveBeenCalled(); + }); + + it('should return null if there are no enabled nodes', () => { + const workflow = new Workflow({ + nodes: [disabledNode], + connections: {}, + active: false, + nodeTypes, + }); + + const issues = workflow.checkReadyForExecution({ startNode: disabledNode.name }); + expect(issues).toBe(null); + expect(nodeTypes.getByNameAndVersion).toHaveBeenCalledTimes(1); + expect(nodeParamIssuesSpy).not.toHaveBeenCalled(); + }); + + it('should return typeUnknown for unknown nodes', () => { + const workflow = new Workflow({ + nodes: [unknownNode], + connections: {}, + active: false, + nodeTypes, + }); + + const issues = workflow.checkReadyForExecution({ startNode: unknownNode.name }); + expect(issues).toEqual({ [unknownNode.name]: { typeUnknown: true } }); + expect(nodeTypes.getByNameAndVersion).toHaveBeenCalledTimes(2); + expect(nodeParamIssuesSpy).not.toHaveBeenCalled(); + }); + + it('should return issues for regular nodes', () => { + const workflow = new Workflow({ + nodes: [startNode], + connections: {}, + active: false, + nodeTypes, + }); + nodeParamIssuesSpy.mockReturnValue({ execution: false }); + + const issues = workflow.checkReadyForExecution({ startNode: startNode.name }); + expect(issues).toEqual({ [startNode.name]: { execution: false } }); + expect(nodeTypes.getByNameAndVersion).toHaveBeenCalledTimes(2); + expect(nodeParamIssuesSpy).toHaveBeenCalled(); + }); + }); + + describe('renameNodeInParameterValue', () => { + describe('for expressions', () => { + const tests = [ + { + description: 'do nothing if there is no expression', + input: { + currentName: 'Node1', + newName: 'Node1New', + parameters: { + value1: 'value1Node1', + value2: 'value2Node1', + }, + }, + output: { value1: 'value1Node1', value2: 'value2Node1', }, }, - output: { - value1: 'value1Node1', - value2: 'value2Node1', - }, - }, - { - description: 'should work with dot notation', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: "={{$node.Node1.data.value1 + 'Node1'}}", - value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", + { + description: 'should work with dot notation', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: "={{$node.Node1.data.value1 + 'Node1'}}", + value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", + }, + }, + output: { + value1: "={{$node.NewName.data.value1 + 'Node1'}}", + value2: "={{$node.NewName.data.value2 + ' - ' + $node.NewName.data.value2}}", }, }, - output: { - value1: "={{$node.NewName.data.value1 + 'Node1'}}", - value2: "={{$node.NewName.data.value2 + ' - ' + $node.NewName.data.value2}}", - }, - }, - { - description: 'should work with ["nodeName"]', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: '={{$node["Node1"]["data"]["value1"] + \'Node1\'}}', + { + description: 'should work with ["nodeName"]', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: '={{$node["Node1"]["data"]["value1"] + \'Node1\'}}', + value2: + '={{$node["Node1"]["data"]["value2"] + \' - \' + $node["Node1"]["data"]["value2"]}}', + }, + }, + output: { + value1: '={{$node["NewName"]["data"]["value1"] + \'Node1\'}}', value2: - '={{$node["Node1"]["data"]["value2"] + \' - \' + $node["Node1"]["data"]["value2"]}}', + '={{$node["NewName"]["data"]["value2"] + \' - \' + $node["NewName"]["data"]["value2"]}}', }, }, - output: { - value1: '={{$node["NewName"]["data"]["value1"] + \'Node1\'}}', - value2: - '={{$node["NewName"]["data"]["value2"] + \' - \' + $node["NewName"]["data"]["value2"]}}', - }, - }, - { - description: 'should work with $("Node1")', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: '={{$("Node1")["data"]["value1"] + \'Node1\'}}', - value2: '={{$("Node1")["data"]["value2"] + \' - \' + $("Node1")["data"]["value2"]}}', + { + description: 'should work with $("Node1")', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: '={{$("Node1")["data"]["value1"] + \'Node1\'}}', + value2: '={{$("Node1")["data"]["value2"] + \' - \' + $("Node1")["data"]["value2"]}}', + }, }, - }, - output: { - value1: '={{$("NewName")["data"]["value1"] + \'Node1\'}}', - value2: '={{$("NewName")["data"]["value2"] + \' - \' + $("NewName")["data"]["value2"]}}', - }, - }, - { - description: 'should work with $items("Node1")', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: '={{$items("Node1")["data"]["value1"] + \'Node1\'}}', + output: { + value1: '={{$("NewName")["data"]["value1"] + \'Node1\'}}', value2: - '={{$items("Node1")["data"]["value2"] + \' - \' + $items("Node1")["data"]["value2"]}}', + '={{$("NewName")["data"]["value2"] + \' - \' + $("NewName")["data"]["value2"]}}', }, }, - output: { - value1: '={{$items("NewName")["data"]["value1"] + \'Node1\'}}', - value2: - '={{$items("NewName")["data"]["value2"] + \' - \' + $items("NewName")["data"]["value2"]}}', - }, - }, - { - description: 'should work with $items("Node1", 0, 1)', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: '={{$items("Node1", 0, 1)["data"]["value1"] + \'Node1\'}}', + { + description: 'should work with $items("Node1")', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: '={{$items("Node1")["data"]["value1"] + \'Node1\'}}', + value2: + '={{$items("Node1")["data"]["value2"] + \' - \' + $items("Node1")["data"]["value2"]}}', + }, + }, + output: { + value1: '={{$items("NewName")["data"]["value1"] + \'Node1\'}}', value2: - '={{$items("Node1", 0, 1)["data"]["value2"] + \' - \' + $items("Node1", 0, 1)["data"]["value2"]}}', + '={{$items("NewName")["data"]["value2"] + \' - \' + $items("NewName")["data"]["value2"]}}', }, }, - output: { - value1: '={{$items("NewName", 0, 1)["data"]["value1"] + \'Node1\'}}', - value2: - '={{$items("NewName", 0, 1)["data"]["value2"] + \' - \' + $items("NewName", 0, 1)["data"]["value2"]}}', - }, - }, - { - description: 'should work with dot notation that contains space and special character', - input: { - currentName: 'Node1', - newName: 'New $ Name', - parameters: { - value1: "={{$node.Node1.data.value1 + 'Node1'}}", - value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", + { + description: 'should work with $items("Node1", 0, 1)', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: '={{$items("Node1", 0, 1)["data"]["value1"] + \'Node1\'}}', + value2: + '={{$items("Node1", 0, 1)["data"]["value2"] + \' - \' + $items("Node1", 0, 1)["data"]["value2"]}}', + }, }, - }, - output: { - value1: '={{$node["New $ Name"].data.value1 + \'Node1\'}}', - value2: - '={{$node["New $ Name"].data.value2 + \' - \' + $node["New $ Name"].data.value2}}', - }, - }, - { - description: 'should work with dot notation that contains space and trailing $', - input: { - currentName: 'Node1', - newName: 'NewName$', - parameters: { - value1: "={{$node.Node1.data.value1 + 'Node1'}}", - value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", - }, - }, - output: { - value1: '={{$node["NewName$"].data.value1 + \'Node1\'}}', - value2: '={{$node["NewName$"].data.value2 + \' - \' + $node["NewName$"].data.value2}}', - }, - }, - { - description: 'should work with dot notation that contains space and special character', - input: { - currentName: 'Node1', - newName: 'NewName $ $& $` $$$', - parameters: { - value1: "={{$node.Node1.data.value1 + 'Node1'}}", - value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", - }, - }, - output: { - value1: '={{$node["NewName $ $& $` $$$"].data.value1 + \'Node1\'}}', - value2: - '={{$node["NewName $ $& $` $$$"].data.value2 + \' - \' + $node["NewName $ $& $` $$$"].data.value2}}', - }, - }, - { - description: 'should work with dot notation without trailing dot', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: "={{$node.Node1 + 'Node1'}}", - value2: "={{$node.Node1 + ' - ' + $node.Node1}}", - }, - }, - output: { - value1: "={{$node.NewName + 'Node1'}}", - value2: "={{$node.NewName + ' - ' + $node.NewName}}", - }, - }, - { - description: "should work with ['nodeName']", - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - value1: "={{$node['Node1']['data']['value1'] + 'Node1'}}", + output: { + value1: '={{$items("NewName", 0, 1)["data"]["value1"] + \'Node1\'}}', value2: - "={{$node['Node1']['data']['value2'] + ' - ' + $node['Node1']['data']['value2']}}", + '={{$items("NewName", 0, 1)["data"]["value2"] + \' - \' + $items("NewName", 0, 1)["data"]["value2"]}}', }, }, - output: { - value1: "={{$node['NewName']['data']['value1'] + 'Node1'}}", - value2: - "={{$node['NewName']['data']['value2'] + ' - ' + $node['NewName']['data']['value2']}}", + { + description: 'should work with dot notation that contains space and special character', + input: { + currentName: 'Node1', + newName: 'New $ Name', + parameters: { + value1: "={{$node.Node1.data.value1 + 'Node1'}}", + value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", + }, + }, + output: { + value1: '={{$node["New $ Name"].data.value1 + \'Node1\'}}', + value2: + '={{$node["New $ Name"].data.value2 + \' - \' + $node["New $ Name"].data.value2}}', + }, }, - }, - { - description: 'should work on lower levels', - input: { - currentName: 'Node1', - newName: 'NewName', - parameters: { - level1a: "={{$node.Node1.data.value1 + 'Node1'}}", + { + description: 'should work with dot notation that contains space and trailing $', + input: { + currentName: 'Node1', + newName: 'NewName$', + parameters: { + value1: "={{$node.Node1.data.value1 + 'Node1'}}", + value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", + }, + }, + output: { + value1: '={{$node["NewName$"].data.value1 + \'Node1\'}}', + value2: '={{$node["NewName$"].data.value2 + \' - \' + $node["NewName$"].data.value2}}', + }, + }, + { + description: 'should work with dot notation that contains space and special character', + input: { + currentName: 'Node1', + newName: 'NewName $ $& $` $$$', + parameters: { + value1: "={{$node.Node1.data.value1 + 'Node1'}}", + value2: "={{$node.Node1.data.value2 + ' - ' + $node.Node1.data.value2}}", + }, + }, + output: { + value1: '={{$node["NewName $ $& $` $$$"].data.value1 + \'Node1\'}}', + value2: + '={{$node["NewName $ $& $` $$$"].data.value2 + \' - \' + $node["NewName $ $& $` $$$"].data.value2}}', + }, + }, + { + description: 'should work with dot notation without trailing dot', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: "={{$node.Node1 + 'Node1'}}", + value2: "={{$node.Node1 + ' - ' + $node.Node1}}", + }, + }, + output: { + value1: "={{$node.NewName + 'Node1'}}", + value2: "={{$node.NewName + ' - ' + $node.NewName}}", + }, + }, + { + description: "should work with ['nodeName']", + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + value1: "={{$node['Node1']['data']['value1'] + 'Node1'}}", + value2: + "={{$node['Node1']['data']['value2'] + ' - ' + $node['Node1']['data']['value2']}}", + }, + }, + output: { + value1: "={{$node['NewName']['data']['value1'] + 'Node1'}}", + value2: + "={{$node['NewName']['data']['value2'] + ' - ' + $node['NewName']['data']['value2']}}", + }, + }, + { + description: 'should work on lower levels', + input: { + currentName: 'Node1', + newName: 'NewName', + parameters: { + level1a: "={{$node.Node1.data.value1 + 'Node1'}}", + level1b: [ + { + value2a: "={{$node.Node1.data.value1 + 'Node1'}}", + value2b: "={{$node.Node1.data.value1 + 'Node1'}}", + }, + ], + level1c: { + value2a: { + value3a: "={{$node.Node1.data.value1 + 'Node1'}}", + value3b: [ + { + value4a: "={{$node.Node1.data.value1 + 'Node1'}}", + value4b: { + value5a: "={{$node.Node1.data.value1 + 'Node1'}}", + value5b: "={{$node.Node1.data.value1 + 'Node1'}}", + }, + }, + ], + }, + }, + } as INodeParameters, + }, + output: { + level1a: "={{$node.NewName.data.value1 + 'Node1'}}", level1b: [ { - value2a: "={{$node.Node1.data.value1 + 'Node1'}}", - value2b: "={{$node.Node1.data.value1 + 'Node1'}}", + value2a: "={{$node.NewName.data.value1 + 'Node1'}}", + value2b: "={{$node.NewName.data.value1 + 'Node1'}}", }, ], level1c: { value2a: { - value3a: "={{$node.Node1.data.value1 + 'Node1'}}", + value3a: "={{$node.NewName.data.value1 + 'Node1'}}", value3b: [ { - value4a: "={{$node.Node1.data.value1 + 'Node1'}}", + value4a: "={{$node.NewName.data.value1 + 'Node1'}}", value4b: { - value5a: "={{$node.Node1.data.value1 + 'Node1'}}", - value5b: "={{$node.Node1.data.value1 + 'Node1'}}", + value5a: "={{$node.NewName.data.value1 + 'Node1'}}", + value5b: "={{$node.NewName.data.value1 + 'Node1'}}", }, }, ], }, }, - } as INodeParameters, - }, - output: { - level1a: "={{$node.NewName.data.value1 + 'Node1'}}", - level1b: [ - { - value2a: "={{$node.NewName.data.value1 + 'Node1'}}", - value2b: "={{$node.NewName.data.value1 + 'Node1'}}", - }, - ], - level1c: { - value2a: { - value3a: "={{$node.NewName.data.value1 + 'Node1'}}", - value3b: [ - { - value4a: "={{$node.NewName.data.value1 + 'Node1'}}", - value4b: { - value5a: "={{$node.NewName.data.value1 + 'Node1'}}", - value5b: "={{$node.NewName.data.value1 + 'Node1'}}", - }, - }, - ], - }, }, }, - }, - ]; + ]; - const nodeTypes = Helpers.NodeTypes(); - const workflow = new Workflow({ nodes: [], connections: {}, active: false, nodeTypes }); + const nodeTypes = Helpers.NodeTypes(); + const workflow = new Workflow({ nodes: [], connections: {}, active: false, nodeTypes }); - for (const testData of tests) { - test(testData.description, () => { - const result = workflow.renameNodeInParameterValue( - testData.input.parameters, - testData.input.currentName, - testData.input.newName, - ); - expect(result).toEqual(testData.output); - }); - } - }); - - describe('renameNodeInParameterValue for node with renamable content', () => { - const tests = [ - { - description: "should work with $('name')", - input: { - currentName: 'Old', - newName: 'New', - parameters: { jsCode: "$('Old').first();" }, - }, - output: { jsCode: "$('New').first();" }, - }, - { - description: "should work with $node['name'] and $node.name", - input: { - currentName: 'Old', - newName: 'New', - parameters: { jsCode: "$node['Old'].first(); $node.Old.first();" }, - }, - output: { jsCode: "$node['New'].first(); $node.New.first();" }, - }, - { - description: 'should work with $items()', - input: { - currentName: 'Old', - newName: 'New', - parameters: { jsCode: "$items('Old').first();" }, - }, - output: { jsCode: "$items('New').first();" }, - }, - ]; - - const workflow = new Workflow({ - nodes: [], - connections: {}, - active: false, - nodeTypes: Helpers.NodeTypes(), + for (const testData of tests) { + test(testData.description, () => { + const result = workflow.renameNodeInParameterValue( + testData.input.parameters, + testData.input.currentName, + testData.input.newName, + ); + expect(result).toEqual(testData.output); + }); + } }); - for (const t of tests) { - test(t.description, () => { - expect( - workflow.renameNodeInParameterValue( - t.input.parameters, - t.input.currentName, - t.input.newName, - { hasRenamableContent: true }, - ), - ).toEqual(t.output); + describe('for node with renamable content', () => { + const tests = [ + { + description: "should work with $('name')", + input: { + currentName: 'Old', + newName: 'New', + parameters: { jsCode: "$('Old').first();" }, + }, + output: { jsCode: "$('New').first();" }, + }, + { + description: "should work with $node['name'] and $node.name", + input: { + currentName: 'Old', + newName: 'New', + parameters: { jsCode: "$node['Old'].first(); $node.Old.first();" }, + }, + output: { jsCode: "$node['New'].first(); $node.New.first();" }, + }, + { + description: 'should work with $items()', + input: { + currentName: 'Old', + newName: 'New', + parameters: { jsCode: "$items('Old').first();" }, + }, + output: { jsCode: "$items('New').first();" }, + }, + ]; + + const workflow = new Workflow({ + nodes: [], + connections: {}, + active: false, + nodeTypes: Helpers.NodeTypes(), }); - } + + for (const t of tests) { + test(t.description, () => { + expect( + workflow.renameNodeInParameterValue( + t.input.parameters, + t.input.currentName, + t.input.newName, + { hasRenamableContent: true }, + ), + ).toEqual(t.output); + }); + } + }); }); describe('renameNode', () => { @@ -377,7 +506,7 @@ describe('Workflow', () => { [ { node: 'Node2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -408,7 +537,7 @@ describe('Workflow', () => { [ { node: 'Node2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -444,7 +573,7 @@ describe('Workflow', () => { [ { node: 'Node2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -475,7 +604,7 @@ describe('Workflow', () => { [ { node: 'Node2New', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -532,7 +661,7 @@ describe('Workflow', () => { [ { node: 'Node3', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -543,12 +672,12 @@ describe('Workflow', () => { [ { node: 'Node3', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, { node: 'Node5', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -559,12 +688,12 @@ describe('Workflow', () => { [ { node: 'Node4', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, { node: 'Node5', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -616,7 +745,7 @@ describe('Workflow', () => { [ { node: 'Node3New', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -627,12 +756,12 @@ describe('Workflow', () => { [ { node: 'Node3New', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, { node: 'Node5', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -643,12 +772,12 @@ describe('Workflow', () => { [ { node: 'Node4', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, { node: 'Node5', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1229,7 +1358,7 @@ describe('Workflow', () => { [ { node: 'Node2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1240,7 +1369,7 @@ describe('Workflow', () => { [ { node: 'Node3', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1251,7 +1380,7 @@ describe('Workflow', () => { [ { node: 'Node2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1521,7 +1650,7 @@ describe('Workflow', () => { [ { node: 'Set', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1532,7 +1661,7 @@ describe('Workflow', () => { [ { node: 'Set1', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1591,21 +1720,21 @@ describe('Workflow', () => { [ { node: 'Set1', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], [ { node: 'Set', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], [ { node: 'Set', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1616,7 +1745,7 @@ describe('Workflow', () => { [ { node: 'Set2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1627,7 +1756,7 @@ describe('Workflow', () => { [ { node: 'Set2', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1691,7 +1820,7 @@ describe('Workflow', () => { [ { node: 'Set', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1699,7 +1828,7 @@ describe('Workflow', () => { [ { node: 'Switch', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1710,7 +1839,7 @@ describe('Workflow', () => { [ { node: 'Set1', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1721,12 +1850,12 @@ describe('Workflow', () => { [ { node: 'Set1', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, { node: 'Switch', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ], @@ -1737,7 +1866,7 @@ describe('Workflow', () => { [ { node: 'Set1', - type: 'main', + type: NodeConnectionType.Main, index: 0, }, ],