first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,8 @@
export const credentials = {
microsoftExcelOAuth2Api: {
scope: 'openid',
oauthTokenData: {
access_token: 'token',
},
},
};
@@ -0,0 +1,134 @@
import { mock } from 'jest-mock-extended';
import type { ILoadOptionsFunctions } from 'n8n-workflow';
import { getWorksheetColumnRow } from '../../../v2/methods/loadOptions';
import { microsoftApiRequest } from '../../../v2/transport';
// Mock the transport module
jest.mock('../../../v2/transport', () => ({
microsoftApiRequest: jest.fn(),
}));
describe('Microsoft Excel V2 - loadOptions', () => {
let mockContext: ILoadOptionsFunctions;
const mockMicrosoftApiRequest = microsoftApiRequest as jest.MockedFunction<
typeof microsoftApiRequest
>;
const mockGetNodeParameter = jest.fn();
beforeEach(() => {
mockContext = mock<ILoadOptionsFunctions>({
getNodeParameter: mockGetNodeParameter,
});
mockMicrosoftApiRequest.mockReset();
mockGetNodeParameter.mockReset();
});
describe('getWorksheetColumnRow', () => {
it('should get columns from usedRange when range is empty', async () => {
// Arrange
const workbookId = 'test-workbook-id';
const worksheetId = 'test-worksheet-id';
const range = '';
mockGetNodeParameter
.mockReturnValueOnce(workbookId)
.mockReturnValueOnce(worksheetId)
.mockReturnValueOnce(range);
const mockResponse = {
values: [['Column A', 'Column B', 'Column C']],
};
mockMicrosoftApiRequest.mockResolvedValue(mockResponse);
const result = await getWorksheetColumnRow.call(mockContext);
expect(mockMicrosoftApiRequest).toHaveBeenCalledWith(
'GET',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/usedRange`,
undefined,
{ select: 'values' },
);
expect(result).toEqual([
{ name: 'Column A', value: 'Column A' },
{ name: 'Column B', value: 'Column B' },
{ name: 'Column C', value: 'Column C' },
]);
});
it('should get columns from specific range when range is provided', async () => {
const workbookId = 'test-workbook-id';
const worksheetId = 'test-worksheet-id';
const range = 'A1:C1';
mockGetNodeParameter
.mockReturnValueOnce(workbookId)
.mockReturnValueOnce(worksheetId)
.mockReturnValueOnce(range);
const mockResponse = {
values: [['Header 1', 'Header 2', 'Header 3']],
};
mockMicrosoftApiRequest.mockResolvedValue(mockResponse);
const result = await getWorksheetColumnRow.call(mockContext);
expect(mockMicrosoftApiRequest).toHaveBeenCalledWith(
'PATCH',
`/drive/items/${workbookId}/workbook/worksheets/${worksheetId}/range(address='${range}')`,
{ select: 'values' },
);
expect(result).toEqual([
{ name: 'Header 1', value: 'Header 1' },
{ name: 'Header 2', value: 'Header 2' },
{ name: 'Header 3', value: 'Header 3' },
]);
});
it('should handle empty columns array', async () => {
const workbookId = 'test-workbook-id';
const worksheetId = 'test-worksheet-id';
const range = '';
mockGetNodeParameter
.mockReturnValueOnce(workbookId)
.mockReturnValueOnce(worksheetId)
.mockReturnValueOnce(range);
const mockResponse = {
values: [[]],
};
mockMicrosoftApiRequest.mockResolvedValue(mockResponse);
const result = await getWorksheetColumnRow.call(mockContext);
expect(result).toEqual([]);
});
it('should handle single column', async () => {
const workbookId = 'test-workbook-id';
const worksheetId = 'test-worksheet-id';
const range = 'A1:A1';
mockGetNodeParameter
.mockReturnValueOnce(workbookId)
.mockReturnValueOnce(worksheetId)
.mockReturnValueOnce(range);
const mockResponse = {
values: [['Single Column']],
};
mockMicrosoftApiRequest.mockResolvedValue(mockResponse);
const result = await getWorksheetColumnRow.call(mockContext);
expect(result).toEqual([{ name: 'Single Column', value: 'Single Column' }]);
});
});
});
@@ -0,0 +1,30 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => addTable', () => {
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/tables/add',
{ address: 'A1:D4', hasHeaders: true },
)
.reply(200, {
style: 'TableStyleMedium2',
name: 'Table3',
showFilterButton: true,
id: '{317CA469-7D1C-4A5D-9B0B-424444BF0336}',
highlightLastColumn: false,
highlightFirstColumn: false,
legacyId: '3',
showBandedColumns: false,
showBandedRows: true,
showHeaders: true,
showTotals: false,
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['addTable.workflow.json'],
});
});
@@ -0,0 +1,78 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [380, 140]
},
{
"parameters": {
"resource": "table",
"operation": "addTable",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "list",
"cachedResultName": "Sheet4"
},
"selectRange": "manual",
"range": "A1:D4"
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"style": "TableStyleMedium2",
"name": "Table3",
"showFilterButton": true,
"id": "{317CA469-7D1C-4A5D-9B0B-424444BF0336}",
"highlightLastColumn": false,
"highlightFirstColumn": false,
"legacyId": "3",
"showBandedColumns": false,
"showBandedRows": true,
"showHeaders": true,
"showTotals": false
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,31 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => append', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/tables/%7B317CA469-7D1C-4A5D-9B0B-424444BF0336%7D/columns',
)
.reply(200, {
value: [{ name: 'id' }, { name: 'name' }, { name: 'age' }, { name: 'data' }],
})
.post(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/tables/%7B317CA469-7D1C-4A5D-9B0B-424444BF0336%7D/rows/add',
{ values: [['3', 'Donald', '99', 'data 5']] },
)
.reply(200, {
index: 3,
values: [[3, 'Donald', 99, 'data 5']],
})
.post('/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/createSession')
.reply(200, { id: 12345 })
.post('/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/closeSession')
.reply(200);
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['append.workflow.json'],
});
});
@@ -0,0 +1,104 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [380, 140]
},
{
"parameters": {
"resource": "table",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
},
"worksheet": {
"__rl": true,
"value": "{A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "list",
"cachedResultName": "Sheet4",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1&activeCell=Sheet4!A1"
},
"table": {
"__rl": true,
"value": "{317CA469-7D1C-4A5D-9B0B-424444BF0336}",
"mode": "list",
"cachedResultName": "Table3",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1&activeCell=Sheet4!A1:D4"
},
"fieldsUi": {
"values": [
{
"column": "id",
"fieldValue": "3"
},
{
"column": "name",
"fieldValue": "Donald"
},
{
"column": "age",
"fieldValue": "99"
},
{
"column": "data",
"fieldValue": "data 5"
}
]
},
"options": {}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"id": 3,
"name": "Donald",
"age": 99,
"data": "data 5"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"versionId": "b9eda2d8-e1a5-4a54-aaa9-5e81adaae909",
"id": "135",
"meta": {
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
},
"tags": []
}
@@ -0,0 +1,26 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => convertToRange', () => {
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/tables/%7B6321EE4A-AC21-48AD-87D9-B527637D94B3%7D/convertToRange',
)
.reply(200, {
address: 'Sheet4!A1:D5',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Sam', 34, 'data 4'],
[3, 'Donald', 99, 'data 5'],
],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['convertToRange.workflow.json'],
});
});
@@ -0,0 +1,79 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [580, 140]
},
{
"parameters": {
"resource": "table",
"operation": "convertToRange",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "list",
"cachedResultName": "Sheet4"
},
"table": {
"__rl": true,
"value": "{6321EE4A-AC21-48AD-87D9-B527637D94B3}",
"mode": "list",
"cachedResultName": "Table3"
}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"address": "Sheet4!A1:D5",
"values": [
["id", "name", "age", "data"],
[1, "Sam", 33, "data 1"],
[2, "Jon", 44, "data 2"],
[3, "Sam", 34, "data 4"],
[3, "Donald", 99, "data 5"]
]
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,17 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => deleteTable', () => {
nock('https://graph.microsoft.com/v1.0/me')
.delete(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/tables/%7B92FBE3F5-3180-47EE-8549-40892C38DA7F%7D',
)
.reply(200);
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['deleteTable.workflow.json'],
});
});
@@ -0,0 +1,72 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [580, 140]
},
{
"parameters": {
"resource": "table",
"operation": "deleteTable",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "list",
"cachedResultName": "Sheet4"
},
"table": {
"__rl": true,
"value": "{92FBE3F5-3180-47EE-8549-40892C38DA7F}",
"mode": "list",
"cachedResultName": "Table3"
}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,28 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => getColumns', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/columns?%24top=100&%24skip=0',
)
.reply(200, {
value: [
{ name: 'country' },
{ name: 'browser' },
{ name: 'session_duration' },
{ name: 'visits' },
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/columns?%24top=100&%24skip=100',
)
.reply(200, { value: [] });
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['getColumns.workflow.json'],
});
});
@@ -0,0 +1,88 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [580, 140]
},
{
"parameters": {
"resource": "table",
"operation": "getColumns",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{00000000-0001-0000-0000-000000000000}",
"mode": "list",
"cachedResultName": "Sheet1"
},
"table": {
"__rl": true,
"value": "{613E8967-D581-44ED-81D3-82A01AA6A05C}",
"mode": "list",
"cachedResultName": "Table1"
},
"returnAll": true
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"name": "country"
}
},
{
"json": {
"name": "browser"
}
},
{
"json": {
"name": "session_duration"
}
},
{
"json": {
"name": "visits"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,37 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => getRows', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/rows?%24top=2',
)
.reply(200, {
value: [
{ index: 0, values: [['uk', 'firefox', 1, 1]] },
{ index: 1, values: [['us', 'chrome', 1, 12]] },
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/columns?%24select=name&%24top=100&%24skip=0',
)
.reply(200, {
value: [
{ name: 'country' },
{ name: 'browser' },
{ name: 'session_duration' },
{ name: 'visits' },
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/columns?%24select=name&%24top=100&%24skip=100',
)
.reply(200, { value: [] });
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['getRows.workflow.json'],
});
});
@@ -0,0 +1,85 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [580, 140]
},
{
"parameters": {
"resource": "table",
"operation": "getRows",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{00000000-0001-0000-0000-000000000000}",
"mode": "list",
"cachedResultName": "Sheet1"
},
"table": {
"__rl": true,
"value": "{613E8967-D581-44ED-81D3-82A01AA6A05C}",
"mode": "list",
"cachedResultName": "Table1"
},
"limit": 2,
"filters": {}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"country": "uk",
"browser": "firefox",
"session_duration": 1,
"visits": 1
}
},
{
"json": {
"country": "us",
"browser": "chrome",
"session_duration": 1,
"visits": 12
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,45 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, table => lookup', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/rows?%24top=100&%24skip=0',
)
.reply(200, {
value: [
{ index: 0, values: [['uk', 'firefox', 1, 1]] },
{ index: 1, values: [['us', 'chrome', 1, 12]] },
{ index: 2, values: [['test', 'test', 55, 123]] },
{ index: 3, values: [['ua', 'chrome', 1, 3]] },
{ index: 4, values: [['ua', 'firefox', 1, 4]] },
{ index: 5, values: [['uk', 'chrome', 1, 55]] },
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/rows?%24top=100&%24skip=100',
)
.reply(200, { value: [] })
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/columns?%24select=name&%24top=100&%24skip=0',
)
.reply(200, {
value: [
{ name: 'country' },
{ name: 'browser' },
{ name: 'session_duration' },
{ name: 'visits' },
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B00000000-0001-0000-0000-000000000000%7D/tables/%7B613E8967-D581-44ED-81D3-82A01AA6A05C%7D/columns?%24select=name&%24top=100&%24skip=100',
)
.reply(200, { value: [] });
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['lookup.workflow.json'],
});
});
@@ -0,0 +1,88 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [580, 140]
},
{
"parameters": {
"resource": "table",
"operation": "lookup",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{00000000-0001-0000-0000-000000000000}",
"mode": "list",
"cachedResultName": "Sheet1"
},
"table": {
"__rl": true,
"value": "{613E8967-D581-44ED-81D3-82A01AA6A05C}",
"mode": "list",
"cachedResultName": "Table1"
},
"lookupColumn": "country",
"lookupValue": "uk",
"options": {
"returnAllMatches": true
}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"country": "uk",
"browser": "firefox",
"session_duration": 1,
"visits": 1
}
},
{
"json": {
"country": "uk",
"browser": "chrome",
"session_duration": 1,
"visits": 55
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,29 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, workbook => addWorksheet', () => {
nock('https://graph.microsoft.com/v1.0/me')
.post('/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/createSession', {
persistChanges: true,
})
.reply(200, { id: 12345 })
.post('/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/add', {
name: 'Sheet42',
})
.matchHeader('workbook-session-id', '12345')
.reply(200, {
id: '{266ADAB7-25B6-4F28-A2D1-FD5BFBD7A4F0}',
name: 'Sheet42',
position: 8,
visibility: 'Visible',
})
.post('/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/closeSession')
.reply(200);
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['addWorksheet.workflow.json'],
});
});
@@ -0,0 +1,65 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [380, 140]
},
{
"parameters": {
"operation": "addWorksheet",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"additionalFields": {
"name": "Sheet42"
}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"id": "{266ADAB7-25B6-4F28-A2D1-FD5BFBD7A4F0}",
"name": "Sheet42",
"position": 8,
"visibility": "Visible"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,15 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, workbook => deleteWorkbook', () => {
nock('https://graph.microsoft.com/v1.0/me')
.delete('/drive/items/01FUWX3BXJLISGF2CFWBGYPHXFCXPXOJUK')
.reply(200);
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['deleteWorkbook.workflow.json'],
});
});
@@ -0,0 +1,59 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [380, 140]
},
{
"parameters": {
"operation": "deleteWorkbook",
"workbook": {
"__rl": true,
"value": "01FUWX3BXJLISGF2CFWBGYPHXFCXPXOJUK",
"mode": "list",
"cachedResultName": "Book"
}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,26 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, workbook => getAll', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get("/drive/root/search(q='.xlsx')?%24select=name&%24top=2")
.reply(200, {
value: [
{
'@odata.type': '#microsoft.graph.driveItem',
name: 'ПРРО копія.xlsx',
},
{
'@odata.type': '#microsoft.graph.driveItem',
name: 'Book 3.xlsx',
},
],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['getAll.workflow.json'],
});
});
@@ -0,0 +1,63 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [380, 140]
},
{
"parameters": {
"limit": 2,
"filters": {
"fields": "name"
}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"@odata.type": "#microsoft.graph.driveItem",
"name": "ПРРО копія.xlsx"
}
},
{
"json": {
"@odata.type": "#microsoft.graph.driveItem",
"name": "Book 3.xlsx"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,45 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => append', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/usedRange',
)
.reply(200, {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.patch(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/range(address='A7:D7')",
)
.reply(200, { values: [[4, 'Sam', 34, 'data 4']] })
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B426949D7-797F-43A9-A8A4-8FE283495A82%7D/usedRange',
)
.reply(200, {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.patch(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B426949D7-797F-43A9-A8A4-8FE283495A82%7D/range(address='A7:D7')",
)
.reply(200, { values: [[4, 'Don', 37, 'data 44']] });
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['append.workflow.json'],
});
});
@@ -0,0 +1,171 @@
{
"name": "microsoft excel 365 - tests",
"nodes": [
{
"parameters": {},
"id": "2e1ec8f6-a2e2-4aa9-909c-d0a279584131",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [800, 260]
},
{
"parameters": {
"resource": "worksheet",
"operation": "append",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "={A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "id"
},
"fieldsUi": {
"values": [
{
"column": "id",
"fieldValue": "4"
},
{
"column": "name",
"fieldValue": "Sam"
},
{
"column": "age",
"fieldValue": "34"
},
{
"column": "data",
"fieldValue": "data 4"
}
]
},
"options": {}
},
"id": "86f2a240-3acf-45c2-b97f-63dd655d296b",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1280, 260],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"resource": "worksheet",
"operation": "append",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{426949D7-797F-43A9-A8A4-8FE283495A82}",
"mode": "list",
"cachedResultName": "Sheet5"
},
"dataMode": "autoMap",
"options": {}
},
"id": "531949d8-1ffa-4e1c-ae3e-032360b74f06",
"name": "Microsoft Excel 3651",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1280, 500],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"data": {
"id": 4,
"name": "Don",
"age": 37,
"data": "data 44"
}
},
"id": "2919f9b9-e3ac-42cd-a792-774738fd2195",
"name": "Code",
"type": "n8n-nodes-testing.testData",
"typeVersion": 1,
"position": [1080, 500]
}
],
"pinData": {
"Microsoft Excel 3651": [
{
"json": {
"id": 4,
"name": "Don",
"age": 37,
"data": "data 44"
}
}
],
"Microsoft Excel 365": [
{
"json": {
"id": 4,
"name": "Sam",
"age": 34,
"data": "data 4"
}
}
],
"Code": [
{
"json": {
"id": 4,
"name": "Don",
"age": 37,
"data": "data 44"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
},
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Microsoft Excel 3651",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,20 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => clear', () => {
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BF7AF92FE-D42D-452F-8E4A-901B1D1EBF3F%7D/range/clear',
{ applyTo: 'All' },
)
.reply(200, {
values: [{ json: { success: true } }],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['clear.workflow.json'],
});
});
@@ -0,0 +1,66 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "f0857ec9-0709-4657-a2f4-059837c94060",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [540, 220]
},
{
"parameters": {
"resource": "worksheet",
"operation": "clear",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{F7AF92FE-D42D-452F-8E4A-901B1D1EBF3F}",
"mode": "list",
"cachedResultName": "Sheet2"
}
},
"id": "426ed055-0c9b-4ae2-a9fe-a6cce875d5ee",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1020, 220],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,19 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => deleteWorksheet', () => {
nock('https://graph.microsoft.com/v1.0/me')
.delete(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B88D9C37A-4180-4B23-8996-BF11F32EB63C%7D',
)
.reply(200, {
values: [{ json: { success: true } }],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['deleteWorksheet.workflow.json'],
});
});
@@ -0,0 +1,66 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "f0857ec9-0709-4657-a2f4-059837c94060",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [540, 220]
},
{
"parameters": {
"resource": "worksheet",
"operation": "deleteWorksheet",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{88D9C37A-4180-4B23-8996-BF11F32EB63C}",
"mode": "list",
"cachedResultName": "188"
}
},
"id": "426ed055-0c9b-4ae2-a9fe-a6cce875d5ee",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1020, 220],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,32 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => getAll', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets?%24select=name&%24top=3',
)
.reply(200, {
value: [
{
id: '{00000000-0001-0000-0000-000000000000}',
name: 'Sheet1',
},
{
id: '{F7AF92FE-D42D-452F-8E4A-901B1D1EBF3F}',
name: 'Sheet2',
},
{
id: '{BF7BD843-4912-4B81-A0AC-4FBBC2783E20}',
name: 'foo2',
},
],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['getAll.workflow.json'],
});
});
@@ -0,0 +1,76 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "f0857ec9-0709-4657-a2f4-059837c94060",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [540, 220]
},
{
"parameters": {
"resource": "worksheet",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"limit": 3,
"filters": {
"fields": "name"
}
},
"id": "426ed055-0c9b-4ae2-a9fe-a6cce875d5ee",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1020, 220],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"id": "{00000000-0001-0000-0000-000000000000}",
"name": "Sheet1"
}
},
{
"json": {
"id": "{F7AF92FE-D42D-452F-8E4A-901B1D1EBF3F}",
"name": "Sheet2"
}
},
{
"json": {
"id": "{BF7BD843-4912-4B81-A0AC-4FBBC2783E20}",
"name": "foo2"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,34 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => readRows', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/usedRange',
)
.reply(200, {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.get(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/range(address='A1:D3')",
)
.reply(200, {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['readRows.workflow.json'],
});
});
@@ -0,0 +1,137 @@
{
"name": "microsoft excel 365 - read rows",
"nodes": [
{
"parameters": {},
"id": "2e1ec8f6-a2e2-4aa9-909c-d0a279584131",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [820, 380]
},
{
"parameters": {
"resource": "worksheet",
"operation": "readRows",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "{A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "list",
"cachedResultName": "Sheet4"
},
"options": {}
},
"id": "86f2a240-3acf-45c2-b97f-63dd655d296b",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1100, 260],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"resource": "worksheet",
"operation": "readRows",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
},
"worksheet": {
"__rl": true,
"value": "{A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "list",
"cachedResultName": "Sheet4",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1&activeCell=Sheet4!A1"
},
"useRange": true,
"range": "A1:D3",
"dataStartRow": 2,
"options": {}
},
"id": "8ce6ab42-8f38-452b-90da-598d8a958c2b",
"name": "Microsoft Excel 3651",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1100, 520],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"id": 1,
"name": "Sam",
"age": 33,
"data": "data 1"
}
},
{
"json": {
"id": 2,
"name": "Jon",
"age": 44,
"data": "data 2"
}
},
{
"json": {
"id": 3,
"name": "Ron",
"age": 55,
"data": "data 3"
}
}
],
"Microsoft Excel 3651": [
{
"json": {
"id": 2,
"name": "Jon",
"age": 44,
"data": "data 2"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
},
{
"node": "Microsoft Excel 3651",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"tags": []
}
@@ -0,0 +1,59 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => update', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/usedRange',
)
.reply(200, {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.patch(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/range(address='A1:D6')",
)
.reply(200, {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Sam', 34, 'data 4'],
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B426949D7-797F-43A9-A8A4-8FE283495A82%7D/usedRange',
)
.reply(200, {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.patch(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B426949D7-797F-43A9-A8A4-8FE283495A82%7D/range(address='A1:D6')",
)
.reply(200, {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Don', 37, 'data 44'],
],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['update.workflow.json'],
});
});
@@ -0,0 +1,159 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "875e8784-eb59-40d8-ba45-129a5e29881c",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [380, 140]
},
{
"parameters": {
"resource": "worksheet",
"operation": "update",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "={A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "id"
},
"columnToMatchOn": "id",
"valueToMatchOn": "3",
"fieldsUi": {
"values": [
{
"column": "name",
"fieldValue": "Sam"
},
{
"column": "age",
"fieldValue": "34"
},
{
"column": "data",
"fieldValue": "data 4"
}
]
},
"options": {}
},
"id": "0e0ac1d2-242c-486a-9287-c70307645acc",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 140],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"resource": "worksheet",
"operation": "update",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія"
},
"worksheet": {
"__rl": true,
"value": "={426949D7-797F-43A9-A8A4-8FE283495A82}",
"mode": "id"
},
"dataMode": "autoMap",
"columnToMatchOn": "id",
"options": {}
},
"id": "d3209da3-cfaf-40a6-a318-c66c2931a28a",
"name": "Microsoft Excel 3651",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [860, 380],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"data": {
"id": 3,
"name": "Don",
"age": 37,
"data": "data 44"
}
},
"id": "eb908630-7324-46a5-890d-b5cfccf17cb2",
"name": "Code",
"type": "n8n-nodes-testing.testData",
"typeVersion": 1,
"position": [660, 380]
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"id": 3,
"name": "Sam",
"age": 34,
"data": "data 4"
}
}
],
"Microsoft Excel 3651": [
{
"json": {
"id": 3,
"name": "Don",
"age": 37,
"data": "data 44"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
},
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Microsoft Excel 3651",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {}
}
@@ -0,0 +1,61 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import { credentials } from '../../../credentials';
describe('Test MicrosoftExcelV2, worksheet => upsert', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/usedRange',
)
.reply(200, {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.patch(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7BA0883CFE-D27E-4ECC-B94B-981830AAD55B%7D/range(address='A1:D7')",
)
.reply(200, {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
[4, 'Sam', 34, 'data 4'],
],
})
.get(
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B426949D7-797F-43A9-A8A4-8FE283495A82%7D/usedRange',
)
.reply(200, {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
})
.patch(
"/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/%7B426949D7-797F-43A9-A8A4-8FE283495A82%7D/range(address='A1:D7')",
)
.reply(200, {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
[4, 'Don', 37, 'data 44'],
],
});
new NodeTestHarness().setupTests({
credentials,
workflowFiles: ['upsert.workflow.json'],
});
});
@@ -0,0 +1,167 @@
{
"name": "My workflow 5",
"nodes": [
{
"parameters": {},
"id": "f0857ec9-0709-4657-a2f4-059837c94060",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [540, 220]
},
{
"parameters": {
"resource": "worksheet",
"operation": "upsert",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
},
"worksheet": {
"__rl": true,
"value": "={A0883CFE-D27E-4ECC-B94B-981830AAD55B}",
"mode": "id"
},
"columnToMatchOn": "id",
"valueToMatchOn": "4",
"fieldsUi": {
"values": [
{
"column": "name",
"fieldValue": "Sam"
},
{
"column": "age",
"fieldValue": "34"
},
{
"column": "data",
"fieldValue": "data 4"
}
]
},
"options": {}
},
"id": "426ed055-0c9b-4ae2-a9fe-a6cce875d5ee",
"name": "Microsoft Excel 365",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1020, 220],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"resource": "worksheet",
"operation": "upsert",
"workbook": {
"__rl": true,
"value": "01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I",
"mode": "list",
"cachedResultName": "ПРРО копія",
"cachedResultUrl": "https://5w1hb7-my.sharepoint.com/personal/michaeldevsandbox_5w1hb7_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BECC4041C-3AB6-4CF7-B079-0926470A1388%7D&file=%D0%9F%D0%A0%D0%A0%D0%9E%20%D0%BA%D0%BE%D0%BF%D1%96%D1%8F.xlsx&action=default&mobileredirect=true&DefaultItemOpen=1"
},
"worksheet": {
"__rl": true,
"value": "={426949D7-797F-43A9-A8A4-8FE283495A82}",
"mode": "id"
},
"dataMode": "autoMap",
"columnToMatchOn": "id",
"options": {}
},
"id": "0b10bfae-4e15-48c5-a2e6-7bec1c2687ec",
"name": "Microsoft Excel 3651",
"type": "n8n-nodes-base.microsoftExcel",
"typeVersion": 2,
"position": [1020, 460],
"credentials": {
"microsoftExcelOAuth2Api": {
"id": "70",
"name": "Microsoft Excel account"
}
}
},
{
"parameters": {
"data": {
"id": 4,
"name": "Don",
"age": 37,
"data": "data 44"
}
},
"id": "93453ccb-5ac3-425b-8ac4-d20f0dfe9bab",
"name": "Code",
"type": "n8n-nodes-testing.testData",
"typeVersion": 1,
"position": [820, 460]
}
],
"pinData": {
"Microsoft Excel 365": [
{
"json": {
"id": 4,
"name": "Sam",
"age": 34,
"data": "data 4"
}
}
],
"Microsoft Excel 3651": [
{
"json": {
"id": 4,
"name": "Don",
"age": 37,
"data": "data 44"
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Excel 365",
"type": "main",
"index": 0
},
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Microsoft Excel 3651",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"versionId": "f24273bf-ef07-49da-960b-a68b63961d4a",
"id": "135",
"meta": {
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
},
"tags": []
}
@@ -0,0 +1,741 @@
import { mock } from 'jest-mock-extended';
import get from 'lodash/get';
import { constructExecutionMetaData } from 'n8n-core';
import type { IDataObject, IExecuteFunctions, IGetNodeParameterOptions, INode } from 'n8n-workflow';
import {
checkRange,
findAppendRange,
nextExcelColumn,
parseAddress,
prepareOutput,
updateByAutoMaping,
updateByDefinedValues,
} from '../../../v2/helpers/utils';
const node: INode = {
id: '1',
name: 'Microsoft Excel 365',
typeVersion: 2,
type: 'n8n-nodes-base.microsoftExcel',
position: [60, 760],
parameters: {},
};
const fakeExecute = (nodeParameters: IDataObject[]) => {
const fakeExecuteFunction = {
getInputData() {
return [{ json: {} }];
},
getNodeParameter(
parameterName: string,
itemIndex: number,
fallbackValue?: IDataObject,
options?: IGetNodeParameterOptions,
) {
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
return get(nodeParameters[itemIndex], parameter, fallbackValue);
},
} as unknown as IExecuteFunctions;
return fakeExecuteFunction;
};
const responseData = {
address: 'Sheet4!A1:D4',
addressLocal: 'Sheet4!A1:D4',
columnCount: 4,
cellCount: 16,
columnHidden: false,
rowHidden: false,
numberFormat: [
['General', 'General', 'General', 'General'],
['General', 'General', 'General', 'General'],
['General', 'General', 'General', 'General'],
['General', 'General', 'General', 'General'],
],
columnIndex: 0,
text: [
['id', 'name', 'age', 'data'],
['1', 'Sam', '33', 'data 1'],
['2', 'Jon', '44', 'data 2'],
['3', 'Ron', '55', 'data 3'],
],
formulas: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
formulasLocal: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
formulasR1C1: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
hidden: false,
rowCount: 4,
rowIndex: 0,
valueTypes: [
['String', 'String', 'String', 'String'],
['Double', 'String', 'Double', 'String'],
['Double', 'String', 'Double', 'String'],
['Double', 'String', 'Double', 'String'],
],
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
};
describe('Test MicrosoftExcelV2, prepareOutput', () => {
const thisArg = mock<IExecuteFunctions>({
helpers: mock({ constructExecutionMetaData }),
getInputData() {
return [{ json: {} }];
},
});
it('should return empty array', () => {
const output = prepareOutput.call(thisArg, node, { values: [] }, { rawData: false });
expect(output).toBeDefined();
expect(output).toEqual([]);
});
it('should return raw response', () => {
const output = prepareOutput.call(thisArg, node, responseData, { rawData: true });
expect(output).toBeDefined();
expect(output[0].json.data).toEqual(responseData);
});
it('should return raw response in custom property', () => {
const customKey = 'customKey';
const output = prepareOutput.call(thisArg, node, responseData, {
rawData: true,
dataProperty: customKey,
});
expect(output).toBeDefined();
expect(output[0].json.customKey).toEqual(responseData);
});
it('should return formated response', () => {
const output = prepareOutput.call(thisArg, node, responseData, { rawData: false });
expect(output).toBeDefined();
expect(output.length).toEqual(3);
expect(output[0].json).toEqual({
id: 1,
name: 'Sam',
age: 33,
data: 'data 1',
});
});
it('should return response with selected first data row', () => {
const output = prepareOutput.call(thisArg, node, responseData, {
rawData: false,
firstDataRow: 3,
});
expect(output).toBeDefined();
expect(output.length).toEqual(1);
expect(output[0].json).toEqual({
id: 3,
name: 'Ron',
age: 55,
data: 'data 3',
});
});
it('should return response with selected first data row', () => {
const [firstRow, ...rest] = responseData.values;
const response = { values: [...rest, firstRow] };
const output = prepareOutput.call(thisArg, node, response, {
rawData: false,
keyRow: 3,
firstDataRow: 0,
});
expect(output).toBeDefined();
expect(output.length).toEqual(3);
expect(output[0].json).toEqual({
id: 1,
name: 'Sam',
age: 33,
data: 'data 1',
});
});
});
describe('Test MicrosoftExcelV2, updateByDefinedValues', () => {
it('should update single row', () => {
const nodeParameters = [
{
columnToMatchOn: 'id',
valueToMatchOn: 2,
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Donald',
},
],
},
},
];
const sheetData = responseData.values;
const updateSummary = updateByDefinedValues.call(
fakeExecute(nodeParameters),
nodeParameters.length,
sheetData,
false,
);
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.updatedRows).toContain(2); //updated row
expect(updateSummary.updatedRows).toHaveLength(2);
expect(updateSummary.updatedData[2][1]).toEqual('Donald'); // updated value
});
it('should update multiple rows', () => {
const nodeParameters = [
{
columnToMatchOn: 'id',
valueToMatchOn: 2,
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Donald',
},
],
},
},
{
columnToMatchOn: 'id',
valueToMatchOn: 3,
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Eduard',
},
],
},
},
{
columnToMatchOn: 'id',
valueToMatchOn: 4,
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Ismael',
},
],
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
[4, 'Ron', 55, 'data 3'],
];
const updateSummary = updateByDefinedValues.call(
fakeExecute(nodeParameters),
nodeParameters.length,
sheetData,
false,
);
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.updatedRows).toContain(2); //updated row
expect(updateSummary.updatedRows).toContain(3); //updated row
expect(updateSummary.updatedRows).toContain(4); //updated row
expect(updateSummary.updatedRows).toHaveLength(4);
expect(updateSummary.updatedData[2][1]).toEqual('Donald'); // updated value
expect(updateSummary.updatedData[3][1]).toEqual('Eduard'); // updated value
expect(updateSummary.updatedData[4][1]).toEqual('Ismael'); // updated value
});
it('should update all occurances', () => {
const nodeParameters = [
{
columnToMatchOn: 'data',
valueToMatchOn: 'data 3',
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Donald',
},
],
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 55, 'data 3'],
[2, 'Jon', 77, 'data 3'],
[3, 'Ron', 44, 'data 3'],
[4, 'Ron', 33, 'data 3'],
];
const updateSummary = updateByDefinedValues.call(
fakeExecute(nodeParameters),
nodeParameters.length,
sheetData,
true,
);
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.updatedRows).toHaveLength(5);
for (let i = 1; i < updateSummary.updatedRows.length; i++) {
expect(updateSummary.updatedData[i][1]).toEqual('Donald'); // updated value
}
});
it('should append rows', () => {
const nodeParameters = [
{
columnToMatchOn: 'id',
valueToMatchOn: 4,
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Donald',
},
{
column: 'age',
fieldValue: 45,
},
{
column: 'data',
fieldValue: 'data 4',
},
],
},
},
{
columnToMatchOn: 'id',
valueToMatchOn: 5,
fieldsUi: {
values: [
{
column: 'name',
fieldValue: 'Victor',
},
{
column: 'age',
fieldValue: 67,
},
{
column: 'data',
fieldValue: 'data 5',
},
],
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 55, 'data 3'],
[2, 'Jon', 77, 'data 3'],
[3, 'Ron', 44, 'data 3'],
];
const updateSummary = updateByDefinedValues.call(
fakeExecute(nodeParameters),
nodeParameters.length,
sheetData,
true,
);
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0);
expect(updateSummary.updatedRows.length).toEqual(1);
expect(updateSummary.appendData[0]).toEqual({ id: 4, name: 'Donald', age: 45, data: 'data 4' });
expect(updateSummary.appendData[1]).toEqual({ id: 5, name: 'Victor', age: 67, data: 'data 5' });
});
});
describe('Test MicrosoftExcelV2, updateByAutoMaping', () => {
it('should update single row', () => {
const items = [
{
json: {
id: 2,
name: 'Donald',
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
];
const updateSummary = updateByAutoMaping(items, sheetData, 'id');
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toHaveLength(2);
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.updatedRows).toContain(2); //updated row
expect(updateSummary.updatedData[2][1]).toEqual('Donald'); // updated value
});
it('should append single row', () => {
const items = [
{
json: {
id: 5,
name: 'Donald',
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
];
const updateSummary = updateByAutoMaping(items, sheetData, 'id');
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toHaveLength(1);
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.appendData[0]).toEqual({ id: 5, name: 'Donald' });
});
it('should append skip row with match column undefined', () => {
const items = [
{
json: {
id: 5,
name: 'Donald',
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
];
const updateSummary = updateByAutoMaping(items, sheetData, 'idd');
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toHaveLength(1);
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.appendData.length).toEqual(0);
});
it('should update multiple rows', () => {
const items = [
{
json: {
id: 2,
name: 'Donald',
},
},
{
json: {
id: 3,
name: 'Eduard',
},
},
{
json: {
id: 4,
name: 'Ismael',
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
[4, 'Ron', 55, 'data 3'],
];
const updateSummary = updateByAutoMaping(items, sheetData, 'id');
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.updatedRows).toContain(2); //updated row
expect(updateSummary.updatedRows).toContain(3); //updated row
expect(updateSummary.updatedRows).toContain(4); //updated row
expect(updateSummary.updatedRows).toHaveLength(4);
expect(updateSummary.updatedData[2][1]).toEqual('Donald'); // updated value
expect(updateSummary.updatedData[3][1]).toEqual('Eduard'); // updated value
expect(updateSummary.updatedData[4][1]).toEqual('Ismael'); // updated value
});
it('should update all occurrences', () => {
const items = [
{
json: {
data: 'data 3',
name: 'Donald',
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 55, 'data 3'],
[2, 'Jon', 77, 'data 3'],
[3, 'Ron', 44, 'data 3'],
[4, 'Ron', 33, 'data 3'],
];
const updateSummary = updateByAutoMaping(items, sheetData, 'data', true);
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0); //header row
expect(updateSummary.updatedRows).toHaveLength(5);
for (let i = 1; i < updateSummary.updatedRows.length; i++) {
expect(updateSummary.updatedData[i][1]).toEqual('Donald'); // updated value
}
});
it('should append rows', () => {
const items = [
{
json: {
id: 4,
data: 'data 4',
name: 'Donald',
age: 45,
},
},
{
json: {
id: 5,
data: 'data 5',
name: 'Victor',
age: 67,
},
},
];
const sheetData = [
['id', 'name', 'age', 'data'],
[1, 'Sam', 55, 'data 3'],
[2, 'Jon', 77, 'data 3'],
[3, 'Ron', 44, 'data 3'],
];
const updateSummary = updateByAutoMaping(items, sheetData, 'data', true);
expect(updateSummary).toBeDefined();
expect(updateSummary.updatedRows).toContain(0);
expect(updateSummary.updatedRows.length).toEqual(1);
expect(updateSummary.appendData[0]).toEqual({ id: 4, name: 'Donald', age: 45, data: 'data 4' });
expect(updateSummary.appendData[1]).toEqual({ id: 5, name: 'Victor', age: 67, data: 'data 5' });
});
});
describe('Test MicrosoftExcelV2, checkRange', () => {
it('should not throw error', () => {
const range = 'A1:D4';
expect(() => {
checkRange(node, range);
}).not.toThrow();
});
it('should throw error', () => {
const range = 'A:D';
expect(() => {
checkRange(node, range);
}).toThrow();
});
});
describe('Test MicrosoftExcelV2, findAppendRange', () => {
it('should find append range for empty table', () => {
const address = 'A1';
const cols = 2;
const rows = 3;
const result = findAppendRange(address, { cols, rows });
expect(result).toBe('A1:B3');
});
it('should find append range for filled table', () => {
const address = 'A1:B2';
const cols = 2;
const rows = 2;
const result = findAppendRange(address, { cols, rows });
expect(result).toBe('A3:B4');
});
it('should find append range with additional columns for filled table', () => {
const address = 'A1:B2';
const cols = 3;
const rows = 2;
const result = findAppendRange(address, { cols, rows });
expect(result).toBe('A3:C4');
});
});
describe('Test MicrosoftExcelV2, nextExcelColumn', () => {
it('should return same column with offset 0', () => {
const result = nextExcelColumn('A', 0);
expect(result).toBe('A');
});
it('should return next column with default offset', () => {
const result = nextExcelColumn('A');
expect(result).toBe('B');
});
it('should return next column with offset 2', () => {
const result = nextExcelColumn('A', 2);
expect(result).toBe('C');
});
it('should handle Z to AA transition', () => {
const result = nextExcelColumn('Z');
expect(result).toBe('AA');
});
it('should handle AZ with offset 2', () => {
const result = nextExcelColumn('AZ', 2);
expect(result).toBe('BB');
});
it('should handle ZZ with offset 5', () => {
const result = nextExcelColumn('ZZ', 5);
expect(result).toBe('AAE');
});
it('should handle single letter columns', () => {
expect(nextExcelColumn('B')).toBe('C');
expect(nextExcelColumn('Y')).toBe('Z');
expect(nextExcelColumn('M', 3)).toBe('P');
});
it('should handle double letter columns', () => {
expect(nextExcelColumn('AA')).toBe('AB');
expect(nextExcelColumn('AB')).toBe('AC');
expect(nextExcelColumn('BA')).toBe('BB');
expect(nextExcelColumn('AY')).toBe('AZ');
});
it('should handle triple letter columns', () => {
expect(nextExcelColumn('AAA')).toBe('AAB');
expect(nextExcelColumn('AAZ')).toBe('ABA');
expect(nextExcelColumn('AZZ')).toBe('BAA');
});
it('should handle large offsets', () => {
expect(nextExcelColumn('A', 25)).toBe('Z');
expect(nextExcelColumn('A', 26)).toBe('AA');
expect(nextExcelColumn('A', 27)).toBe('AB');
expect(nextExcelColumn('A', 51)).toBe('AZ');
expect(nextExcelColumn('A', 52)).toBe('BA');
});
it('should handle transitions at column boundaries', () => {
expect(nextExcelColumn('Z', 1)).toBe('AA');
expect(nextExcelColumn('Z', 2)).toBe('AB');
expect(nextExcelColumn('AZ', 1)).toBe('BA');
expect(nextExcelColumn('ZZ', 1)).toBe('AAA');
});
it('should handle very large columns', () => {
expect(nextExcelColumn('XFD', 1)).toBe('XFE'); // XFD is Excel's last column
expect(nextExcelColumn('ZZY', 1)).toBe('ZZZ');
});
it('should handle offset of 1 explicitly', () => {
expect(nextExcelColumn('A', 1)).toBe('B');
expect(nextExcelColumn('Z', 1)).toBe('AA');
expect(nextExcelColumn('AA', 1)).toBe('AB');
});
it('should throw error for invalid offset', () => {
expect(() => nextExcelColumn('A', -1)).toThrow('Invalid offset: -1');
});
it('should maintain column sequence continuity', () => {
let current = 'A';
const sequence = [current];
for (let i = 0; i < 30; i++) {
current = nextExcelColumn(current);
sequence.push(current);
}
// Verify some key transitions in the sequence
expect(sequence).toContain('Z');
expect(sequence).toContain('AA');
expect(sequence).toContain('AB');
// Verify Z is followed by AA
const zIndex = sequence.indexOf('Z');
expect(sequence[zIndex + 1]).toBe('AA');
});
});
describe('Test MicrosoftExcelV2, parseAddress', () => {
it('should parse normal address', () => {
const address = 'A1:B2';
const result = parseAddress(address);
expect(result.cellFrom.value).toBe('A1');
expect(result.cellFrom.column).toBe('A');
expect(result.cellFrom.row).toBe('1');
expect(result.cellTo.value).toBe('B2');
expect(result.cellTo.column).toBe('B');
expect(result.cellTo.row).toBe('2');
});
it('should parse address with sheet name', () => {
const address = 'Sheet1!A1:B2';
const result = parseAddress(address);
expect(result.cellFrom.value).toBe('A1');
expect(result.cellFrom.column).toBe('A');
expect(result.cellFrom.row).toBe('1');
expect(result.cellTo.value).toBe('B2');
expect(result.cellTo.column).toBe('B');
expect(result.cellTo.row).toBe('2');
});
it('should parse address with double letter cell', () => {
const address = 'A1:AA2';
const result = parseAddress(address);
expect(result.cellFrom.value).toBe('A1');
expect(result.cellFrom.column).toBe('A');
expect(result.cellFrom.row).toBe('1');
expect(result.cellTo.value).toBe('AA2');
expect(result.cellTo.column).toBe('AA');
expect(result.cellTo.row).toBe('2');
});
});