From 26b69b5ffc308185b82d50b9cb0239f7ea9e55f9 Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Tue, 7 Feb 2023 11:27:37 +0200 Subject: [PATCH] test(Item Lists Node): Unit tests (no-changelog) --- package.json | 2 +- .../ItemLists/test/node/ItemLists.test.ts | 5 + .../test/node/workflow.aggregateItems.json | 223 +++++++++++ .../ItemLists/test/node/workflow.limit.json | 97 +++++ .../test/node/workflow.removeDuplicates.json | 177 +++++++++ .../ItemLists/test/node/workflow.sort.json | 216 +++++++++++ .../test/node/workflow.splitOutItems.json | 360 ++++++++++++++++++ .../test/node/workflow.summarize.json | 299 +++++++++++++++ .../nodes-base/test/nodes/ExecuteWorkflow.ts | 3 +- packages/nodes-base/test/nodes/Helpers.ts | 71 +++- 10 files changed, 1450 insertions(+), 3 deletions(-) create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/ItemLists.test.ts create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/workflow.aggregateItems.json create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/workflow.limit.json create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/workflow.removeDuplicates.json create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/workflow.sort.json create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/workflow.splitOutItems.json create mode 100644 packages/nodes-base/nodes/ItemLists/test/node/workflow.summarize.json diff --git a/package.json b/package.json index 7c10921722..b859df9a60 100644 --- a/package.json +++ b/package.json @@ -77,4 +77,4 @@ "element-ui@2.15.12": "patches/element-ui@2.15.12.patch" } } -} +} \ No newline at end of file diff --git a/packages/nodes-base/nodes/ItemLists/test/node/ItemLists.test.ts b/packages/nodes-base/nodes/ItemLists/test/node/ItemLists.test.ts new file mode 100644 index 0000000000..715ee90b71 --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/ItemLists.test.ts @@ -0,0 +1,5 @@ +import { testWorkflows, getWorkflowFilenames } from '../../../../test/nodes/Helpers'; + +const workflows = getWorkflowFilenames(__dirname); + +describe('Test ItemLists Node', () => testWorkflows(workflows)); diff --git a/packages/nodes-base/nodes/ItemLists/test/node/workflow.aggregateItems.json b/packages/nodes-base/nodes/ItemLists/test/node/workflow.aggregateItems.json new file mode 100644 index 0000000000..9024d37b34 --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/workflow.aggregateItems.json @@ -0,0 +1,223 @@ +{ + "name": "itemLists test", + "nodes": [ + { + "parameters": {}, + "id": "6c90bf81-0c0e-4c5f-9f0c-297f06d9668a", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [-440, 260] + }, + { + "parameters": { + "jsCode": "return [\n {id: 1, char: 'a'},\n {id: 2, char: 'b'},\n {id: 3, char: 'c'},\n {id: 4, char: 'd'},\n {id: 5, char: 'e'},\n];" + }, + "id": "2e0011d5-c6a0-4a40-ab8c-9d011cde40d5", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [-180, 260] + }, + { + "parameters": { + "operation": "aggregateItems", + "fieldsToAggregate": { + "fieldToAggregate": [ + { + "fieldToAggregate": "id", + "renameField": true, + "outputFieldName": "data" + } + ] + }, + "options": {} + }, + "id": "d95ca3a3-fb43-4037-846e-b87103dec1a3", + "name": "fields aggregate and rename", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 0] + }, + { + "parameters": { + "operation": "aggregateItems", + "aggregate": "aggregateAllItemData" + }, + "id": "4c1bc7be-7611-418d-aad5-8642b1cc0781", + "name": "aggregate all fields into list", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 320] + }, + { + "parameters": { + "operation": "aggregateItems", + "aggregate": "aggregateAllItemData", + "include": "specifiedFields", + "fieldsToInclude": { + "fields": [ + { + "fieldName": "id" + } + ] + } + }, + "id": "951de23c-2018-437b-961e-8ae7d7fd1a82", + "name": "aggregate selected fields into list", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 500] + }, + { + "parameters": { + "operation": "aggregateItems", + "aggregate": "aggregateAllItemData", + "destinationFieldName": "output", + "include": "allFieldsExcept", + "fieldsToExclude": { + "fields": [ + { + "fieldName": "char" + } + ] + } + }, + "id": "b62c02ee-5edb-473d-a755-7fb8700641fa", + "name": "aggregate all fields except selected into list", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 700] + } + ], + "pinData": { + "fields aggregate and rename": [ + { + "json": { + "data": [1, 2, 3, 4, 5] + } + } + ], + "aggregate all fields into list": [ + { + "json": { + "data": [ + { + "id": 1, + "char": "a" + }, + { + "id": 2, + "char": "b" + }, + { + "id": 3, + "char": "c" + }, + { + "id": 4, + "char": "d" + }, + { + "id": 5, + "char": "e" + } + ] + } + } + ], + "aggregate selected fields into list": [ + { + "json": { + "data": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + } + ] + } + } + ], + "aggregate all fields except selected into list": [ + { + "json": { + "output": [ + { + "id": 1 + }, + { + "id": 2 + }, + { + "id": 3 + }, + { + "id": 4 + }, + { + "id": 5 + } + ] + } + } + ] + }, + "connections": { + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [ + [ + { + "node": "fields aggregate and rename", + "type": "main", + "index": 0 + }, + { + "node": "aggregate all fields into list", + "type": "main", + "index": 0 + }, + { + "node": "aggregate selected fields into list", + "type": "main", + "index": 0 + }, + { + "node": "aggregate all fields except selected into list", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "9bf7c52b-b118-4dad-bfef-7db41828393b", + "id": "105", + "meta": { + "instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0" + }, + "tags": [] +} diff --git a/packages/nodes-base/nodes/ItemLists/test/node/workflow.limit.json b/packages/nodes-base/nodes/ItemLists/test/node/workflow.limit.json new file mode 100644 index 0000000000..f1d18040e2 --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/workflow.limit.json @@ -0,0 +1,97 @@ +{ + "name": "itemLists test", + "nodes": [ + { + "parameters": {}, + "id": "bd7af0bb-de39-44b4-ac11-eb1d22f5e8d7", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [260, 180] + }, + { + "parameters": { + "jsCode": "return [\n {entry: 1},\n {entry: 2},\n {entry: 3},\n {entry: 4},\n {entry: 5},\n];" + }, + "id": "21185d7a-f0c1-49a0-9c2d-f0f198ceea7e", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [520, 180] + }, + { + "parameters": { + "operation": "limit" + }, + "id": "7cc02cc4-1f5f-489a-81e2-4c96b3bdf221", + "name": "Item Lists limit first", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [740, 80] + }, + { + "parameters": { + "operation": "limit", + "keep": "lastItems" + }, + "id": "2bf79d53-7a0b-4716-aa09-55ad43d306ae", + "name": "Item Lists limit last", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [740, 300] + } + ], + "pinData": { + "Item Lists limit first": [ + { + "json": { + "entry": 1 + } + } + ], + "Item Lists limit last": [ + { + "json": { + "entry": 5 + } + } + ] + }, + "connections": { + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [ + [ + { + "node": "Item Lists limit first", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists limit last", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "5036d554-1ba4-4b5f-ba9f-1de6df09e807", + "id": "105", + "meta": { + "instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0" + }, + "tags": [] +} diff --git a/packages/nodes-base/nodes/ItemLists/test/node/workflow.removeDuplicates.json b/packages/nodes-base/nodes/ItemLists/test/node/workflow.removeDuplicates.json new file mode 100644 index 0000000000..723deb2240 --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/workflow.removeDuplicates.json @@ -0,0 +1,177 @@ +{ + "name": "itemLists test", + "nodes": [ + { + "parameters": {}, + "id": "c36aef04-b8ee-4f50-938b-ec64c4f78c97", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [860, 340] + }, + { + "parameters": { + "jsCode": "return [\n {entry: 1, data: 'a', char: 'a'},\n {entry: 1, data: 'b', char: 'a'},\n {entry: 1, data: 'a', char: 'a'},\n {entry: 4, data: 'd', char: 'a'},\n {entry: 5, data: 'e', char: 'a'},\n];" + }, + "id": "79f44614-aaf8-421a-9cad-2d92445a5dd5", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [1120, 340] + }, + { + "parameters": { + "operation": "removeDuplicates", + "compare": "allFieldsExcept", + "fieldsToExclude": { + "fields": [ + { + "fieldName": "data" + } + ] + }, + "options": {} + }, + "id": "c1f69c55-caba-4d44-b209-445f4bef3756", + "name": "Item Lists remove duplicates exclude", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [1320, 340] + }, + { + "parameters": { + "operation": "removeDuplicates", + "compare": "selectedFields", + "fieldsToCompare": { + "fields": [ + { + "fieldName": "char" + } + ] + }, + "options": { + "removeOtherFields": true + } + }, + "id": "7b9f0a7c-25f0-4d1f-b30f-666ddcaf5d98", + "name": "Item Lists remove duplicates selected", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [1340, 560] + }, + { + "parameters": { + "operation": "removeDuplicates" + }, + "id": "9762644f-34cb-48ca-b8a3-e0aa0ca05d4a", + "name": "Item Lists remove duplicates", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [1320, 120] + } + ], + "pinData": { + "Item Lists remove duplicates selected": [ + { + "json": { + "char": "a" + } + } + ], + "Item Lists remove duplicates exclude": [ + { + "json": { + "entry": 1, + "data": "a", + "char": "a" + } + }, + { + "json": { + "entry": 4, + "data": "d", + "char": "a" + } + }, + { + "json": { + "entry": 5, + "data": "e", + "char": "a" + } + } + ], + "Item Lists remove duplicates": [ + { + "json": { + "entry": 1, + "data": "a", + "char": "a" + } + }, + { + "json": { + "entry": 1, + "data": "b", + "char": "a" + } + }, + { + "json": { + "entry": 4, + "data": "d", + "char": "a" + } + }, + { + "json": { + "entry": 5, + "data": "e", + "char": "a" + } + } + ] + }, + "connections": { + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [ + [ + { + "node": "Item Lists remove duplicates", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists remove duplicates exclude", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists remove duplicates selected", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "9b7b1482-ceaa-4878-8091-d6fbfbe58a79", + "id": "105", + "meta": { + "instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0" + }, + "tags": [] +} diff --git a/packages/nodes-base/nodes/ItemLists/test/node/workflow.sort.json b/packages/nodes-base/nodes/ItemLists/test/node/workflow.sort.json new file mode 100644 index 0000000000..2f95bee14e --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/workflow.sort.json @@ -0,0 +1,216 @@ +{ + "name": "itemLists test", + "nodes": [ + { + "parameters": {}, + "id": "6c90bf81-0c0e-4c5f-9f0c-297f06d9668a", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [-440, 300] + }, + { + "parameters": { + "jsCode": "return [\n {id: 3, char: 'c'},\n {id: 4, char: 'd'},\n {id: 5, char: 'e'},\n {id: 1, char: 'a'},\n {id: 2, char: 'b'},\n];" + }, + "id": "2e0011d5-c6a0-4a40-ab8c-9d011cde40d5", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [-180, 300] + }, + { + "parameters": { + "operation": "sort", + "sortFieldsUi": { + "sortField": [ + { + "fieldName": "char", + "order": "descending" + }, + { + "fieldName": "id", + "order": "descending" + } + ] + }, + "options": {} + }, + "id": "20031848-2374-45b2-98db-69d7b8d055ad", + "name": "Item Lists1", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 300] + }, + { + "parameters": { + "operation": "sort", + "sortFieldsUi": { + "sortField": [ + { + "fieldName": "id" + } + ] + }, + "options": {} + }, + "id": "93dd8c32-21e1-4762-a340-b3e8c6866811", + "name": "Item Lists", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 120] + }, + { + "parameters": { + "operation": "sort", + "type": "code", + "code": "// The two items to compare are in the variables a and b\n// Access the fields in a.json and b.json\n// Return -1 if a should go before b\n// Return 1 if b should go before a\n// Return 0 if there's no difference\n\nfieldName = 'id';\n\nif (a.json[fieldName] < b.json[fieldName]) {\n\t\treturn -1;\n}\nif (a.json[fieldName] > b.json[fieldName]) {\n\t\treturn 1;\n}\nreturn 0;" + }, + "id": "112c72e6-b5d9-4d6d-87fc-2621fbaa5bf7", + "name": "Item Lists2", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 500] + } + ], + "pinData": { + "Item Lists": [ + { + "json": { + "id": 1, + "char": "a" + } + }, + { + "json": { + "id": 2, + "char": "b" + } + }, + { + "json": { + "id": 3, + "char": "c" + } + }, + { + "json": { + "id": 4, + "char": "d" + } + }, + { + "json": { + "id": 5, + "char": "e" + } + } + ], + "Item Lists1": [ + { + "json": { + "id": 5, + "char": "e" + } + }, + { + "json": { + "id": 4, + "char": "d" + } + }, + { + "json": { + "id": 3, + "char": "c" + } + }, + { + "json": { + "id": 2, + "char": "b" + } + }, + { + "json": { + "id": 1, + "char": "a" + } + } + ], + "Item Lists2": [ + { + "json": { + "id": 1, + "char": "a" + } + }, + { + "json": { + "id": 2, + "char": "b" + } + }, + { + "json": { + "id": 3, + "char": "c" + } + }, + { + "json": { + "id": 4, + "char": "d" + } + }, + { + "json": { + "id": 5, + "char": "e" + } + } + ] + }, + "connections": { + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [ + [ + { + "node": "Item Lists1", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists2", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "6f896427-a3be-44bc-898f-c1a6f58fa1e1", + "id": "105", + "meta": { + "instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0" + }, + "tags": [] +} diff --git a/packages/nodes-base/nodes/ItemLists/test/node/workflow.splitOutItems.json b/packages/nodes-base/nodes/ItemLists/test/node/workflow.splitOutItems.json new file mode 100644 index 0000000000..2e398783ff --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/workflow.splitOutItems.json @@ -0,0 +1,360 @@ +{ + "name": "itemLists test", + "nodes": [ + { + "parameters": {}, + "id": "6c90bf81-0c0e-4c5f-9f0c-297f06d9668a", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [-400, 400] + }, + { + "parameters": { + "jsCode": "return { \ndata:[\n {id: 3, char: 'c'},\n {id: 4, char: 'd'},\n {id: 5, char: 'e'},\n {id: 1, char: 'a'},\n {id: 2, char: 'b'},\n],\ndata2: [\n {text: 'foo'},\n],\ndata3: [\n {text: 'bar'},\n],\n};" + }, + "id": "2e0011d5-c6a0-4a40-ab8c-9d011cde40d5", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [-180, 400] + }, + { + "parameters": { + "fieldToSplitOut": "data", + "options": {} + }, + "id": "e7eac465-8fe6-498c-9942-ebd47df537c1", + "name": "Item Lists", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 160] + }, + { + "parameters": { + "fieldToSplitOut": "data", + "include": "allOtherFields", + "options": {} + }, + "id": "09b7fe15-dbad-4ca6-bf1e-3093139d14e5", + "name": "Item Lists1", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 320] + }, + { + "parameters": { + "fieldToSplitOut": "data", + "include": "selectedOtherFields", + "fieldsToInclude": { + "fields": [ + { + "fieldName": "data3" + } + ] + }, + "options": {} + }, + "id": "7ea63dc7-8141-4233-af47-9894919c7fe4", + "name": "Item Lists2", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 480] + }, + { + "parameters": { + "fieldToSplitOut": "data", + "options": { + "destinationFieldName": "output" + } + }, + "id": "89c3c1b4-9577-480a-931f-3b34450b23cb", + "name": "Item Lists3", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [80, 660] + } + ], + "pinData": { + "Item Lists": [ + { + "json": { + "id": 3, + "char": "c" + } + }, + { + "json": { + "id": 4, + "char": "d" + } + }, + { + "json": { + "id": 5, + "char": "e" + } + }, + { + "json": { + "id": 1, + "char": "a" + } + }, + { + "json": { + "id": 2, + "char": "b" + } + } + ], + "Item Lists1": [ + { + "json": { + "data2": [ + { + "text": "foo" + } + ], + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 3, + "char": "c" + } + } + }, + { + "json": { + "data2": [ + { + "text": "foo" + } + ], + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 4, + "char": "d" + } + } + }, + { + "json": { + "data2": [ + { + "text": "foo" + } + ], + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 5, + "char": "e" + } + } + }, + { + "json": { + "data2": [ + { + "text": "foo" + } + ], + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 1, + "char": "a" + } + } + }, + { + "json": { + "data2": [ + { + "text": "foo" + } + ], + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 2, + "char": "b" + } + } + } + ], + "Item Lists2": [ + { + "json": { + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 3, + "char": "c" + } + } + }, + { + "json": { + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 4, + "char": "d" + } + } + }, + { + "json": { + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 5, + "char": "e" + } + } + }, + { + "json": { + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 1, + "char": "a" + } + } + }, + { + "json": { + "data3": [ + { + "text": "bar" + } + ], + "data": { + "id": 2, + "char": "b" + } + } + } + ], + "Item Lists3": [ + { + "json": { + "output": { + "id": 3, + "char": "c" + } + } + }, + { + "json": { + "output": { + "id": 4, + "char": "d" + } + } + }, + { + "json": { + "output": { + "id": 5, + "char": "e" + } + } + }, + { + "json": { + "output": { + "id": 1, + "char": "a" + } + } + }, + { + "json": { + "output": { + "id": 2, + "char": "b" + } + } + } + ] + }, + "connections": { + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [ + [ + { + "node": "Item Lists", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists1", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists2", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists3", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "9230f580-6f41-47c9-9949-bf258fc3fa47", + "id": "105", + "meta": { + "instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0" + }, + "tags": [] +} diff --git a/packages/nodes-base/nodes/ItemLists/test/node/workflow.summarize.json b/packages/nodes-base/nodes/ItemLists/test/node/workflow.summarize.json new file mode 100644 index 0000000000..75f008cc2c --- /dev/null +++ b/packages/nodes-base/nodes/ItemLists/test/node/workflow.summarize.json @@ -0,0 +1,299 @@ +{ + "name": "itemLists test", + "nodes": [ + { + "parameters": {}, + "id": "6c90bf81-0c0e-4c5f-9f0c-297f06d9668a", + "name": "When clicking \"Execute Workflow\"", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [-400, 420] + }, + { + "parameters": { + "jsCode": "return [\n {\n category: 'red',\n text: 'foo',\n char: 'a',\n value: 1,\n },\n {\n category: 'blue',\n text: 'spam',\n char: 'b',\n value: 2,\n },\n {\n category: 'green',\n text: 'bar',\n char: 'c',\n value: 3,\n },\n {\n category: 'red',\n text: 'foo',\n char: 'a',\n value: 4,\n },\n {\n category: 'red',\n text: 'bar',\n char: 'a',\n value: 5,\n },\n {\n category: 'blue',\n text: 'foo',\n char: 'a',\n value: 6,\n },\n {\n category: 'blue',\n text: 'foo',\n char: 'a',\n value: 7,\n },\n];" + }, + "id": "2e0011d5-c6a0-4a40-ab8c-9d011cde40d5", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [-180, 420] + }, + { + "parameters": { + "operation": "summarize", + "fieldsToSummarize": { + "values": [ + { + "aggregation": "append", + "field": "char" + }, + { + "field": "char" + }, + { + "aggregation": "countUnique", + "field": "char" + }, + { + "aggregation": "concatenate", + "field": "char", + "separateBy": ", " + } + ] + }, + "fieldsToSplitBy": "category, text", + "options": {} + }, + "id": "1dedf668-b766-4283-9efd-90db28404f0b", + "name": "Item Lists", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [40, 220] + }, + { + "parameters": { + "operation": "summarize", + "fieldsToSummarize": { + "values": [ + { + "aggregation": "append", + "field": "char" + }, + { + "field": "char" + }, + { + "aggregation": "countUnique", + "field": "char" + }, + { + "aggregation": "concatenate", + "field": "char", + "separateBy": ", " + } + ] + }, + "fieldsToSplitBy": "category, text", + "options": { + "outputFormat": "singleItem" + } + }, + "id": "8fd0f819-226c-4b29-87c7-b724dd72605c", + "name": "Item Lists1", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [40, 420] + }, + { + "parameters": { + "operation": "summarize", + "fieldsToSummarize": { + "values": [ + { + "aggregation": "average", + "field": "value" + }, + { + "aggregation": "max", + "field": "value" + }, + { + "aggregation": "min", + "field": "value" + }, + { + "aggregation": "max", + "field": "value" + }, + { + "aggregation": "sum", + "field": "value" + }, + { + "aggregation": "append", + "field": "value" + } + ] + }, + "fieldsToSplitBy": "category", + "options": {} + }, + "id": "33e0367d-42d9-4f82-8fc8-8e2019aa3734", + "name": "Item Lists2", + "type": "n8n-nodes-base.itemLists", + "typeVersion": 1, + "position": [40, 620] + } + ], + "pinData": { + "Item Lists": [ + { + "json": { + "category": "red", + "text": "foo", + "appended_char": ["a", "a"], + "count_char": 2, + "unique_count_char": 1, + "concatenated_char": "a, a" + } + }, + { + "json": { + "category": "red", + "text": "bar", + "appended_char": ["a"], + "count_char": 1, + "unique_count_char": 1, + "concatenated_char": "a" + } + }, + { + "json": { + "category": "blue", + "text": "spam", + "appended_char": ["b"], + "count_char": 1, + "unique_count_char": 1, + "concatenated_char": "b" + } + }, + { + "json": { + "category": "blue", + "text": "foo", + "appended_char": ["a", "a"], + "count_char": 2, + "unique_count_char": 1, + "concatenated_char": "a, a" + } + }, + { + "json": { + "category": "green", + "text": "bar", + "appended_char": ["c"], + "count_char": 1, + "unique_count_char": 1, + "concatenated_char": "c" + } + } + ], + "Item Lists1": [ + { + "json": { + "red": { + "foo": { + "appended_char": ["a", "a"], + "count_char": 2, + "unique_count_char": 1, + "concatenated_char": "a, a" + }, + "bar": { + "appended_char": ["a"], + "count_char": 1, + "unique_count_char": 1, + "concatenated_char": "a" + } + }, + "blue": { + "spam": { + "appended_char": ["b"], + "count_char": 1, + "unique_count_char": 1, + "concatenated_char": "b" + }, + "foo": { + "appended_char": ["a", "a"], + "count_char": 2, + "unique_count_char": 1, + "concatenated_char": "a, a" + } + }, + "green": { + "bar": { + "appended_char": ["c"], + "count_char": 1, + "unique_count_char": 1, + "concatenated_char": "c" + } + } + } + } + ], + "Item Lists2": [ + { + "json": { + "category": "red", + "average_value": 3.3333333333333335, + "max_value": 5, + "min_value": 1, + "sum_value": 10, + "appended_value": [1, 4, 5] + } + }, + { + "json": { + "category": "blue", + "average_value": 5, + "max_value": 7, + "min_value": 2, + "sum_value": 15, + "appended_value": [2, 6, 7] + } + }, + { + "json": { + "category": "green", + "average_value": 3, + "max_value": 3, + "min_value": 3, + "sum_value": 3, + "appended_value": [3] + } + } + ] + }, + "connections": { + "When clicking \"Execute Workflow\"": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [ + [ + { + "node": "Item Lists", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists1", + "type": "main", + "index": 0 + }, + { + "node": "Item Lists2", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": {}, + "versionId": "bee0d911-844d-4fe6-bd52-a1716dd74dd8", + "id": "105", + "meta": { + "instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0" + }, + "tags": [] +} diff --git a/packages/nodes-base/test/nodes/ExecuteWorkflow.ts b/packages/nodes-base/test/nodes/ExecuteWorkflow.ts index a9b62a35ab..cf0b5dd01e 100644 --- a/packages/nodes-base/test/nodes/ExecuteWorkflow.ts +++ b/packages/nodes-base/test/nodes/ExecuteWorkflow.ts @@ -1,8 +1,9 @@ import { WorkflowExecute } from 'n8n-core'; import { createDeferredPromise, INodeTypes, IRun, Workflow } from 'n8n-workflow'; import * as Helpers from './Helpers'; +import type { WorkflowTestData } from './types'; -export async function executeWorkflow(testData, nodeTypes: INodeTypes) { +export async function executeWorkflow(testData: WorkflowTestData, nodeTypes: INodeTypes) { const executionMode = 'manual'; const workflowInstance = new Workflow({ id: 'test', diff --git a/packages/nodes-base/test/nodes/Helpers.ts b/packages/nodes-base/test/nodes/Helpers.ts index da548f7002..5b9bf78069 100644 --- a/packages/nodes-base/test/nodes/Helpers.ts +++ b/packages/nodes-base/test/nodes/Helpers.ts @@ -1,8 +1,9 @@ -import { readFileSync } from 'fs'; +import { readFileSync, readdirSync } from 'fs'; import { Credentials, loadClassInIsolation } from 'n8n-core'; import { ICredentialDataDecryptedObject, ICredentialsHelper, + IDataObject, IDeferredPromise, IExecuteWorkflowInfo, IHttpRequestHelper, @@ -23,6 +24,7 @@ import { NodeHelpers, WorkflowHooks, } from 'n8n-workflow'; +import { executeWorkflow } from './ExecuteWorkflow'; import { WorkflowTestData } from './types'; import path from 'path'; @@ -214,3 +216,70 @@ export function getResultNodeData(result: IRun, testData: WorkflowTestData) { export function readJsonFileSync(path: string) { return JSON.parse(readFileSync(path, 'utf-8')); } + +export const equalityTest = async (testData: WorkflowTestData, types: INodeTypes) => { + // execute workflow + const { result } = await executeWorkflow(testData, types); + + // check if result node data matches expected test data + const resultNodeData = getResultNodeData(result, testData); + + resultNodeData.forEach(({ nodeName, resultData }) => { + return expect(resultData).toEqual(testData.output.nodeData[nodeName]); + }); + + expect(result.finished).toEqual(true); +}; + +export const workflowToTests = (workflowFiles: string[]) => { + const testCases: WorkflowTestData[] = []; + for (const filePath of workflowFiles) { + const description = filePath.replace('.json', ''); + const workflowData = readJsonFileSync(filePath); + if (workflowData.pinData === undefined) { + throw new Error('Workflow data does not contain pinData'); + } + const nodeData = Object.keys(workflowData.pinData).reduce( + (acc, key) => { + const data = (workflowData.pinData[key] as IDataObject[]).map((item) => item.json); + acc[key] = [data as IDataObject[]]; + return acc; + }, + {} as { + [key: string]: IDataObject[][]; + }, + ); + + delete workflowData.pinData; + + const input = { workflowData }; + const output = { nodeData }; + + testCases.push({ description, input, output }); + } + return testCases; +}; + +export const testWorkflows = (workflows: string[]) => { + const tests = workflowToTests(workflows); + + const nodeTypes = setup(tests); + + for (const testData of tests) { + test(testData.description, async () => equalityTest(testData, nodeTypes)); + } +}; + +export const getWorkflowFilenames = (dirname: string) => { + const workflows: string[] = []; + + const filenames = readdirSync(dirname); + const testFolder = dirname.split(`${path.sep}nodes-base${path.sep}`)[1]; + filenames.forEach((file) => { + if (file.includes('.json')) { + workflows.push(path.join(testFolder, file)); + } + }); + + return workflows; +};