refactor: Overhaul nodes-testing setup - Part 1 (no-changelog) (#14303)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2025-04-01 10:15:13 +02:00
committed by GitHub
parent f85b851851
commit 73e8d76e13
165 changed files with 3397 additions and 6453 deletions

View File

@@ -18,13 +18,12 @@ import type {
KnownNodesAndCredentials,
INodeTypeBaseDescription,
INodeTypeDescription,
INodeTypeData,
ICredentialTypeData,
LoadedClass,
ICredentialType,
INodeType,
IVersionedNodeType,
INodeProperties,
LoadedNodesAndCredentials,
} from 'n8n-workflow';
import { deepCopy, NodeConnectionTypes, UnexpectedError, UserError } from 'n8n-workflow';
import path from 'path';
@@ -39,11 +38,6 @@ import {
} from '@/constants';
import { isContainedWithin } from '@/utils/path-util';
interface LoadedNodesAndCredentials {
nodes: INodeTypeData;
credentials: ICredentialTypeData;
}
@Service()
export class LoadNodesAndCredentials {
private known: KnownNodesAndCredentials = { nodes: {}, credentials: {} };

View File

@@ -1,6 +1,7 @@
const { NODE_ENV } = process.env;
export const inProduction = NODE_ENV === 'production';
export const inDevelopment = !NODE_ENV || NODE_ENV === 'development';
export const inTest = NODE_ENV === 'test';
export const CUSTOM_EXTENSION_ENV = 'N8N_CUSTOM_EXTENSIONS';
export const PLACEHOLDER_EMPTY_EXECUTION_ID = '__UNKNOWN__';

View File

@@ -2,6 +2,10 @@ import vm from 'vm';
import { loadClassInIsolation } from '../load-class-in-isolation';
jest.mock('@/constants', () => ({
inTest: false,
}));
describe('loadClassInIsolation', () => {
const filePath = '/path/to/TestClass.js';
const className = 'TestClass';

View File

@@ -1,10 +1,19 @@
import { createContext, Script } from 'vm';
import { inTest } from '@/constants';
const context = createContext({ require });
export const loadClassInIsolation = <T>(filePath: string, className: string) => {
if (process.platform === 'win32') {
filePath = filePath.replace(/\\/g, '/');
}
const script = new Script(`new (require('${filePath}').${className})()`);
return script.runInContext(context) as T;
// Note: Skip the isolation because it breaks nock mocks in tests
if (inTest) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
return new (require(filePath)[className])() as T;
} else {
const script = new Script(`new (require('${filePath}').${className})()`);
return script.runInContext(context) as T;
}
};

View File

@@ -1,8 +1,8 @@
import type { WorkflowTestData } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '../ExecuteWorkflow';
import * as Helpers from '../Helpers';
import type { WorkflowTestData } from '../types';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
const records = [
{
@@ -26,7 +26,7 @@ describe('Execute Airtable Node', () => {
{
description: 'List Airtable Records',
input: {
workflowData: Helpers.readJsonFileSync('test/nodes/Airtable/workflow.json'),
workflowData: Helpers.readJsonFileSync('nodes/Airtable/test/workflow.json'),
},
output: {
nodeData: {
@@ -36,19 +36,9 @@ describe('Execute Airtable Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
for (const testData of tests) {
test(testData.description, async () => {
try {
// execute workflow
await executeWorkflow(testData, nodeTypes);
} catch (error) {
expect(error).toBeUndefined();
expect(error.message).toEqual(
'The API Key connection was deprecated by Airtable, please use Access Token or OAuth2 instead.',
);
}
await executeWorkflow(testData);
});
}
});

View File

@@ -1,10 +1,9 @@
import { NodeConnectionTypes } from 'n8n-workflow';
import { NodeConnectionTypes, type WorkflowTestData } from 'n8n-workflow';
import assert from 'node:assert';
import qs from 'node:querystring';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
describe('AwsSes Node', () => {
const email = 'test+user@example.com';
@@ -170,10 +169,8 @@ describe('AwsSes Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = Helpers.getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) =>
expect(resultData).toEqual(testData.output.nodeData[nodeName]),

View File

@@ -1,5 +1,7 @@
import nock from 'nock';
import { getWorkflowFilenames, testWorkflows } from '@test/nodes/Helpers';
import {
createResponse,
fieldsResponse,
@@ -7,18 +9,9 @@ import {
getResponse,
updateResponse,
} from './apiResponses';
import {
setup,
equalityTest,
workflowToTests,
getWorkflowFilenames,
} from '../../../../test/nodes/Helpers';
describe('Baserow > Workflows', () => {
describe('Run workflow', () => {
const workflows = getWorkflowFilenames(__dirname);
const tests = workflowToTests(workflows);
beforeAll(() => {
const mock = nock('https://api.baserow.io');
// Baserow > Get Token
@@ -54,10 +47,7 @@ describe('Baserow > Workflows', () => {
mock.delete('/api/database/rows/table/482710/3/').reply(200, {});
});
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = getWorkflowFilenames(__dirname);
testWorkflows(workflows);
});
});

View File

@@ -1,16 +1,10 @@
/* eslint-disable @typescript-eslint/no-loop-func */
import type { IDataObject } from 'n8n-workflow';
import type { IDataObject, WorkflowTestData } from 'n8n-workflow';
import os from 'node:os';
import path from 'path';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import {
getResultNodeData,
setup,
initBinaryDataService,
readJsonFileSync,
} from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { getResultNodeData, initBinaryDataService, readJsonFileSync } from '@test/nodes/Helpers';
if (os.platform() !== 'win32') {
describe('Execute Compression Node', () => {
@@ -53,11 +47,9 @@ if (os.platform() !== 'win32') {
},
];
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'POST') {
return {
describe('Test DiscordV2, channel => create', () => {
nock('https://discord.com/api/v10')
.post('/guilds/1168516062791340136/channels', { name: 'third', type: '0' })
.reply(200, {
id: '1168528323006181417',
type: 0,
last_message_id: null,
@@ -23,35 +18,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
position: 3,
permission_overwrites: [],
nsfw: false,
};
}
});
describe('Test DiscordV2, channel => create', () => {
const workflows = ['nodes/Discord/test/v2/node/channel/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'POST',
'/guilds/1168516062791340136/channels',
{ name: 'third', type: '0' },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Discord/test/v2/node/channel/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,53 +1,12 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'DELETE') {
return {
id: '1168528323006181417',
type: 0,
last_message_id: null,
flags: 0,
guild_id: '1168516062791340136',
name: 'third',
parent_id: null,
rate_limit_per_user: 0,
topic: null,
position: 3,
permission_overwrites: [],
nsfw: false,
};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, channel => deleteChannel', () => {
nock('https://discord.com/api/v10')
.delete('/channels/1168528323006181417')
.reply(200, { success: true });
const workflows = ['nodes/Discord/test/v2/node/channel/deleteChannel.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith('DELETE', '/channels/1168528323006181417');
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -61,18 +61,7 @@
"No Operation, do nothing": [
{
"json": {
"id": "1168528323006181417",
"type": 0,
"last_message_id": null,
"flags": 0,
"guild_id": "1168516062791340136",
"name": "third",
"parent_id": null,
"rate_limit_per_user": 0,
"topic": null,
"position": 3,
"permission_overwrites": [],
"nsfw": false
"success": true
}
}
]

View File

@@ -1,103 +1,28 @@
import type { INodeTypes, IRequestOptions } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/helpers';
// TODO: use nock
const requestApiSpy = jest.spyOn(transport, 'requestApi');
requestApiSpy.mockImplementation(
async (_options: IRequestOptions, _credentialType: string, endpoint: string) => {
if (endpoint === '/users/@me/guilds') {
return {
headers: {},
body: [
{
id: '1168516062791340136',
},
],
};
} else {
return {
headers: {},
body: {
id: '1168516240332034067',
type: 0,
last_message_id: null,
flags: 0,
guild_id: '1168516062791340136',
name: 'first',
parent_id: '1168516063340789831',
rate_limit_per_user: 0,
topic: null,
position: 1,
permission_overwrites: [],
nsfw: false,
},
};
}
},
);
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, channel => get', () => {
const workflows = ['nodes/Discord/test/v2/node/channel/get.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://discord.com/api/v10')
.persist()
.get('/users/@me/guilds')
.reply(200, [{ id: '1168516062791340136' }])
.get('/channels/1168516240332034067')
.reply(200, {
id: '1168516240332034067',
type: 0,
last_message_id: null,
flags: 0,
guild_id: '1168516062791340136',
name: 'first',
parent_id: '1168516063340789831',
rate_limit_per_user: 0,
topic: null,
position: 1,
permission_overwrites: [],
nsfw: false,
});
expect(requestApiSpy).toHaveBeenCalledTimes(3);
expect(requestApiSpy).toHaveBeenCalledWith(
{
body: undefined,
headers: {},
json: true,
method: 'GET',
qs: undefined,
url: 'https://discord.com/api/v10/users/@me/guilds',
},
'discordOAuth2Api',
'/users/@me/guilds',
);
expect(requestApiSpy).toHaveBeenCalledWith(
{
body: undefined,
headers: {},
json: true,
method: 'GET',
qs: undefined,
url: 'https://discord.com/api/v10/channels/1168516240332034067',
},
'discordOAuth2Api',
'/channels/1168516240332034067',
);
expect(requestApiSpy).toHaveBeenCalledWith(
{
body: undefined,
headers: {},
json: true,
method: 'GET',
qs: undefined,
url: 'https://discord.com/api/v10/channels/1168516240332034067',
},
'discordOAuth2Api',
'/channels/1168516240332034067',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Discord/test/v2/node/channel/get.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'GET') {
return [
describe('Test DiscordV2, channel => getAll', () => {
nock('https://discord.com/api/v10')
.get('/guilds/1168516062791340136/channels')
.reply(200, [
{
id: '1168516063340789831',
type: 4,
@@ -99,34 +94,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
permission_overwrites: [],
nsfw: false,
},
];
}
});
]);
describe('Test DiscordV2, channel => getAll', () => {
const workflows = ['nodes/Discord/test/v2/node/channel/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'GET',
'/guilds/1168516062791340136/channels',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,60 +1,23 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string, _) => {
if (method === 'PATCH') {
return {
id: '1168516240332034067',
type: 0,
last_message_id: null,
flags: 0,
guild_id: '1168516062791340136',
name: 'first-channel',
parent_id: '1168516063340789831',
rate_limit_per_user: 30,
topic: 'This is channel topic',
position: 3,
permission_overwrites: [],
nsfw: true,
};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, channel => update', () => {
nock('https://discord.com/api/v10').patch('/channels/1168516240332034067').reply(200, {
id: '1168516240332034067',
type: 0,
last_message_id: null,
flags: 0,
guild_id: '1168516062791340136',
name: 'first-channel',
parent_id: '1168516063340789831',
rate_limit_per_user: 30,
topic: 'This is channel topic',
position: 3,
permission_overwrites: [],
nsfw: true,
});
const workflows = ['nodes/Discord/test/v2/node/channel/update.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith('PATCH', '/channels/1168516240332034067', {
name: 'First Channel',
nsfw: true,
parent_id: '1168516063340789831',
position: 3,
rate_limit_per_user: 30,
topic: 'This is channel topic',
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'GET') {
return [
describe('Test DiscordV2, member => getAll', () => {
nock('https://discord.com/api/v10')
.get('/guilds/1168516062791340136/members?limit=2')
.reply(200, [
{
user: {
id: '470936827994570762',
@@ -46,36 +41,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
},
roles: ['1168518368526077992'],
},
];
}
});
]);
describe('Test DiscordV2, member => getAll', () => {
const workflows = ['nodes/Discord/test/v2/node/member/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'GET',
'/guilds/1168516062791340136/members',
undefined,
{ limit: 2 },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,45 +1,12 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'PUT') {
return {
success: true,
};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, member => roleAdd', () => {
nock('https://discord.com/api/v10')
.put('/guilds/1168516062791340136/members/470936827994570762/roles/1168772374540320890')
.reply(200, { success: true });
const workflows = ['nodes/Discord/test/v2/node/member/roleAdd.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'PUT',
'/guilds/1168516062791340136/members/470936827994570762/roles/1168772374540320890',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,53 +1,13 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'DELETE') {
return {
success: true,
};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, member => roleRemove', () => {
nock('https://discord.com/api/v10')
.persist()
.delete(/\/guilds\/1168516062791340136\/members\/470936827994570762\/roles\/\d+/)
.reply(200, { success: true });
const workflows = ['nodes/Discord/test/v2/node/member/roleRemove.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(3);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'DELETE',
'/guilds/1168516062791340136/members/470936827994570762/roles/1168773588963299428',
);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'DELETE',
'/guilds/1168516062791340136/members/470936827994570762/roles/1168773645800308756',
);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'DELETE',
'/guilds/1168516062791340136/members/470936827994570762/roles/1168772374540320890',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,45 +1,12 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'DELETE') {
return {
success: true,
};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, message => deleteMessage', () => {
nock('https://discord.com/api/v10')
.delete('/channels/1168516240332034067/messages/1168776343194972210')
.reply(200, { success: true });
const workflows = ['nodes/Discord/test/v2/node/message/deleteMessage.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'DELETE',
'/channels/1168516240332034067/messages/1168776343194972210',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'GET') {
return {
describe('Test DiscordV2, message => get', () => {
nock('https://discord.com/api/v10')
.get('/channels/1168516240332034067/messages/1168777380144369718')
.reply(200, {
id: '1168777380144369718',
channel_id: '1168516240332034067',
author: {
@@ -31,34 +26,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
content: 'msg 3',
timestamp: '2023-10-31T05:04:02.260000+00:00',
type: 0,
};
}
});
describe('Test DiscordV2, message => get', () => {
const workflows = ['nodes/Discord/test/v2/node/message/get.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'GET',
'/channels/1168516240332034067/messages/1168777380144369718',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Discord/test/v2/node/message/get.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'GET') {
return [
describe('Test DiscordV2, message => getAll', () => {
nock('https://discord.com/api/v10')
.get('/channels/1168516240332034067/messages?limit=1')
.reply(200, [
{
id: '1168784010269433998',
type: 0,
@@ -54,36 +49,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
flags: 0,
components: [],
},
];
}
});
]);
describe('Test DiscordV2, message => getAll', () => {
const workflows = ['nodes/Discord/test/v2/node/message/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'GET',
'/channels/1168516240332034067/messages',
undefined,
{ limit: 1 },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,45 +1,12 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'PUT') {
return {
success: true,
};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test DiscordV2, message => react', () => {
nock('https://discord.com/api/v10')
.put('/channels/1168516240332034067/messages/1168777380144369718/reactions/%F0%9F%98%80/@me')
.reply(200, { success: true });
const workflows = ['nodes/Discord/test/v2/node/message/react.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'PUT',
'/channels/1168516240332034067/messages/1168777380144369718/reactions/%F0%9F%98%80/@me',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,16 +1,22 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'POST') {
return {
describe('Test DiscordV2, message => send', () => {
nock('https://discord.com/api/v10')
.post('/channels/1168516240332034067/messages', {
content: 'msg 4',
embeds: [
{
author: { name: 'Me' },
color: 2112935,
description: 'description',
timestamp: '2023-10-30T22:00:00.000Z',
title: 'Some Title',
},
],
})
.reply(200, {
id: '1168784010269433998',
type: 0,
content: 'msg 4',
@@ -53,46 +59,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
flags: 0,
components: [],
referenced_message: null,
};
}
});
describe('Test DiscordV2, message => send', () => {
const workflows = ['nodes/Discord/test/v2/node/message/send.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'POST',
'/channels/1168516240332034067/messages',
{
content: 'msg 4',
embeds: [
{
author: { name: 'Me' },
color: 2112935,
description: 'description',
timestamp: '2023-10-30T22:00:00.000Z',
title: 'Some Title',
},
],
},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Discord/test/v2/node/message/send.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport/discord.api';
const discordApiRequestSpy = jest.spyOn(transport, 'discordApiRequest');
discordApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'POST') {
return {
describe('Test DiscordV2, webhook => sendLegacy', () => {
nock('https://discord.com')
.post('/webhook?wait=true')
.reply(200, {
id: '1168768986385747999',
type: 0,
content: 'TEST Message',
@@ -47,49 +42,8 @@ discordApiRequestSpy.mockImplementation(async (method: string) => {
flags: 4096,
components: [],
webhook_id: '1153265494955135077',
};
}
});
describe('Test DiscordV2, webhook => sendLegacy', () => {
const workflows = ['nodes/Discord/test/v2/node/webhook/sendLegacy.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(discordApiRequestSpy).toHaveBeenCalledTimes(1);
expect(discordApiRequestSpy).toHaveBeenCalledWith(
'POST',
'',
{
content: 'TEST Message',
embeds: [
{
author: { name: 'Michael' },
color: 10930459,
description: 'some description',
timestamp: '2023-10-17T21:00:00.000Z',
},
],
flags: 4096,
tts: true,
username: 'TEST_USER',
},
{ wait: true },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Discord/test/v2/node/webhook/sendLegacy.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,7 +1,8 @@
import { mock } from 'jest-mock-extended';
import type { IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
import { testWorkflows, getWorkflowFilenames } from '../../../test/nodes/Helpers';
import { testWorkflows, getWorkflowFilenames } from '@test/nodes/Helpers';
import { ExecutionData } from '../ExecutionData.node';
describe('ExecutionData Node', () => {

View File

@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-loop-func */
import type { WorkflowTestData } from 'n8n-workflow';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
describe('Test ReadWriteFile Node', () => {
beforeEach(async () => {
@@ -84,11 +85,9 @@ describe('Test ReadWriteFile Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
for (const testData of tests) {
test(testData.description, async () => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = Helpers.getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {

View File

@@ -62,9 +62,9 @@ describe('Test Github Node', () => {
jest.useFakeTimers({ doNotFake: ['nextTick'], now });
await initBinaryDataService();
});
beforeEach(async () => {
const baseUrl = 'https://api.github.com';
nock.cleanAll();
nock(baseUrl)
.persist()
.defaultReplyHeaders({ 'Content-Type': 'application/json' })
@@ -83,9 +83,6 @@ describe('Test Github Node', () => {
.reply(200, {});
});
afterEach(() => {
nock.cleanAll();
});
testWorkflows(workflows);
});
});

View File

@@ -2,27 +2,19 @@ import type {
ICredentialDataDecryptedObject,
IDataObject,
IHttpRequestOptions,
WorkflowTestData,
} from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import nock from 'nock';
import { CredentialsHelper } from '@test/nodes/credentials-helper';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { gongApiResponse, gongNodeResponse } from './mocks';
import { FAKE_CREDENTIALS_DATA } from '../../../test/nodes/FakeCredentialsMap';
describe('Gong Node', () => {
const baseUrl = 'https://api.gong.io';
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('Credentials', () => {
const tests: WorkflowTestData[] = [
{
@@ -121,12 +113,39 @@ describe('Gong Node', () => {
],
},
},
nock: {
baseUrl,
mocks: [
{
method: 'post',
path: '/v2/calls/extensive',
requestBody: { filter: { callIds: ['7782342274025937895'] } },
statusCode: 200,
responseBody: {
...gongApiResponse.postCallsExtensive,
records: {},
calls: [{ metaData: gongApiResponse.postCallsExtensive.calls[0].metaData }],
},
},
{
method: 'post',
path: '/v2/calls/extensive',
requestBody: { filter: { callIds: ['7782342274025937896'] } },
statusCode: 200,
responseBody: {
...gongApiResponse.postCallsExtensive,
records: {},
calls: [{ metaData: gongApiResponse.postCallsExtensive.calls[0].metaData }],
},
},
],
},
},
];
beforeAll(() => {
jest
.spyOn(Helpers.CredentialsHelper.prototype, 'authenticate')
.spyOn(CredentialsHelper.prototype, 'authenticate')
.mockImplementation(
async (
credentials: ICredentialDataDecryptedObject,
@@ -159,35 +178,8 @@ describe('Gong Node', () => {
);
});
nock(baseUrl)
.post('/v2/calls/extensive', { filter: { callIds: ['7782342274025937895'] } })
.matchHeader(
'authorization',
'basic ' +
Buffer.from(
`${FAKE_CREDENTIALS_DATA.gongApi.accessKey}:${FAKE_CREDENTIALS_DATA.gongApi.accessKeySecret}`,
).toString('base64'),
)
.reply(200, {
...gongApiResponse.postCallsExtensive,
records: {},
calls: [{ metaData: gongApiResponse.postCallsExtensive.calls[0].metaData }],
})
.post('/v2/calls/extensive', { filter: { callIds: ['7782342274025937896'] } })
.matchHeader(
'authorization',
'bearer ' + FAKE_CREDENTIALS_DATA.gongOAuth2Api.oauthTokenData.access_token,
)
.reply(200, {
...gongApiResponse.postCallsExtensive,
records: {},
calls: [{ metaData: gongApiResponse.postCallsExtensive.calls[0].metaData }],
});
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = Helpers.getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) =>
expect(resultData).toEqual(testData.output.nodeData[nodeName]),
@@ -780,10 +772,8 @@ describe('Gong Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
if (testData.description === 'should handle error response') {
// Only matches error message
@@ -1051,10 +1041,8 @@ describe('Gong Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
if (testData.description === 'should handle error response') {
expect(() => Helpers.getResultNodeData(result, testData)).toThrow(

View File

@@ -1,67 +1,42 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../v2/transport';
jest.mock('../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../v2/transport');
return {
...originalModule,
googleBigQueryApiRequest: jest.fn(async (method: IHttpRequestMethods, resource: string) => {
if (resource === '/v2/projects/test-project/jobs' && method === 'POST') {
return {
jobReference: {
jobId: 'job_123',
},
status: {
state: 'DONE',
},
};
}
if (resource === '/v2/projects/test-project/queries/job_123' && method === 'GET') {
return {};
}
}),
googleBigQueryApiRequestAllItems: jest.fn(async () => ({ rows: [], schema: {} })),
};
});
jest.mock('jsonwebtoken', () => ({
sign: jest.fn().mockReturnValue('signature'),
}));
describe('Test Google BigQuery V2, executeQuery', () => {
const workflows = ['nodes/Google/BigQuery/test/v2/node/executeQuery.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
nock('https://oauth2.googleapis.com')
.persist()
.post(
'/token',
'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=signature',
)
.reply(200, { access_token: 'token' });
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledTimes(1);
expect(transport.googleBigQueryApiRequestAllItems).toHaveBeenCalledTimes(1);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledWith(
'POST',
'/v2/projects/test-project/jobs',
{
configuration: {
query: {
query: 'SELECT * FROM bigquery_node_dev_test_dataset.test_json;',
useLegacySql: false,
},
nock('https://bigquery.googleapis.com/bigquery')
.post('/v2/projects/test-project/jobs', {
configuration: {
query: {
query: 'SELECT * FROM bigquery_node_dev_test_dataset.test_json;',
useLegacySql: false,
},
},
);
expect(transport.googleBigQueryApiRequestAllItems).toHaveBeenCalledWith(
'GET',
'/v2/projects/test-project/queries/job_123',
undefined,
{ location: undefined, maxResults: 1000, timeoutMs: 10000 },
);
})
.reply(200, {
jobReference: {
jobId: 'job_123',
},
status: {
state: 'DONE',
},
})
.get('/v2/projects/test-project/queries/job_123')
.reply(200)
.get('/v2/projects/test-project/queries/job_123?maxResults=1000&timeoutMs=10000')
.reply(200, { rows: [], schema: {} });
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Google/BigQuery/test/v2/node/executeQuery.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,58 +1,31 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../v2/transport';
jest.mock('../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../v2/transport');
return {
...originalModule,
googleBigQueryApiRequest: jest.fn(async (method: IHttpRequestMethods, resource: string) => {
if (
resource ===
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/num_text' &&
method === 'GET'
) {
return {
schema: {
fields: [
{ name: 'id', type: 'INT' },
{ name: 'test', type: 'STRING' },
],
},
};
}
if (
resource ===
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/num_text/insertAll' &&
method === 'POST'
) {
return { kind: 'bigquery#tableDataInsertAllResponse' };
}
}),
googleApiRequestAllItems: jest.fn(async () => {}),
};
});
jest.mock('jsonwebtoken', () => ({
sign: jest.fn().mockReturnValue('signature'),
}));
describe('Test Google BigQuery V2, insert auto map', () => {
const workflows = ['nodes/Google/BigQuery/test/v2/node/insert.autoMapMode.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
nock('https://oauth2.googleapis.com')
.persist()
.post(
'/token',
'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=signature',
)
.reply(200, { access_token: 'token' });
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledTimes(2);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledWith(
'GET',
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/num_text',
{},
);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledWith(
'POST',
nock('https://bigquery.googleapis.com/bigquery')
.get('/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/num_text')
.reply(200, {
schema: {
fields: [
{ name: 'id', type: 'INT' },
{ name: 'test', type: 'STRING' },
],
},
})
.post(
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/num_text/insertAll',
{
rows: [
@@ -62,12 +35,13 @@ describe('Test Google BigQuery V2, insert auto map', () => {
],
traceId: 'trace_id',
},
);
)
.reply(200, [
{ kind: 'bigquery#tableDataInsertAllResponse' },
{ kind: 'bigquery#tableDataInsertAllResponse' },
{ kind: 'bigquery#tableDataInsertAllResponse' },
]);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Google/BigQuery/test/v2/node/insert.autoMapMode.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,70 +1,40 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../v2/transport';
jest.mock('../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../v2/transport');
return {
...originalModule,
googleBigQueryApiRequest: jest.fn(async (method: IHttpRequestMethods, resource: string) => {
if (
resource ===
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/test_json' &&
method === 'GET'
) {
return {
schema: {
fields: [
{ name: 'json', type: 'JSON' },
{ name: 'name with space', type: 'STRING' },
{ name: 'active', type: 'BOOLEAN' },
],
},
};
}
if (
resource ===
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/test_json/insertAll' &&
method === 'POST'
) {
return { kind: 'bigquery#tableDataInsertAllResponse' };
}
}),
googleApiRequestAllItems: jest.fn(async () => {}),
};
});
jest.mock('jsonwebtoken', () => ({
sign: jest.fn().mockReturnValue('signature'),
}));
describe('Test Google BigQuery V2, insert define manually', () => {
const workflows = ['nodes/Google/BigQuery/test/v2/node/insert.manualMode.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
nock('https://oauth2.googleapis.com')
.persist()
.post(
'/token',
'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=signature',
)
.reply(200, { access_token: 'token' });
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledTimes(2);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledWith(
'GET',
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/test_json',
{},
);
expect(transport.googleBigQueryApiRequest).toHaveBeenCalledWith(
'POST',
nock('https://bigquery.googleapis.com/bigquery')
.get('/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/test_json')
.reply(200, {
schema: {
fields: [
{ name: 'json', type: 'JSON' },
{ name: 'name with space', type: 'STRING' },
{ name: 'active', type: 'BOOLEAN' },
],
},
})
.post(
'/v2/projects/test-project/datasets/bigquery_node_dev_test_dataset/tables/test_json/insertAll',
{
rows: [{ json: { active: 'true', json: '{"test": 1}', 'name with space': 'some name' } }],
traceId: 'trace_id',
},
);
)
.reply(200, [{ kind: 'bigquery#tableDataInsertAllResponse' }]);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Google/BigQuery/test/v2/node/insert.manualMode.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -12,12 +12,9 @@ describe('Test Gmail Node v1', () => {
jest
.useFakeTimers({ doNotFake: ['setImmediate', 'nextTick'] })
.setSystemTime(new Date('2024-12-16 12:34:56.789Z'));
nock.disableNetConnect();
});
afterAll(() => {
nock.restore();
jest.resetAllMocks();
});

View File

@@ -14,8 +14,6 @@ describe('Test Gmail Node v2', () => {
jest
.useFakeTimers({ doNotFake: ['setImmediate', 'nextTick'] })
.setSystemTime(new Date('2024-12-16 12:34:56.789Z'));
nock.disableNetConnect();
});
describe('Messages', () => {

View File

@@ -1,18 +1,9 @@
/* eslint-disable n8n-nodes-base/node-filename-against-convention */
import nock from 'nock';
import {
equalityTest,
getWorkflowFilenames,
initBinaryDataService,
setup,
workflowToTests,
} from '@test/nodes/Helpers';
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
describe('GraphQL Node', () => {
const workflows = getWorkflowFilenames(__dirname);
const workflowTests = workflowToTests(workflows);
const baseUrl = 'https://api.n8n.io/';
beforeAll(async () => {
@@ -69,9 +60,6 @@ describe('GraphQL Node', () => {
});
});
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
}
const workflows = getWorkflowFilenames(__dirname);
testWorkflows(workflows);
});

View File

@@ -1,17 +1,8 @@
import nock from 'nock';
import {
setup,
equalityTest,
workflowToTests,
getWorkflowFilenames,
initBinaryDataService,
} from '@test/nodes/Helpers';
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
describe('Test Binary Data Download', () => {
const workflows = getWorkflowFilenames(__dirname);
const tests = workflowToTests(workflows);
const baseUrl = 'https://dummy.domain';
beforeAll(async () => {
@@ -31,9 +22,7 @@ describe('Test Binary Data Download', () => {
'content-disposition': 'attachment; filename="testing.jpg"',
});
});
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = getWorkflowFilenames(__dirname);
testWorkflows(workflows);
});

View File

@@ -1,17 +1,8 @@
import nock from 'nock';
import {
setup,
equalityTest,
workflowToTests,
getWorkflowFilenames,
initBinaryDataService,
} from '@test/nodes/Helpers';
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
describe('Test Response Encoding', () => {
const workflows = getWorkflowFilenames(__dirname);
const tests = workflowToTests(workflows);
const baseUrl = 'https://dummy.domain';
const payload = Buffer.from(
'El rápido zorro marrón salta sobre el perro perezoso. ¡Qué bello día en París! Árbol, cañón, façade.',
@@ -26,9 +17,7 @@ describe('Test Response Encoding', () => {
.get('/index.html')
.reply(200, payload, { 'content-type': 'text/plain; charset=latin1' });
});
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = getWorkflowFilenames(__dirname);
testWorkflows(workflows);
});

View File

@@ -1,17 +1,8 @@
import nock from 'nock';
import {
setup,
equalityTest,
workflowToTests,
getWorkflowFilenames,
initBinaryDataService,
} from '@test/nodes/Helpers';
import { getWorkflowFilenames, initBinaryDataService, testWorkflows } from '@test/nodes/Helpers';
describe('Test Quoted Response Encoding', () => {
const workflows = getWorkflowFilenames(__dirname);
const tests = workflowToTests(workflows);
const baseUrl = 'https://dummy.domain';
const payload = Buffer.from(
'El rápido zorro marrón salta sobre el perro perezoso. ¡Qué bello día en París! Árbol, cañón, façade.',
@@ -26,9 +17,7 @@ describe('Test Quoted Response Encoding', () => {
.get('/index.html')
.reply(200, payload, { 'content-type': 'text/plain; charset="latin1"' });
});
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = getWorkflowFilenames(__dirname);
testWorkflows(workflows);
});

View File

@@ -1,18 +1,9 @@
import nock from 'nock';
import { parse as parseUrl } from 'url';
import {
initBinaryDataService,
setup,
equalityTest,
workflowToTests,
getWorkflowFilenames,
} from '@test/nodes/Helpers';
import { initBinaryDataService, getWorkflowFilenames, testWorkflows } from '@test/nodes/Helpers';
describe('Test HTTP Request Node', () => {
const workflows = getWorkflowFilenames(__dirname);
const tests = workflowToTests(workflows);
const baseUrl = 'https://dummyjson.com';
beforeAll(async () => {
@@ -191,9 +182,7 @@ describe('Test HTTP Request Node', () => {
return getPaginationReturnData.call(this, limit, skip);
});
});
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = getWorkflowFilenames(__dirname);
testWorkflows(workflows);
});

View File

@@ -1,12 +1,8 @@
/* eslint-disable @typescript-eslint/no-loop-func */
import type { WorkflowTestData } from 'n8n-workflow';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import {
getResultNodeData,
setup,
readJsonFileSync,
initBinaryDataService,
} from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { getResultNodeData, readJsonFileSync, initBinaryDataService } from '@test/nodes/Helpers';
describe('Execute iCalendar Node', () => {
beforeEach(async () => {
@@ -43,11 +39,10 @@ describe('Execute iCalendar Node', () => {
},
},
];
const nodeTypes = setup(tests);
for (const testData of tests) {
test(testData.description, async () => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {

View File

@@ -1,6 +1,7 @@
import nock from 'nock';
import { getWorkflowFilenames, testWorkflows } from '../../../../test/nodes/Helpers';
import { getWorkflowFilenames, testWorkflows } from '@test/nodes/Helpers';
import {
getCreateResponseClassic,
getSubscriberResponseClassic,

View File

@@ -1,6 +1,7 @@
import nock from 'nock';
import { getWorkflowFilenames, testWorkflows } from '../../../../test/nodes/Helpers';
import { getWorkflowFilenames, testWorkflows } from '@test/nodes/Helpers';
import {
getCreateResponseV2,
getSubscriberResponseV2,

View File

@@ -1,6 +1,7 @@
import type { IDataObject, INode } from 'n8n-workflow';
import { createMockExecuteFunction } from '../../../../test/nodes/Helpers';
import { createMockExecuteFunction } from '@test/nodes/Helpers';
import * as mode from '../../v3/actions/mode';
const node: INode = {

View File

@@ -1,22 +1,13 @@
import { NodeConnectionTypes } from 'n8n-workflow';
import nock from 'nock';
import { NodeConnectionTypes, type WorkflowTestData } from 'n8n-workflow';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { microsoftEntraApiResponse, microsoftEntraNodeResponse } from './mocks';
describe('Microsoft Entra Node', () => {
const baseUrl = 'https://graph.microsoft.com/v1.0';
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('Group description', () => {
const tests: WorkflowTestData[] = [
{
@@ -760,10 +751,8 @@ describe('Microsoft Entra Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = Helpers.getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) =>

View File

@@ -3,28 +3,20 @@ import type {
IDataObject,
IHttpRequestOptions,
ILoadOptionsFunctions,
WorkflowTestData,
} from 'n8n-workflow';
import { NodeConnectionTypes } from 'n8n-workflow';
import nock from 'nock';
import { CredentialsHelper } from '@test/nodes/credentials-helper';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { microsoftEntraApiResponse, microsoftEntraNodeResponse } from './mocks';
import { FAKE_CREDENTIALS_DATA } from '../../../../test/nodes/FakeCredentialsMap';
import { MicrosoftEntra } from '../MicrosoftEntra.node';
describe('Microsoft Entra Node', () => {
const baseUrl = 'https://graph.microsoft.com/v1.0';
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('Credentials', () => {
const tests: WorkflowTestData[] = [
{
@@ -87,12 +79,25 @@ describe('Microsoft Entra Node', () => {
'Micosoft Entra ID': [microsoftEntraNodeResponse.getGroup],
},
},
nock: {
baseUrl,
mocks: [
{
method: 'get',
path: `/groups/${microsoftEntraApiResponse.getGroup.id}`,
statusCode: 200,
responseBody: {
...microsoftEntraApiResponse.getGroup,
},
},
],
},
},
];
beforeAll(() => {
jest
.spyOn(Helpers.CredentialsHelper.prototype, 'authenticate')
.spyOn(CredentialsHelper.prototype, 'authenticate')
.mockImplementation(
async (
credentials: ICredentialDataDecryptedObject,
@@ -114,20 +119,8 @@ describe('Microsoft Entra Node', () => {
);
});
nock(baseUrl)
.get(`/groups/${microsoftEntraApiResponse.getGroup.id}`)
.matchHeader(
'authorization',
'bearer ' + FAKE_CREDENTIALS_DATA.microsoftEntraOAuth2Api.oauthTokenData.access_token,
)
.reply(200, {
...microsoftEntraApiResponse.getGroup,
});
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = Helpers.getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) =>
expect(resultData).toEqual(testData.output.nodeData[nodeName]),

View File

@@ -1,22 +1,13 @@
import { NodeConnectionTypes } from 'n8n-workflow';
import nock from 'nock';
import { NodeConnectionTypes, type WorkflowTestData } from 'n8n-workflow';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import * as Helpers from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { microsoftEntraApiResponse, microsoftEntraNodeResponse } from './mocks';
describe('Microsoft Entra Node', () => {
const baseUrl = 'https://graph.microsoft.com/v1.0';
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('User description', () => {
const tests: WorkflowTestData[] = [
{
@@ -1146,10 +1137,8 @@ describe('Microsoft Entra Node', () => {
},
];
const nodeTypes = Helpers.setup(tests);
test.each(tests)('$description', async (testData) => {
const { result } = await executeWorkflow(testData, nodeTypes);
const { result } = await executeWorkflow(testData);
const resultNodeData = Helpers.getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) =>

View File

@@ -1,60 +1,27 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'POST') {
return {
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,
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, table => addTable', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/addTable.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
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,
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{A0883CFE-D27E-4ECC-B94B-981830AAD55B}/tables/add',
{ address: 'A1:D4', hasHeaders: true },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/addTable.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,81 +1,28 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods, resource: string) {
if (method === 'GET') {
return {
value: [
{
name: 'id',
},
{
name: 'name',
},
{
name: 'age',
},
{
name: 'data',
},
],
};
}
if (method === 'POST' && resource.includes('createSession')) {
return {
id: 12345,
};
}
if (method === 'POST' && resource.includes('add')) {
return {
index: 3,
values: [[3, 'Donald', 99, 'data 5']],
};
}
if (method === 'POST' && resource.includes('closeSession')) {
return;
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, table => append', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/append.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(4);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{A0883CFE-D27E-4ECC-B94B-981830AAD55B}/tables/{317CA469-7D1C-4A5D-9B0B-424444BF0336}/rows/add',
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']] },
{},
'',
{ 'workbook-session-id': 12345 },
);
)
.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);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/append.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,56 +1,23 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'POST') {
return {
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'],
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, table => convertToRange', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/convertToRange.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
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'],
],
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{A0883CFE-D27E-4ECC-B94B-981830AAD55B}/tables/{6321EE4A-AC21-48AD-87D9-B527637D94B3}/convertToRange',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/convertToRange.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,47 +1,14 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'DELETE') {
return;
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
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);
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/deleteTable.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'DELETE',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{A0883CFE-D27E-4ECC-B94B-981830AAD55B}/tables/{92FBE3F5-3180-47EE-8549-40892C38DA7F}',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,61 +1,25 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequestAllItemsSkip: jest.fn(async function () {
return [
{
name: 'country',
},
{
name: 'browser',
},
{
name: 'session_duration',
},
{
name: 'visits',
},
];
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
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: [] });
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/getColumns.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledWith(
'value',
'GET',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{00000000-0001-0000-0000-000000000000}/tables/{613E8967-D581-44ED-81D3-82A01AA6A05C}/columns',
{},
{},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,85 +1,34 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'GET') {
return {
value: [
{
index: 0,
values: [['uk', 'firefox', 1, 1]],
},
{
index: 1,
values: [['us', 'chrome', 1, 12]],
},
],
};
}
}),
microsoftApiRequestAllItemsSkip: jest.fn(async function () {
return [
{
name: 'country',
},
{
name: 'browser',
},
{
name: 'session_duration',
},
{
name: 'visits',
},
];
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
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: [] });
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/getRows.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'GET',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{00000000-0001-0000-0000-000000000000}/tables/{613E8967-D581-44ED-81D3-82A01AA6A05C}/rows',
{},
{ $top: 2 },
);
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledWith(
'value',
'GET',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{00000000-0001-0000-0000-000000000000}/tables/{613E8967-D581-44ED-81D3-82A01AA6A05C}/columns',
{},
{ $select: 'name' },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,102 +1,42 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequestAllItemsSkip: jest.fn(async function (
_property: string,
_method: IHttpRequestMethods,
endpoint: string,
) {
if (endpoint.includes('columns')) {
return [
{
name: 'country',
},
{
name: 'browser',
},
{
name: 'session_duration',
},
{
name: 'visits',
},
];
}
if (endpoint.includes('rows')) {
return [
{
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]],
},
];
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
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: [] });
const workflows = ['nodes/Microsoft/Excel/test/v2/node/table/lookup.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledTimes(2);
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledWith(
'value',
'GET',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{00000000-0001-0000-0000-000000000000}/tables/{613E8967-D581-44ED-81D3-82A01AA6A05C}/rows',
{},
{},
);
expect(transport.microsoftApiRequestAllItemsSkip).toHaveBeenCalledWith(
'value',
'GET',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{00000000-0001-0000-0000-000000000000}/tables/{613E8967-D581-44ED-81D3-82A01AA6A05C}/columns',
{},
{ $select: 'name' },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,77 +1,26 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods, resource: string) {
if (method === 'POST' && resource.includes('createSession')) {
return {
id: 12345,
};
}
if (method === 'POST' && resource.includes('add')) {
return {
id: '{266ADAB7-25B6-4F28-A2D1-FD5BFBD7A4F0}',
name: 'Sheet42',
position: 8,
visibility: 'Visible',
};
}
if (method === 'POST' && resource.includes('closeSession')) {
return;
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
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);
const workflows = ['nodes/Microsoft/Excel/test/v2/node/workbook/addWorksheet.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(3);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/createSession',
{ persistChanges: true },
);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/add',
{ name: 'Sheet42' },
{},
'',
{ 'workbook-session-id': 12345 },
);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/closeSession',
{},
{},
'',
{ 'workbook-session-id': 12345 },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,47 +1,12 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'DELETE') {
return;
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, workbook => deleteWorkbook', () => {
nock('https://graph.microsoft.com/v1.0/me')
.delete('/drive/items/01FUWX3BXJLISGF2CFWBGYPHXFCXPXOJUK')
.reply(200);
const workflows = ['nodes/Microsoft/Excel/test/v2/node/workbook/deleteWorkbook.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'DELETE',
'/drive/items/01FUWX3BXJLISGF2CFWBGYPHXFCXPXOJUK',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,62 +1,23 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'GET') {
return {
value: [
{
'@odata.type': '#microsoft.graph.driveItem',
name: 'ПРРО копія.xlsx',
},
,
{
'@odata.type': '#microsoft.graph.driveItem',
name: 'Book 3.xlsx',
},
,
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, workbook => getAll', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/workbook/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
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',
},
],
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'GET',
"/drive/root/search(q='.xlsx')",
{},
{ $select: 'name', $top: 2 },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/workbook/getAll.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,45 +1,42 @@
import type { IHttpRequestMethods } from 'n8n-workflow';
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods, resource: string) {
if (method === 'GET' && resource.includes('usedRange')) {
return {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
};
}
if (method === 'PATCH' && resource.includes('{A0883CFE-D27E-4ECC-B94B-981830AAD55B}')) {
return {
values: [[4, 'Sam', 34, 'data 4']],
};
}
if (method === 'PATCH' && resource.includes('{426949D7-797F-43A9-A8A4-8FE283495A82}')) {
return {
values: [[4, 'Don', 37, 'data 44']],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => append', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/append.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
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']] });
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/append.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,56 +1,17 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'POST') {
return {
values: [
{
json: {
success: true,
},
},
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => clear', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/clear.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
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 } }],
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{F7AF92FE-D42D-452F-8E4A-901B1D1EBF3F}/range/clear',
{ applyTo: 'All' },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/clear.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,55 +1,16 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'DELETE') {
return {
values: [
{
json: {
success: true,
},
},
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => deleteWorksheet', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/deleteWorksheet.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
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 } }],
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'DELETE',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets/{88D9C37A-4180-4B23-8996-BF11F32EB63C}',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/deleteWorksheet.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,64 +1,29 @@
import type { IHttpRequestMethods, INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
if (method === 'GET') {
return {
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',
},
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => getAll', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
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',
},
],
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'GET',
'/drive/items/01FUWX3BQ4ATCOZNR265GLA6IJEZDQUE4I/workbook/worksheets',
{},
{ $select: 'name', $top: 3 },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/getAll.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,42 +1,31 @@
import type { IHttpRequestMethods } from 'n8n-workflow';
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods, resource: string) {
{
if (method === 'GET' && resource.includes('usedRange')) {
return {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
};
}
return {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => readRows', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/readRows.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
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'],
],
});
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/readRows.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,55 +1,56 @@
import type { IHttpRequestMethods } from 'n8n-workflow';
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods, resource: string) {
if (method === 'GET' && resource.includes('usedRange')) {
return {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
};
}
if (method === 'PATCH' && resource.includes('{A0883CFE-D27E-4ECC-B94B-981830AAD55B}')) {
return {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Sam', 34, 'data 4'],
],
};
}
if (method === 'PATCH' && resource.includes('{426949D7-797F-43A9-A8A4-8FE283495A82}')) {
return {
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Don', 37, 'data 44'],
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => update', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/update.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
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'],
],
});
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/update.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,57 +1,58 @@
import type { IHttpRequestMethods } from 'n8n-workflow';
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: IHttpRequestMethods, resource: string) {
if (method === 'GET' && resource.includes('usedRange')) {
return {
address: 'Sheet4!A1:D6',
values: [
['id', 'name', 'age', 'data'],
[1, 'Sam', 33, 'data 1'],
[2, 'Jon', 44, 'data 2'],
[3, 'Ron', 55, 'data 3'],
],
};
}
if (method === 'PATCH' && resource.includes('{A0883CFE-D27E-4ECC-B94B-981830AAD55B}')) {
return {
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'],
],
};
}
if (method === 'PATCH' && resource.includes('{426949D7-797F-43A9-A8A4-8FE283495A82}')) {
return {
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'],
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftExcelV2, worksheet => upsert', () => {
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/upsert.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
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'],
],
});
for (const testData of tests) {
test(testData.description, async () => await equalityTest(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Excel/test/v2/node/worksheet/upsert.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,68 +1,35 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendarGroups('AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRu_AAA%3D')/calendars/$entity",
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAFXBBZ_AAA=',
name: 'New Calendar',
color: 'lightOrange',
hexColor: '#fcab73',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAABVtwWTA==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, calendar => create', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/calendarGroups/AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRu_AAA=/calendars',
{ color: 'lightOrange', name: 'New Calendar' },
);
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendarGroups('AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRu_AAA%3D')/calendars/$entity",
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAFXBBZ_AAA=',
name: 'New Calendar',
color: 'lightOrange',
hexColor: '#fcab73',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAABVtwWTA==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,47 +1,14 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'DELETE') {
return {};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, calendar => delete', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/delete.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'DELETE',
nock('https://graph.microsoft.com/v1.0/me')
.delete(
'/calendars/AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvIAAA=',
);
)
.reply(200);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/delete.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,69 +1,34 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'GET') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendars/$entity",
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
name: 'Foo Calendar',
color: 'lightGreen',
hexColor: '#87d28e',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAAAi67hiw==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, calendar => get', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/get.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/calendars/AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendars/$entity",
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
name: 'Foo Calendar',
color: 'lightGreen',
hexColor: '#87d28e',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAAAi67hiw==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'GET',
'/calendars/AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
undefined,
{},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/get.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,88 +1,53 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'GET') {
return {
value: [
{
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=',
name: 'Calendar',
color: 'auto',
hexColor: '',
isDefaultCalendar: true,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAAACfdHfw==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: true,
isRemovable: false,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
},
{
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvBAAA=',
name: 'Third calendar',
color: 'lightYellow',
hexColor: '#fde300',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAAAi67hIw==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
},
],
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, calendar => getAll', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get('/calendars?%24filter=canEdit%20eq%20true&%24top=2')
.reply(200, {
value: [
{
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=',
name: 'Calendar',
color: 'auto',
hexColor: '',
isDefaultCalendar: true,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAAACfdHfw==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: true,
isRemovable: false,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
},
{
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvBAAA=',
name: 'Third calendar',
color: 'lightYellow',
hexColor: '#fde300',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAAAi67hIw==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
},
],
});
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith('GET', '/calendars', undefined, {
$filter: 'canEdit eq true',
$top: 2,
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
testWorkflows(workflows);
});

View File

@@ -1,68 +1,35 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'PATCH') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendars/$entity",
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
name: 'Foo',
color: 'lightOrange',
hexColor: '#fcab73',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAABVtwYKA==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, calendar => update', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/update.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'PATCH',
nock('https://graph.microsoft.com/v1.0/me')
.patch(
'/calendars/AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
{ color: 'lightOrange', isDefaultCalendar: false, name: 'Foo' },
);
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendars/$entity",
id: 'AAAXXXYYYnnnT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAACLtRvGAAA=',
name: 'Foo',
color: 'lightOrange',
hexColor: '#fcab73',
isDefaultCalendar: false,
changeKey: 'WX+A3vy5K0qqTyPHso1JgAABVtwYKA==',
canShare: true,
canViewPrivateItems: true,
canEdit: true,
allowedOnlineMeetingProviders: ['teamsForBusiness'],
defaultOnlineMeetingProvider: 'teamsForBusiness',
isTallyingResponses: false,
isRemovable: true,
owner: {
name: 'User Name',
address: 'test@mail.com',
},
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/calendar/update.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,82 +1,10 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/contacts/$entity",
'@odata.etag': 'W/"EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bob"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAABZf4De-LkrSqpPI8eyjUmAAAFXBCQuAAA=',
createdDateTime: '2023-09-04T08:48:39Z',
lastModifiedDateTime: '2023-09-04T08:48:39Z',
changeKey: 'EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bob',
categories: ['blue', 'green'],
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAAA=',
birthday: '1991-09-19T11:59:00Z',
fileAs: '',
displayName: 'User Name',
givenName: 'User',
initials: null,
middleName: null,
nickName: null,
surname: 'Name',
title: 'Title',
yomiGivenName: null,
yomiSurname: null,
yomiCompanyName: null,
generation: null,
imAddresses: [],
jobTitle: null,
companyName: 'Company',
department: 'IT',
officeLocation: null,
profession: null,
businessHomePage: null,
assistantName: 'Assistant',
manager: null,
homePhones: [],
mobilePhone: null,
businessPhones: [],
spouseName: null,
personalNotes: '',
children: [],
emailAddresses: [],
homeAddress: {},
businessAddress: {},
otherAddress: {},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, contact => create', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/contact/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith('POST', '/contacts', {
nock('https://graph.microsoft.com/v1.0/me')
.post('/contacts', {
assistantName: 'Assistant',
birthday: '1991-09-19T21:00:00.000Z',
categories: ['blue', 'green'],
@@ -86,12 +14,52 @@ describe('Test MicrosoftOutlookV2, contact => create', () => {
givenName: 'User',
surname: 'Name',
title: 'Title',
})
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/contacts/$entity",
'@odata.etag': 'W/"EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bob"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAABZf4De-LkrSqpPI8eyjUmAAAFXBCQuAAA=',
createdDateTime: '2023-09-04T08:48:39Z',
lastModifiedDateTime: '2023-09-04T08:48:39Z',
changeKey: 'EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bob',
categories: ['blue', 'green'],
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAAA=',
birthday: '1991-09-19T11:59:00Z',
fileAs: '',
displayName: 'User Name',
givenName: 'User',
initials: null,
middleName: null,
nickName: null,
surname: 'Name',
title: 'Title',
yomiGivenName: null,
yomiSurname: null,
yomiCompanyName: null,
generation: null,
imAddresses: [],
jobTitle: null,
companyName: 'Company',
department: 'IT',
officeLocation: null,
profession: null,
businessHomePage: null,
assistantName: 'Assistant',
manager: null,
homePhones: [],
mobilePhone: null,
businessPhones: [],
spouseName: null,
personalNotes: '',
children: [],
emailAddresses: [],
homeAddress: {},
businessAddress: {},
otherAddress: {},
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/contact/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,89 +1,10 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'PATCH') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/contacts/$entity",
'@odata.etag': 'W/"EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bou"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAABZf4De-LkrSqpPI8eyjUmAAAFXBCQuAAA=',
createdDateTime: '2023-09-04T08:48:39Z',
lastModifiedDateTime: '2023-09-04T09:06:21Z',
changeKey: 'EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bou',
categories: ['blue', 'green'],
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAAA=',
birthday: '1991-09-19T11:59:00Z',
fileAs: '',
displayName: 'Username',
givenName: 'User',
initials: null,
middleName: null,
nickName: null,
surname: 'Name',
title: 'Title',
yomiGivenName: null,
yomiSurname: null,
yomiCompanyName: null,
generation: null,
imAddresses: [],
jobTitle: null,
companyName: 'Company',
department: 'IT',
officeLocation: null,
profession: null,
businessHomePage: null,
assistantName: 'Assistant',
manager: 'Manager',
homePhones: [],
mobilePhone: '',
businessPhones: ['999000555777'],
spouseName: '',
personalNotes: '',
children: [],
emailAddresses: [],
homeAddress: {},
businessAddress: {
street: 'Street',
city: 'City',
state: 'State',
countryOrRegion: 'Country',
postalCode: '777777',
},
otherAddress: {},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, contact => update', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/contact/update.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'PATCH',
nock('https://graph.microsoft.com/v1.0/me')
.patch(
'/contacts/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAABZf4De-LkrSqpPI8eyjUmAAAFXBCQuAAA=',
{
businessAddress: {
@@ -97,12 +18,58 @@ describe('Test MicrosoftOutlookV2, contact => update', () => {
displayName: 'Username',
manager: 'Manager',
},
);
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/contacts/$entity",
'@odata.etag': 'W/"EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bou"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAABZf4De-LkrSqpPI8eyjUmAAAFXBCQuAAA=',
createdDateTime: '2023-09-04T08:48:39Z',
lastModifiedDateTime: '2023-09-04T09:06:21Z',
changeKey: 'EQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bou',
categories: ['blue', 'green'],
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEOAAA=',
birthday: '1991-09-19T11:59:00Z',
fileAs: '',
displayName: 'Username',
givenName: 'User',
initials: null,
middleName: null,
nickName: null,
surname: 'Name',
title: 'Title',
yomiGivenName: null,
yomiSurname: null,
yomiCompanyName: null,
generation: null,
imAddresses: [],
jobTitle: null,
companyName: 'Company',
department: 'IT',
officeLocation: null,
profession: null,
businessHomePage: null,
assistantName: 'Assistant',
manager: 'Manager',
homePhones: [],
mobilePhone: '',
businessPhones: ['999000555777'],
spouseName: '',
personalNotes: '',
children: [],
emailAddresses: [],
homeAddress: {},
businessAddress: {
street: 'Street',
city: 'City',
state: 'State',
countryOrRegion: 'Country',
postalCode: '777777',
},
otherAddress: {},
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/contact/update.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,137 +1,100 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/messages/$entity",
'@odata.etag': 'W/"CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bo2"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDupAAA=',
createdDateTime: '2023-09-04T09:18:35Z',
lastModifiedDateTime: '2023-09-04T09:18:35Z',
changeKey: 'CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bo2',
categories: [
'd10cd8f9-14ac-460e-a6ec-c40dd1876ea2',
'6844a34e-4d23-4805-9fec-38b7f6e1a780',
'fbf44fcd-7689-43a0-99c8-2c9faf6d825a',
],
receivedDateTime: '2023-09-04T09:18:35Z',
sentDateTime: '2023-09-04T09:18:35Z',
hasAttachments: false,
internetMessageId:
'<AM0PR10MB21003DD359041CBE7D64DDB6DDE9A@AM0PR10MB2100.EURPRD10.PROD.OUTLOOK.COM>',
subject: 'New Draft',
bodyPreview: 'draft message',
importance: 'normal',
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAAA=',
conversationId:
'AAQkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAQAKELKTNBg5JJuTnBGaTDyl0=',
conversationIndex: 'AQHZ3xDIoQspM0GDkkm5OcEZpMPKXQ==',
isDeliveryReceiptRequested: false,
isReadReceiptRequested: true,
isRead: true,
isDraft: true,
webLink:
'https://outlook.office365.com/owa/?ItemID=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAEPAABZf4De%2FLkrSqpPI8eyjUmAAAFXBDupAAA%3D&exvsurl=1&viewmodel=ReadMessageItem',
inferenceClassification: 'focused',
body: {
contentType: 'text',
content: 'draft message',
},
toRecipients: [
{
emailAddress: {
name: 'some@mail.com',
address: 'some@mail.com',
},
},
],
ccRecipients: [],
bccRecipients: [
{
emailAddress: {
name: 'name1@mail.com',
address: 'name1@mail.com',
},
},
{
emailAddress: {
name: 'name2@mail.com',
address: 'name2@mail.com',
},
},
],
replyTo: [
{
emailAddress: {
name: 'reply@mail.com',
address: 'reply@mail.com',
},
},
],
flag: {
flagStatus: 'notFlagged',
},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, draft => create', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/draft/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://graph.microsoft.com/v1.0/me')
.post('/messages', {
bccRecipients: [
{ emailAddress: { address: 'name1@mail.com' } },
{ emailAddress: { address: 'name2@mail.com' } },
],
body: { content: 'draft message', contentType: 'Text' },
categories: [
'd10cd8f9-14ac-460e-a6ec-c40dd1876ea2',
'6844a34e-4d23-4805-9fec-38b7f6e1a780',
'fbf44fcd-7689-43a0-99c8-2c9faf6d825a',
],
importance: 'Normal',
internetMessageHeaders: [{ name: 'x-my-header', value: 'header value' }],
isReadReceiptRequested: true,
replyTo: [{ emailAddress: { address: 'reply@mail.com' } }],
subject: 'New Draft',
toRecipients: [{ emailAddress: { address: 'some@mail.com' } }],
})
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/messages/$entity",
'@odata.etag': 'W/"CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bo2"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDupAAA=',
createdDateTime: '2023-09-04T09:18:35Z',
lastModifiedDateTime: '2023-09-04T09:18:35Z',
changeKey: 'CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3Bo2',
categories: [
'd10cd8f9-14ac-460e-a6ec-c40dd1876ea2',
'6844a34e-4d23-4805-9fec-38b7f6e1a780',
'fbf44fcd-7689-43a0-99c8-2c9faf6d825a',
],
receivedDateTime: '2023-09-04T09:18:35Z',
sentDateTime: '2023-09-04T09:18:35Z',
hasAttachments: false,
internetMessageId:
'<AM0PR10MB21003DD359041CBE7D64DDB6DDE9A@AM0PR10MB2100.EURPRD10.PROD.OUTLOOK.COM>',
subject: 'New Draft',
bodyPreview: 'draft message',
importance: 'normal',
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAAA=',
conversationId:
'AAQkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAQAKELKTNBg5JJuTnBGaTDyl0=',
conversationIndex: 'AQHZ3xDIoQspM0GDkkm5OcEZpMPKXQ==',
isDeliveryReceiptRequested: false,
isReadReceiptRequested: true,
isRead: true,
isDraft: true,
webLink:
'https://outlook.office365.com/owa/?ItemID=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAEPAABZf4De%2FLkrSqpPI8eyjUmAAAFXBDupAAA%3D&exvsurl=1&viewmodel=ReadMessageItem',
inferenceClassification: 'focused',
body: {
contentType: 'text',
content: 'draft message',
},
toRecipients: [
{
emailAddress: {
name: 'some@mail.com',
address: 'some@mail.com',
},
},
],
ccRecipients: [],
bccRecipients: [
{
emailAddress: {
name: 'name1@mail.com',
address: 'name1@mail.com',
},
},
{
emailAddress: {
name: 'name2@mail.com',
address: 'name2@mail.com',
},
},
],
replyTo: [
{
emailAddress: {
name: 'reply@mail.com',
address: 'reply@mail.com',
},
},
],
flag: {
flagStatus: 'notFlagged',
},
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/messages',
{
bccRecipients: [
{ emailAddress: { address: 'name1@mail.com' } },
{ emailAddress: { address: 'name2@mail.com' } },
],
body: { content: 'draft message', contentType: 'Text' },
categories: [
'd10cd8f9-14ac-460e-a6ec-c40dd1876ea2',
'6844a34e-4d23-4805-9fec-38b7f6e1a780',
'fbf44fcd-7689-43a0-99c8-2c9faf6d825a',
],
importance: 'Normal',
internetMessageHeaders: [{ name: 'x-my-header', value: 'header value' }],
isReadReceiptRequested: true,
replyTo: [{ emailAddress: { address: 'reply@mail.com' } }],
subject: 'New Draft',
toRecipients: [{ emailAddress: { address: 'some@mail.com' } }],
},
{},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/draft/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,52 +1,19 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, draft => send', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/draft/send.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(2);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'PATCH',
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDupAAA=/send',
)
.reply(200)
.patch(
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDupAAA=',
{ toRecipients: [{ emailAddress: { address: 'michael.k@radency.com' } }] },
);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDupAAA=/send',
);
)
.reply(200);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/draft/send.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,121 +1,10 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendars('AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA%3D')/events/$entity",
'@odata.etag': 'W/"WX+A3vy5K0qqTyPHso1JgAABVtwgEQ=="',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAENAABZf4De-LkrSqpPI8eyjUmAAAFXBFUSAAA=',
createdDateTime: '2023-09-04T10:12:47.1985121Z',
lastModifiedDateTime: '2023-09-04T10:12:48.2173253Z',
changeKey: 'WX+A3vy5K0qqTyPHso1JgAABVtwgEQ==',
categories: ['Yellow category', 'Orange category'],
transactionId: null,
originalStartTimeZone: 'UTC',
originalEndTimeZone: 'UTC',
iCalUId:
'040000008200E00074C5B7101A82E0080000000062DD545A18DFD90100000000000000001000000004C50947C7B42140B29018ABAB42C965',
reminderMinutesBeforeStart: 15,
isReminderOn: true,
hasAttachments: false,
subject: 'New Event',
bodyPreview:
'event description\r\n________________________________________________________________________________\r\nMicrosoft Teams meeting\r\nJoin on your computer, mobile app or room device\r\nClick here to join the meeting\r\nMeeting ID: 355 132 640 047\r\nPasscode: xgUo7v',
importance: 'normal',
sensitivity: 'personal',
isAllDay: false,
isCancelled: false,
isOrganizer: true,
responseRequested: true,
seriesMasterId: null,
showAs: 'busy',
type: 'singleInstance',
webLink:
'https://outlook.office365.com/owa/?itemid=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAENAABZf4De%2FLkrSqpPI8eyjUmAAAFXBFUSAAA%3D&exvsurl=1&path=/calendar/item',
onlineMeetingUrl: null,
isOnlineMeeting: true,
onlineMeetingProvider: 'teamsForBusiness',
allowNewTimeProposals: true,
occurrenceId: null,
isDraft: false,
hideAttendees: true,
responseStatus: {
response: 'organizer',
time: '0001-01-01T00:00:00Z',
},
body: {
contentType: 'html',
content:
'<html>\r\n<head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\r\n</head>\r\n<body>\r\nevent description<br>\r\n<div style="width:100%"><span style="white-space:nowrap; color:#5F5F5F; opacity:.36">________________________________________________________________________________</span>\r\n</div>\r\n<div class="me-email-text" lang="en-US" style="color:#252424; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\n<div style="margin-top:24px; margin-bottom:20px"><span style="font-size:24px; color:#252424">Microsoft Teams meeting</span>\r\n</div>\r\n<div style="margin-bottom:20px">\r\n<div style="margin-top:0px; margin-bottom:0px; font-weight:bold"><span style="font-size:14px; color:#252424">Join on your computer, mobile app or room device</span>\r\n</div>\r\n<a href="https://teams.microsoft.com/l/meetup-join/19%3ameeting_MDZmMzZmYzYtMDc4Yi00NTA2LWE3MTMtZDc5ZDI1M2JmY2M3%40thread.v2/0?context=%7b%22Tid%22%3a%2223786ca6-7ff2-4672-87d0-5c649ee0a337%22%2c%22Oid%22%3a%22b834447b-6848-4af9-8390-d2259ce46b74%22%7d" class="me-email-headline" style="font-size:14px; font-family:\'Segoe UI Semibold\',\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif; text-decoration:underline; color:#6264a7">Click\r\n here to join the meeting</a> </div>\r\n<div style="margin-bottom:20px; margin-top:20px">\r\n<div style="margin-bottom:4px"><span data-tid="meeting-code" style="font-size:14px; color:#252424">Meeting ID:\r\n<span style="font-size:16px; color:#252424">355 132 640 047</span> </span><br>\r\n<span style="font-size:14px; color:#252424">Passcode: </span><span style="font-size:16px; color:#252424">xgUo7v\r\n</span>\r\n<div style="font-size:14px"><a href="https://www.microsoft.com/en-us/microsoft-teams/download-app" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">Download\r\n Teams</a> | <a href="https://www.microsoft.com/microsoft-teams/join-a-meeting" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\nJoin on the web</a></div>\r\n</div>\r\n</div>\r\n<div style="margin-bottom:24px; margin-top:20px"><a href="https://aka.ms/JoinTeamsMeeting" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">Learn More</a>\r\n | <a href="https://teams.microsoft.com/meetingOptions/?organizerId=b834447b-6848-4af9-8390-d2259ce46b74&amp;tenantId=23786ca6-7ff2-4672-87d0-5c649ee0a337&amp;threadId=19_meeting_MDZmMzZmYzYtMDc4Yi00NTA2LWE3MTMtZDc5ZDI1M2JmY2M3@thread.v2&amp;messageId=0&amp;language=en-US" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\nMeeting options</a> </div>\r\n</div>\r\n<div style="font-size:14px; margin-bottom:4px; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\n</div>\r\n<div style="font-size:12px"></div>\r\n<div></div>\r\n<div style="width:100%"><span style="white-space:nowrap; color:#5F5F5F; opacity:.36">________________________________________________________________________________</span>\r\n</div>\r\n</body>\r\n</html>\r\n',
},
start: {
dateTime: '2023-09-05T07:26:47.0000000',
timeZone: 'UTC',
},
end: {
dateTime: '2023-09-06T07:56:47.0000000',
timeZone: 'UTC',
},
location: {
displayName: 'Microsoft Teams Meeting',
locationType: 'default',
uniqueId: 'Microsoft Teams Meeting',
uniqueIdType: 'private',
},
locations: [
{
displayName: 'Microsoft Teams Meeting',
locationType: 'default',
uniqueId: 'Microsoft Teams Meeting',
uniqueIdType: 'private',
},
],
recurrence: null,
attendees: [],
organizer: {
emailAddress: {
name: 'Michael Kret',
address: 'MichaelDevSandbox@5w1hb7.onmicrosoft.com',
},
},
onlineMeeting: {
joinUrl:
'https://teams.microsoft.com/l/meetup-join/19%3ameeting_MDZmMzZmYzYtMDc4Yi00NTA2LWE3MTMtZDc5ZDI1M2JmY2M3%40thread.v2/0?context=%7b%22Tid%22%3a%2223786ca6-7ff2-4672-87d0-5c649ee0a337%22%2c%22Oid%22%3a%22b834447b-6848-4af9-8390-d2259ce46b74%22%7d',
},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, contact => event', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/event/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/calendars/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA=/events',
{
body: { content: 'event description', contentType: 'html' },
@@ -134,12 +23,90 @@ describe('Test MicrosoftOutlookV2, contact => event', () => {
subject: 'New Event',
type: 'occurrence',
},
);
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/calendars('AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEGAABZf4De-LkrSqpPI8eyjUmAAAAJ9-JDAAA%3D')/events/$entity",
'@odata.etag': 'W/"WX+A3vy5K0qqTyPHso1JgAABVtwgEQ=="',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAENAABZf4De-LkrSqpPI8eyjUmAAAFXBFUSAAA=',
createdDateTime: '2023-09-04T10:12:47.1985121Z',
lastModifiedDateTime: '2023-09-04T10:12:48.2173253Z',
changeKey: 'WX+A3vy5K0qqTyPHso1JgAABVtwgEQ==',
categories: ['Yellow category', 'Orange category'],
transactionId: null,
originalStartTimeZone: 'UTC',
originalEndTimeZone: 'UTC',
iCalUId:
'040000008200E00074C5B7101A82E0080000000062DD545A18DFD90100000000000000001000000004C50947C7B42140B29018ABAB42C965',
reminderMinutesBeforeStart: 15,
isReminderOn: true,
hasAttachments: false,
subject: 'New Event',
bodyPreview:
'event description\r\n________________________________________________________________________________\r\nMicrosoft Teams meeting\r\nJoin on your computer, mobile app or room device\r\nClick here to join the meeting\r\nMeeting ID: 355 132 640 047\r\nPasscode: xgUo7v',
importance: 'normal',
sensitivity: 'personal',
isAllDay: false,
isCancelled: false,
isOrganizer: true,
responseRequested: true,
seriesMasterId: null,
showAs: 'busy',
type: 'singleInstance',
webLink:
'https://outlook.office365.com/owa/?itemid=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAENAABZf4De%2FLkrSqpPI8eyjUmAAAFXBFUSAAA%3D&exvsurl=1&path=/calendar/item',
onlineMeetingUrl: null,
isOnlineMeeting: true,
onlineMeetingProvider: 'teamsForBusiness',
allowNewTimeProposals: true,
occurrenceId: null,
isDraft: false,
hideAttendees: true,
responseStatus: {
response: 'organizer',
time: '0001-01-01T00:00:00Z',
},
body: {
contentType: 'html',
content:
'<html>\r\n<head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\r\n</head>\r\n<body>\r\nevent description<br>\r\n<div style="width:100%"><span style="white-space:nowrap; color:#5F5F5F; opacity:.36">________________________________________________________________________________</span>\r\n</div>\r\n<div class="me-email-text" lang="en-US" style="color:#252424; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\n<div style="margin-top:24px; margin-bottom:20px"><span style="font-size:24px; color:#252424">Microsoft Teams meeting</span>\r\n</div>\r\n<div style="margin-bottom:20px">\r\n<div style="margin-top:0px; margin-bottom:0px; font-weight:bold"><span style="font-size:14px; color:#252424">Join on your computer, mobile app or room device</span>\r\n</div>\r\n<a href="https://teams.microsoft.com/l/meetup-join/19%3ameeting_MDZmMzZmYzYtMDc4Yi00NTA2LWE3MTMtZDc5ZDI1M2JmY2M3%40thread.v2/0?context=%7b%22Tid%22%3a%2223786ca6-7ff2-4672-87d0-5c649ee0a337%22%2c%22Oid%22%3a%22b834447b-6848-4af9-8390-d2259ce46b74%22%7d" class="me-email-headline" style="font-size:14px; font-family:\'Segoe UI Semibold\',\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif; text-decoration:underline; color:#6264a7">Click\r\n here to join the meeting</a> </div>\r\n<div style="margin-bottom:20px; margin-top:20px">\r\n<div style="margin-bottom:4px"><span data-tid="meeting-code" style="font-size:14px; color:#252424">Meeting ID:\r\n<span style="font-size:16px; color:#252424">355 132 640 047</span> </span><br>\r\n<span style="font-size:14px; color:#252424">Passcode: </span><span style="font-size:16px; color:#252424">xgUo7v\r\n</span>\r\n<div style="font-size:14px"><a href="https://www.microsoft.com/en-us/microsoft-teams/download-app" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">Download\r\n Teams</a> | <a href="https://www.microsoft.com/microsoft-teams/join-a-meeting" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\nJoin on the web</a></div>\r\n</div>\r\n</div>\r\n<div style="margin-bottom:24px; margin-top:20px"><a href="https://aka.ms/JoinTeamsMeeting" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">Learn More</a>\r\n | <a href="https://teams.microsoft.com/meetingOptions/?organizerId=b834447b-6848-4af9-8390-d2259ce46b74&amp;tenantId=23786ca6-7ff2-4672-87d0-5c649ee0a337&amp;threadId=19_meeting_MDZmMzZmYzYtMDc4Yi00NTA2LWE3MTMtZDc5ZDI1M2JmY2M3@thread.v2&amp;messageId=0&amp;language=en-US" class="me-email-link" style="font-size:14px; text-decoration:underline; color:#6264a7; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\nMeeting options</a> </div>\r\n</div>\r\n<div style="font-size:14px; margin-bottom:4px; font-family:\'Segoe UI\',\'Helvetica Neue\',Helvetica,Arial,sans-serif">\r\n</div>\r\n<div style="font-size:12px"></div>\r\n<div></div>\r\n<div style="width:100%"><span style="white-space:nowrap; color:#5F5F5F; opacity:.36">________________________________________________________________________________</span>\r\n</div>\r\n</body>\r\n</html>\r\n',
},
start: {
dateTime: '2023-09-05T07:26:47.0000000',
timeZone: 'UTC',
},
end: {
dateTime: '2023-09-06T07:56:47.0000000',
timeZone: 'UTC',
},
location: {
displayName: 'Microsoft Teams Meeting',
locationType: 'default',
uniqueId: 'Microsoft Teams Meeting',
uniqueIdType: 'private',
},
locations: [
{
displayName: 'Microsoft Teams Meeting',
locationType: 'default',
uniqueId: 'Microsoft Teams Meeting',
uniqueIdType: 'private',
},
],
recurrence: null,
attendees: [],
organizer: {
emailAddress: {
name: 'Michael Kret',
address: 'MichaelDevSandbox@5w1hb7.onmicrosoft.com',
},
},
onlineMeeting: {
joinUrl:
'https://teams.microsoft.com/l/meetup-join/19%3ameeting_MDZmMzZmYzYtMDc4Yi00NTA2LWE3MTMtZDc5ZDI1M2JmY2M3%40thread.v2/0?context=%7b%22Tid%22%3a%2223786ca6-7ff2-4672-87d0-5c649ee0a337%22%2c%22Oid%22%3a%22b834447b-6848-4af9-8390-d2259ce46b74%22%7d',
},
});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/event/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,60 +1,27 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/mailFolders('AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEGAAA%3D')/childFolders/$entity",
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=',
displayName: 'Folder 42',
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEGAAA=',
childFolderCount: 0,
unreadItemCount: 0,
totalItemCount: 0,
sizeInBytes: 0,
isHidden: false,
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, contact => folder', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/folder/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://graph.microsoft.com')
.post(
'/v1.0/me/mailFolders/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEGAAA=/childFolders',
{ displayName: 'Folder 42' },
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/mailFolders('AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEGAAA%3D')/childFolders/$entity",
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=',
displayName: 'Folder 42',
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEGAAA=',
childFolderCount: 0,
unreadItemCount: 0,
totalItemCount: 0,
sizeInBytes: 0,
isHidden: false,
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/mailFolders/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEGAAA=/childFolders',
{ displayName: 'Folder 42' },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/folder/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,55 +1,23 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequestAllItems: jest.fn(async function () {
return [
describe('Test MicrosoftOutlookV2, folderMessage => getAll', () => {
nock('https://graph.microsoft.com/v1.0/me')
.get(
'/mailFolders/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=/messages?%24select=bodyPreview%2Csubject&%24top=100',
)
.reply(200, {
value: [
{
'@odata.etag': 'W/"CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3CAj"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAABZf4De-LkrSqpPI8eyjUmAAAFXBGDUAAA=',
subject: 'XXXX',
bodyPreview: 'test',
},
];
}),
};
});
describe('Test MicrosoftOutlookV2, folderMessage => getAll', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/folderMessage/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
],
});
expect(transport.microsoftApiRequestAllItems).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequestAllItems).toHaveBeenCalledWith(
'value',
'GET',
'/mailFolders/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=/messages',
undefined,
{ $select: 'bodyPreview,subject' },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/folderMessage/getAll.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,51 +1,18 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, message => move', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/move.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEJAABZf4De-LkrSqpPI8eyjUmAAAFXBEVwAAA=/move',
{
destinationId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=',
},
);
)
.reply(200);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/move.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,100 +1,10 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/messages/$entity",
'@odata.etag': 'W/"CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3CX+"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDurAAA=',
createdDateTime: '2023-09-04T12:29:59Z',
lastModifiedDateTime: '2023-09-04T12:29:59Z',
changeKey: 'CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3CX+',
categories: [],
receivedDateTime: '2023-09-04T12:29:59Z',
sentDateTime: '2023-09-04T12:29:59Z',
hasAttachments: false,
internetMessageId:
'<AM0PR10MB2100903A148F1623165004E3DDE9A@AM0PR10MB2100.EURPRD10.PROD.OUTLOOK.COM>',
subject: 'Reply Subject',
bodyPreview: 'Reply message',
importance: 'high',
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAAA=',
conversationId:
'AAQkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAQAKwkQLinj69KtoFOxMG2lVY=',
conversationIndex: 'AQHZ3yq3rCRAuKePr0q2gU7EwbaVVrAKmLQ4',
isDeliveryReceiptRequested: false,
isReadReceiptRequested: false,
isRead: true,
isDraft: true,
webLink:
'https://outlook.office365.com/owa/?ItemID=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAEPAABZf4De%2FLkrSqpPI8eyjUmAAAFXBDurAAA%3D&exvsurl=1&viewmodel=ReadMessageItem',
inferenceClassification: 'focused',
body: {
contentType: 'html',
content:
'<html><head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>Reply message </body></html>',
},
sender: {
emailAddress: {
name: 'Michael Kret',
address: 'MichaelDevSandbox@5w1hb7.onmicrosoft.com',
},
},
from: {
emailAddress: {
name: 'Michael Kret',
address: 'MichaelDevSandbox@5w1hb7.onmicrosoft.com',
},
},
toRecipients: [
{
emailAddress: {
name: 'reply@mail.com',
address: 'reply@mail.com',
},
},
],
ccRecipients: [],
bccRecipients: [],
replyTo: [],
flag: {
flagStatus: 'notFlagged',
},
};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, message => reply', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/reply.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(2);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
nock('https://graph.microsoft.com/v1.0/me')
.post(
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEJAABZf4De-LkrSqpPI8eyjUmAAAFXBEVwAAA=/createReply',
{
message: {
@@ -103,16 +13,73 @@ describe('Test MicrosoftOutlookV2, message => reply', () => {
subject: 'Reply Subject',
},
},
);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#users('b834447b-6848-4af9-8390-d2259ce46b74')/messages/$entity",
'@odata.etag': 'W/"CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3CX+"',
id: 'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDurAAA=',
createdDateTime: '2023-09-04T12:29:59Z',
lastModifiedDateTime: '2023-09-04T12:29:59Z',
changeKey: 'CQAAABYAAABZf4De/LkrSqpPI8eyjUmAAAFW3CX+',
categories: [],
receivedDateTime: '2023-09-04T12:29:59Z',
sentDateTime: '2023-09-04T12:29:59Z',
hasAttachments: false,
internetMessageId:
'<AM0PR10MB2100903A148F1623165004E3DDE9A@AM0PR10MB2100.EURPRD10.PROD.OUTLOOK.COM>',
subject: 'Reply Subject',
bodyPreview: 'Reply message',
importance: 'high',
parentFolderId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAAA=',
conversationId:
'AAQkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAQAKwkQLinj69KtoFOxMG2lVY=',
conversationIndex: 'AQHZ3yq3rCRAuKePr0q2gU7EwbaVVrAKmLQ4',
isDeliveryReceiptRequested: false,
isReadReceiptRequested: false,
isRead: true,
isDraft: true,
webLink:
'https://outlook.office365.com/owa/?ItemID=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAEPAABZf4De%2FLkrSqpPI8eyjUmAAAFXBDurAAA%3D&exvsurl=1&viewmodel=ReadMessageItem',
inferenceClassification: 'focused',
body: {
contentType: 'html',
content:
'<html><head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>Reply message </body></html>',
},
sender: {
emailAddress: {
name: 'Michael Kret',
address: 'MichaelDevSandbox@5w1hb7.onmicrosoft.com',
},
},
from: {
emailAddress: {
name: 'Michael Kret',
address: 'MichaelDevSandbox@5w1hb7.onmicrosoft.com',
},
},
toRecipients: [
{
emailAddress: {
name: 'reply@mail.com',
address: 'reply@mail.com',
},
},
],
ccRecipients: [],
bccRecipients: [],
replyTo: [],
flag: {
flagStatus: 'notFlagged',
},
})
.post(
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDurAAA=/send',
);
)
.reply(200);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/reply.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,57 +1,20 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {};
}
}),
};
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftOutlookV2, message => send', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/send.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(transport.microsoftApiRequest).toHaveBeenCalledTimes(1);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/sendMail',
{
message: {
body: { content: 'message description', contentType: 'Text' },
replyTo: [{ emailAddress: { address: 'reply@mail.com' } }],
subject: 'Hello',
toRecipients: [{ emailAddress: { address: 'to@mail.com' } }],
},
saveToSentItems: true,
nock('https://graph.microsoft.com')
.post('/v1.0/me/sendMail', {
message: {
body: { content: 'message description', contentType: 'Text' },
replyTo: [{ emailAddress: { address: 'reply@mail.com' } }],
subject: 'Hello',
toRecipients: [{ emailAddress: { address: 'to@mail.com' } }],
},
{},
);
saveToSentItems: true,
})
.reply(200, {});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/send.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/blob_create.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should create blob', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -66,7 +55,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/blob_delete.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should delete blob', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -35,7 +24,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/blob_get.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should get blob', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -87,7 +76,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/blob_getAll.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should get all blobs', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -36,7 +25,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,6 +1,4 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = [
@@ -8,16 +6,7 @@ describe('Azure Storage Node', () => {
];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should get all blobs with limit and options', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -31,7 +20,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/container_create.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should create container', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -38,7 +27,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/container_delete.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should delete container', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -35,7 +24,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/container_get.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should get container', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -44,7 +33,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,21 +1,10 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/container_getAll.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should get all containers', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -36,7 +25,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,6 +1,4 @@
import nock from 'nock';
import { equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = [
@@ -8,16 +6,7 @@ describe('Azure Storage Node', () => {
];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should get all containers with limit and options', () => {
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -31,7 +20,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -3,25 +3,16 @@ import type {
IDataObject,
IHttpRequestOptions,
} from 'n8n-workflow';
import nock from 'nock';
import { CredentialsHelper, equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { CredentialsHelper } from '@test/nodes/credentials-helper';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
describe('Azure Storage Node', () => {
const workflows = ['nodes/Microsoft/Storage/test/workflows/credentials_oauth2.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should use correct oauth2 credentials', () => {
beforeAll(() => {
nock.disableNetConnect();
jest
.spyOn(CredentialsHelper.prototype, 'authenticate')
.mockImplementation(
@@ -45,12 +36,9 @@ describe('Azure Storage Node', () => {
});
afterAll(() => {
nock.restore();
jest.restoreAllMocks();
});
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
@@ -59,7 +47,6 @@ describe('Azure Storage Node', () => {
method: 'get',
path: '/mycontainer?restype=container',
statusCode: 200,
requestHeaders: { authorization: 'bearer ACCESSTOKEN' },
responseBody: '',
responseHeaders: {
'content-length': '0',
@@ -80,7 +67,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
});

View File

@@ -1,26 +1,18 @@
import type { ICredentialDataDecryptedObject, IHttpRequestOptions } from 'n8n-workflow';
import nock from 'nock';
import { CredentialsHelper, equalityTest, setup, workflowToTests } from '@test/nodes/Helpers';
import { CredentialsHelper } from '@test/nodes/credentials-helper';
import { FAKE_CREDENTIALS_DATA } from '@test/nodes/FakeCredentialsMap';
import { equalityTest, workflowToTests } from '@test/nodes/Helpers';
import { AzureStorageSharedKeyApi } from '../../../../../credentials/AzureStorageSharedKeyApi.credentials';
import { FAKE_CREDENTIALS_DATA } from '../../../../../test/nodes/FakeCredentialsMap';
describe('Azure Storage Node', () => {
const { account, baseUrl, key } = FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi;
const workflows = ['nodes/Microsoft/Storage/test/workflows/credentials_sharedKey.workflow.json'];
const workflowTests = workflowToTests(workflows);
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('should use correct shared key credentials', () => {
beforeAll(() => {
nock.disableNetConnect();
jest
.spyOn(CredentialsHelper.prototype, 'authenticate')
.mockImplementation(
@@ -45,24 +37,17 @@ describe('Azure Storage Node', () => {
});
afterAll(() => {
nock.restore();
jest.restoreAllMocks();
});
const nodeTypes = setup(workflowTests);
for (const workflow of workflowTests) {
workflow.nock = {
baseUrl: 'https://myaccount.blob.core.windows.net',
baseUrl,
mocks: [
{
method: 'get',
path: '/mycontainer?restype=container',
statusCode: 200,
requestHeaders: {
authorization:
'SharedKey Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==',
},
responseBody: '',
responseHeaders: {
'content-length': '0',
@@ -83,7 +68,7 @@ describe('Azure Storage Node', () => {
},
],
};
test(workflow.description, async () => await equalityTest(workflow, nodeTypes));
test(workflow.description, async () => await equalityTest(workflow));
}
});
@@ -92,11 +77,11 @@ describe('Azure Storage Node', () => {
it('should remove undefined query parameters and headers', async () => {
const credentials: ICredentialDataDecryptedObject = {
account: FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.account,
key: FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.key,
account,
key,
};
const requestOptions: IHttpRequestOptions = {
url: `${FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.baseUrl}/mycontainer`,
url: `${baseUrl}/mycontainer`,
qs: { restype: 'container', query1: undefined },
headers: {
'Content-Length': undefined,
@@ -112,11 +97,11 @@ describe('Azure Storage Node', () => {
it('should default method to GET if not provided', async () => {
const credentials: ICredentialDataDecryptedObject = {
account: FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.account,
key: FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.key,
account,
key,
};
const requestOptions: IHttpRequestOptions = {
url: `${FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.baseUrl}/mycontainer`,
url: `${baseUrl}/mycontainer`,
qs: { restype: 'container' },
headers: {
'Content-Length': undefined,
@@ -129,11 +114,11 @@ describe('Azure Storage Node', () => {
it('should generate a valid authorization header', async () => {
const credentials: ICredentialDataDecryptedObject = {
account: FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.account,
key: FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.key,
account,
key,
};
const requestOptions: IHttpRequestOptions = {
url: `${FAKE_CREDENTIALS_DATA.azureStorageSharedKeyApi.baseUrl}/mycontainer/myblob`,
url: `${baseUrl}/mycontainer/myblob`,
qs: { param1: 'value1' },
headers: {
'x-ms-date': 'Thu, 27 Feb 2025 11:05:49 GMT',

View File

@@ -1,18 +1,11 @@
import type { ILoadOptionsFunctions, INodeParameterResourceLocator } from 'n8n-workflow';
import nock from 'nock';
import { FAKE_CREDENTIALS_DATA } from '../../../../../test/nodes/FakeCredentialsMap';
import { FAKE_CREDENTIALS_DATA } from '@test/nodes/FakeCredentialsMap';
import { AzureStorage } from '../../AzureStorage.node';
import { XMsVersion } from '../../GenericFunctions';
describe('Azure Storage Node', () => {
beforeEach(() => {
// https://github.com/nock/nock/issues/2057#issuecomment-663665683
if (!nock.isActive()) {
nock.activate();
}
});
describe('List search', () => {
it('should list search blobs', async () => {
const mockResponse =

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'POST') {
return {
describe('Test MicrosoftTeamsV2, channel => create', () => {
nock('https://graph.microsoft.com')
.post('/v1.0/teams/1644e7fe-547e-4223-a24f-922395865343/channels')
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#teams('1644e7fe-547e-4223-a24f-922395865343')/channels/$entity",
id: '19:16259efabba44a66916d91dd91862a6f@thread.tacv2',
@@ -22,39 +17,8 @@ microsoftApiRequestSpy.mockImplementation(async (method: string) => {
webUrl:
'https://teams.microsoft.com/l/channel/19%3a16259efabba44a66916d91dd91862a6f%40thread.tacv2/New+Channel?groupId=1644e7fe-547e-4223-a24f-922395865343&tenantId=tenantId-111-222-333',
membershipType: 'private',
};
}
});
describe('Test MicrosoftTeamsV2, channel => create', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'POST',
'/v1.0/teams/1644e7fe-547e-4223-a24f-922395865343/channels',
{
description: 'new channel description',
displayName: 'New Channel',
membershipType: 'private',
},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,43 +1,14 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'DELETE') {
return {};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftTeamsV2, channel => deleteChannel', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/deleteChannel.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'DELETE',
nock('https://graph.microsoft.com')
.delete(
'/v1.0/teams/1644e7fe-547e-4223-a24f-922395865343/channels/19:16259efabba44a66916d91dd91862a6f@thread.tacv2',
);
)
.reply(200, {});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/deleteChannel.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,13 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'GET') {
return {
describe('Test MicrosoftTeamsV2, channel => get', () => {
nock('https://graph.microsoft.com')
.get(
'/v1.0/teams/e25bae35-7bcc-4fb7-b4f2-0d5caef251fd/channels/19:dff84a49e5124cc89dff0192c621ea0f@thread.tacv2',
)
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#teams('e25bae35-7bcc-4fb7-b4f2-0d5caef251fd')/channels/$entity",
id: '19:dff84a49e5124cc89dff0192c621ea0f@thread.tacv2',
@@ -23,34 +20,8 @@ microsoftApiRequestSpy.mockImplementation(async (method: string) => {
webUrl:
'https://teams.microsoft.com/l/channel/19%3Adff84a49e5124cc89dff0192c621ea0f%40thread.tacv2/General?groupId=e25bae35-7bcc-4fb7-b4f2-0d5caef251fd&tenantId=tenantId-111-222-333&allowXTenantAccess=True',
membershipType: 'standard',
};
}
});
describe('Test MicrosoftTeamsV2, channel => get', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/get.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'GET',
'/v1.0/teams/e25bae35-7bcc-4fb7-b4f2-0d5caef251fd/channels/19:dff84a49e5124cc89dff0192c621ea0f@thread.tacv2',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/get.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,82 +1,51 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequestAllItems');
microsoftApiRequestSpy.mockImplementation(async (_, method: string) => {
if (method === 'GET') {
return [
{
id: '42:aaabbbccc.tacv2',
createdDateTime: '2022-03-26T17:18:33Z',
displayName: 'Sales West',
description: 'Description of Sales West',
isFavoriteByDefault: null,
email: null,
tenantId: 'tenantId-111-222-333',
webUrl:
'https://teams.microsoft.com/l/channel/threadId/Sales%20West?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&allowXTenantAccess=False',
membershipType: 'standard',
},
{
id: '19:8662cdf2d8ff49eabdcf6364bc0fe3a2@thread.tacv2',
createdDateTime: '2022-03-26T17:18:30Z',
displayName: 'Sales East',
description: 'Description of Sales West',
isFavoriteByDefault: null,
email: null,
tenantId: 'tenantId-111-222-333',
webUrl:
'https://teams.microsoft.com/l/channel/19%3A8662cdf2d8ff49eabdcf6364bc0fe3a2%40thread.tacv2/Sales%20East?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&allowXTenantAccess=False',
membershipType: 'standard',
},
{
id: '19:a95209ede91f4d5595ac944aeb172124@thread.tacv2',
createdDateTime: '2022-03-26T17:18:16Z',
displayName: 'General',
description: 'Description of U.S. Sales',
isFavoriteByDefault: null,
email: 'U.S.Sales@5w1hb7.onmicrosoft.com',
tenantId: 'tenantId-111-222-333',
webUrl:
'https://teams.microsoft.com/l/channel/19%3Aa95209ede91f4d5595ac944aeb172124%40thread.tacv2/U.S.%20Sales?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&allowXTenantAccess=False',
membershipType: 'standard',
},
];
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftTeamsV2, channel => getAll', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://graph.microsoft.com')
.get('/v1.0/teams/1111-2222-3333/channels')
.reply(200, {
value: [
{
id: '42:aaabbbccc.tacv2',
createdDateTime: '2022-03-26T17:18:33Z',
displayName: 'Sales West',
description: 'Description of Sales West',
isFavoriteByDefault: null,
email: null,
tenantId: 'tenantId-111-222-333',
webUrl:
'https://teams.microsoft.com/l/channel/threadId/Sales%20West?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&allowXTenantAccess=False',
membershipType: 'standard',
},
{
id: '19:8662cdf2d8ff49eabdcf6364bc0fe3a2@thread.tacv2',
createdDateTime: '2022-03-26T17:18:30Z',
displayName: 'Sales East',
description: 'Description of Sales West',
isFavoriteByDefault: null,
email: null,
tenantId: 'tenantId-111-222-333',
webUrl:
'https://teams.microsoft.com/l/channel/19%3A8662cdf2d8ff49eabdcf6364bc0fe3a2%40thread.tacv2/Sales%20East?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&allowXTenantAccess=False',
membershipType: 'standard',
},
{
id: '19:a95209ede91f4d5595ac944aeb172124@thread.tacv2',
createdDateTime: '2022-03-26T17:18:16Z',
displayName: 'General',
description: 'Description of U.S. Sales',
isFavoriteByDefault: null,
email: 'U.S.Sales@5w1hb7.onmicrosoft.com',
tenantId: 'tenantId-111-222-333',
webUrl:
'https://teams.microsoft.com/l/channel/19%3Aa95209ede91f4d5595ac944aeb172124%40thread.tacv2/U.S.%20Sales?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&allowXTenantAccess=False',
membershipType: 'standard',
},
],
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'value',
'GET',
'/v1.0/teams/1111-2222-3333/channels',
{},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/getAll.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,44 +1,15 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'PATCH') {
return {};
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftTeamsV2, channel => update', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/update.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'PATCH',
nock('https://graph.microsoft.com')
.patch(
'/v1.0/teams/e25bae35-7bcc-4fb7-b4f2-0d5caef251fd/channels/19:b9daa3647ff8450bacaf39490d3e05e2@thread.tacv2',
{ description: 'new channel description', displayName: 'New Deals' },
);
)
.reply(200, {});
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channel/update.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,13 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'POST') {
return {
describe('Test MicrosoftTeamsV2, channelMessage => create', () => {
nock('https://graph.microsoft.com')
.post('/beta/teams/1111-2222-3333/channels/42:aaabbbccc.tacv2/messages', {
body: { content: 'new sale', contentType: 'html' },
})
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/beta/$metadata#teams('1111-2222-3333')/channels('threadId')/messages/$entity",
id: '1698324478896',
@@ -52,35 +49,8 @@ microsoftApiRequestSpy.mockImplementation(async (method: string) => {
attachments: [],
mentions: [],
reactions: [],
};
}
});
describe('Test MicrosoftTeamsV2, channelMessage => create', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channelMessage/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'POST',
'/beta/teams/1111-2222-3333/channels/42:aaabbbccc.tacv2/messages',
{ body: { content: 'new sale', contentType: 'html' } },
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channelMessage/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,98 +1,68 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequestAllItems');
microsoftApiRequestSpy.mockImplementation(async (_, method: string) => {
if (method === 'GET') {
return [
{
id: '1698130964682',
replyToId: null,
etag: '1698130964682',
messageType: 'message',
createdDateTime: '2023-10-24T07:02:44.682Z',
lastModifiedDateTime: '2023-10-24T07:02:44.682Z',
lastEditedDateTime: null,
deletedDateTime: null,
subject: '',
summary: null,
chatId: null,
importance: 'normal',
locale: 'en-us',
webUrl:
'https://teams.microsoft.com/l/message/threadId/1698130964682?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&createdTime=1698130964682&parentMessageId=1698130964682',
onBehalfOf: null,
policyViolation: null,
eventDetail: null,
from: {
application: null,
device: null,
user: {
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
id: '11111-2222-3333',
displayName: 'My Name',
userIdentityType: 'aadUser',
tenantId: 'tenantId-111-222-333',
},
},
body: {
contentType: 'html',
content:
'<div>I added a tab at the top of this channel. Check it out!</div><attachment id="tab::f22a0494-6f7c-4512-85c5-e4ce72ce142a"></attachment>',
},
channelIdentity: {
teamId: '1111-2222-3333',
channelId: '42:aaabbbccc.tacv2',
},
attachments: [
{
id: 'tab::f22a0494-6f7c-4512-85c5-e4ce72ce142a',
contentType: 'tabReference',
contentUrl: null,
content: null,
name: 'Tasks',
thumbnailUrl: null,
teamsAppId: null,
},
],
mentions: [],
reactions: [],
},
];
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftTeamsV2, channelMessage => getAll', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channelMessage/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://graph.microsoft.com')
.get('/beta/teams/1111-2222-3333/channels/42:aaabbbccc.tacv2/messages')
.reply(200, {
value: [
{
id: '1698130964682',
replyToId: null,
etag: '1698130964682',
messageType: 'message',
createdDateTime: '2023-10-24T07:02:44.682Z',
lastModifiedDateTime: '2023-10-24T07:02:44.682Z',
lastEditedDateTime: null,
deletedDateTime: null,
subject: '',
summary: null,
chatId: null,
importance: 'normal',
locale: 'en-us',
webUrl:
'https://teams.microsoft.com/l/message/threadId/1698130964682?groupId=1111-2222-3333&tenantId=tenantId-111-222-333&createdTime=1698130964682&parentMessageId=1698130964682',
onBehalfOf: null,
policyViolation: null,
eventDetail: null,
from: {
application: null,
device: null,
user: {
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
id: '11111-2222-3333',
displayName: 'My Name',
userIdentityType: 'aadUser',
tenantId: 'tenantId-111-222-333',
},
},
body: {
contentType: 'html',
content:
'<div>I added a tab at the top of this channel. Check it out!</div><attachment id="tab::f22a0494-6f7c-4512-85c5-e4ce72ce142a"></attachment>',
},
channelIdentity: {
teamId: '1111-2222-3333',
channelId: '42:aaabbbccc.tacv2',
},
attachments: [
{
id: 'tab::f22a0494-6f7c-4512-85c5-e4ce72ce142a',
contentType: 'tabReference',
contentUrl: null,
content: null,
name: 'Tasks',
thumbnailUrl: null,
teamsAppId: null,
},
],
mentions: [],
reactions: [],
},
],
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'value',
'GET',
'/beta/teams/1111-2222-3333/channels/42:aaabbbccc.tacv2/messages',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/channelMessage/getAll.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'POST') {
return {
describe('Test MicrosoftTeamsV2, chatMessage => create', () => {
nock('https://graph.microsoft.com')
.post('/v1.0/chats/19:ebed9ad42c904d6c83adf0db360053ec@thread.v2/messages')
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#chats('19%3Aebed9ad42c904d6c83adf0db360053ec%40thread.v2')/messages/$entity",
id: '1698378560692',
@@ -48,35 +43,8 @@ microsoftApiRequestSpy.mockImplementation(async (method: string) => {
attachments: [],
mentions: [],
reactions: [],
};
}
});
describe('Test MicrosoftTeamsV2, chatMessage => create', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/chatMessage/create.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'POST',
'/v1.0/chats/19:ebed9ad42c904d6c83adf0db360053ec@thread.v2/messages',
expect.anything(),
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/chatMessage/create.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,16 +1,11 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { testWorkflows } from '@test/nodes/Helpers';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequest');
microsoftApiRequestSpy.mockImplementation(async (method: string) => {
if (method === 'GET') {
return {
describe('Test MicrosoftTeamsV2, chatMessage => get', () => {
nock('https://graph.microsoft.com')
.get('/v1.0/chats/19:ebed9ad42c904d6c83adf0db360053ec@thread.v2/messages/1698378560692')
.reply(200, {
'@odata.context':
"https://graph.microsoft.com/v1.0/$metadata#chats('19%3Aebed9ad42c904d6c83adf0db360053ec%40thread.v2')/messages/$entity",
id: '1698378560692',
@@ -49,34 +44,8 @@ microsoftApiRequestSpy.mockImplementation(async (method: string) => {
attachments: [],
mentions: [],
reactions: [],
};
}
});
describe('Test MicrosoftTeamsV2, chatMessage => get', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/chatMessage/get.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'GET',
'/v1.0/chats/19:ebed9ad42c904d6c83adf0db360053ec@thread.v2/messages/1698378560692',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/chatMessage/get.workflow.json'];
testWorkflows(workflows);
});

View File

@@ -1,122 +1,91 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import * as transport from '../../../../v2/transport';
const microsoftApiRequestSpy = jest.spyOn(transport, 'microsoftApiRequestAllItems');
microsoftApiRequestSpy.mockImplementation(async (_, method: string) => {
if (method === 'GET') {
return [
{
id: '1698378560692',
replyToId: null,
etag: '1698378560692',
messageType: 'message',
createdDateTime: '2023-10-27T03:49:20.692Z',
lastModifiedDateTime: '2023-10-27T03:49:20.692Z',
lastEditedDateTime: null,
deletedDateTime: null,
subject: null,
summary: null,
chatId: '19:ebed9ad42c904d6c83adf0db360053ec@thread.v2',
importance: 'normal',
locale: 'en-us',
webUrl: null,
channelIdentity: null,
policyViolation: null,
eventDetail: null,
from: {
application: null,
device: null,
user: {
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
id: '11111-2222-3333',
displayName: 'Michael Kret',
userIdentityType: 'aadUser',
tenantId: '23786ca6-7ff2-4672-87d0-5c649ee0a337',
},
},
body: {
contentType: 'html',
content:
'Hello!<br>\n<br>\n<em> Powered by <a href="http://localhost:5678/workflow/i3NYGF0LXV4qDFV9?utm_source=n8n-internal&amp;utm_medium=powered_by&amp;utm_campaign=n8n-nodes-base.microsoftTeams_b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363">this n8n workflow</a> </em>',
},
attachments: [],
mentions: [],
reactions: [],
},
{
id: '1698129297101',
replyToId: null,
etag: '1698129297101',
messageType: 'message',
createdDateTime: '2023-10-24T06:34:57.101Z',
lastModifiedDateTime: '2023-10-24T06:34:57.101Z',
lastEditedDateTime: null,
deletedDateTime: null,
subject: null,
summary: null,
chatId: '19:ebed9ad42c904d6c83adf0db360053ec@thread.v2',
importance: 'normal',
locale: 'en-us',
webUrl: null,
channelIdentity: null,
policyViolation: null,
eventDetail: null,
from: {
application: null,
device: null,
user: {
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
id: '11111-2222-3333',
displayName: 'Michael Kret',
userIdentityType: 'aadUser',
tenantId: '23786ca6-7ff2-4672-87d0-5c649ee0a337',
},
},
body: {
contentType: 'html',
content:
'tada<br>\n<br>\n<em> Powered by <a href="http://localhost:5678/workflow/5sTm8tp3j3niFewr?utm_source=n8n-internal&amp;utm_medium=powered_by&amp;utm_campaign=n8n-nodes-base.microsoftTeams_b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363">this n8n workflow</a> </em>',
},
attachments: [],
mentions: [],
reactions: [],
},
];
}
});
import { testWorkflows } from '@test/nodes/Helpers';
describe('Test MicrosoftTeamsV2, chatMessage => getAll', () => {
const workflows = ['nodes/Microsoft/Teams/test/v2/node/chatMessage/getAll.workflow.json'];
const tests = workflowToTests(workflows);
const nodeTypes = setup(tests);
const testNode = async (testData: WorkflowTestData, types: INodeTypes) => {
const { result } = await executeWorkflow(testData, types);
const resultNodeData = getResultNodeData(result, testData);
resultNodeData.forEach(({ nodeName, resultData }) => {
return expect(resultData).toEqual(testData.output.nodeData[nodeName]);
nock('https://graph.microsoft.com')
.get('/v1.0/chats/19:ebed9ad42c904d6c83adf0db360053ec@thread.v2/messages')
.reply(200, {
value: [
{
id: '1698378560692',
replyToId: null,
etag: '1698378560692',
messageType: 'message',
createdDateTime: '2023-10-27T03:49:20.692Z',
lastModifiedDateTime: '2023-10-27T03:49:20.692Z',
lastEditedDateTime: null,
deletedDateTime: null,
subject: null,
summary: null,
chatId: '19:ebed9ad42c904d6c83adf0db360053ec@thread.v2',
importance: 'normal',
locale: 'en-us',
webUrl: null,
channelIdentity: null,
policyViolation: null,
eventDetail: null,
from: {
application: null,
device: null,
user: {
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
id: '11111-2222-3333',
displayName: 'Michael Kret',
userIdentityType: 'aadUser',
tenantId: '23786ca6-7ff2-4672-87d0-5c649ee0a337',
},
},
body: {
contentType: 'html',
content:
'Hello!<br>\n<br>\n<em> Powered by <a href="http://localhost:5678/workflow/i3NYGF0LXV4qDFV9?utm_source=n8n-internal&amp;utm_medium=powered_by&amp;utm_campaign=n8n-nodes-base.microsoftTeams_b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363">this n8n workflow</a> </em>',
},
attachments: [],
mentions: [],
reactions: [],
},
{
id: '1698129297101',
replyToId: null,
etag: '1698129297101',
messageType: 'message',
createdDateTime: '2023-10-24T06:34:57.101Z',
lastModifiedDateTime: '2023-10-24T06:34:57.101Z',
lastEditedDateTime: null,
deletedDateTime: null,
subject: null,
summary: null,
chatId: '19:ebed9ad42c904d6c83adf0db360053ec@thread.v2',
importance: 'normal',
locale: 'en-us',
webUrl: null,
channelIdentity: null,
policyViolation: null,
eventDetail: null,
from: {
application: null,
device: null,
user: {
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
id: '11111-2222-3333',
displayName: 'Michael Kret',
userIdentityType: 'aadUser',
tenantId: '23786ca6-7ff2-4672-87d0-5c649ee0a337',
},
},
body: {
contentType: 'html',
content:
'tada<br>\n<br>\n<em> Powered by <a href="http://localhost:5678/workflow/5sTm8tp3j3niFewr?utm_source=n8n-internal&amp;utm_medium=powered_by&amp;utm_campaign=n8n-nodes-base.microsoftTeams_b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363">this n8n workflow</a> </em>',
},
attachments: [],
mentions: [],
reactions: [],
},
],
});
expect(microsoftApiRequestSpy).toHaveBeenCalledTimes(1);
expect(microsoftApiRequestSpy).toHaveBeenCalledWith(
'value',
'GET',
'/v1.0/chats/19:ebed9ad42c904d6c83adf0db360053ec@thread.v2/messages',
{},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => await testNode(testData, nodeTypes));
}
const workflows = ['nodes/Microsoft/Teams/test/v2/node/chatMessage/getAll.workflow.json'];
testWorkflows(workflows);
});

Some files were not shown because too many files have changed in this diff Show More