feat(Microsoft Outlook Node): Node overhaul (#4449)

[N8N-4995](https://linear.app/n8n/issue/N8N-4995)

---------

Co-authored-by: Giulio Andreini <g.andreini@gmail.com>
This commit is contained in:
Michael Kret
2023-09-15 12:52:18 +03:00
committed by GitHub
parent bb215bd12a
commit 556a6132ba
98 changed files with 11215 additions and 1202 deletions

View File

@@ -0,0 +1,61 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import * as transport from '../../../../v2/transport';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {};
}
}),
};
});
describe('Test MicrosoftOutlookV2, message => move', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/move.workflow.json'];
const tests = workflowToTests(workflows);
beforeAll(() => {
nock.disableNetConnect();
});
afterAll(() => {
nock.restore();
jest.unmock('../../../../v2/transport');
});
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',
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEJAABZf4De-LkrSqpPI8eyjUmAAAFXBEVwAAA=/move',
{
destinationId:
'AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=',
},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => testNode(testData, nodeTypes));
}
});

View File

@@ -0,0 +1,81 @@
{
"name": "My workflow 21",
"nodes": [
{
"parameters": {},
"id": "e524f588-b6a3-4849-8777-b32a8a755ae5",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
820,
360
]
},
{
"parameters": {
"operation": "move",
"messageId": {
"__rl": true,
"value": "AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEJAABZf4De-LkrSqpPI8eyjUmAAAFXBEVwAAA=",
"mode": "list",
"cachedResultName": "Hello",
"cachedResultUrl": "https://outlook.office365.com/owa/?ItemID=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAEJAABZf4De%2FLkrSqpPI8eyjUmAAAFXBEVwAAA%3D&exvsurl=1&viewmodel=ReadMessageItem"
},
"folderId": {
"__rl": true,
"value": "AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De-LkrSqpPI8eyjUmAAAFXBAEHAAA=",
"mode": "list",
"cachedResultName": "Folder 42",
"cachedResultUrl": "https://outlook.office365.com/mail/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OAAuAAAAAABPLqzvT6b9RLP0CKzHiJrRAQBZf4De%2FLkrSqpPI8eyjUmAAAFXBAEHAAA%3D"
}
},
"id": "baff6798-0304-4255-bdb0-dd3f2659373b",
"name": "Microsoft Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
1040,
360
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "iXJCki7i5Vz0bdks",
"name": "Microsoft Outlook account 2"
}
}
}
],
"pinData": {
"Microsoft Outlook": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Outlook",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "1434b547-7141-4650-8dce-333dda26e092",
"id": "1CYHzBXQw1nfPGtB",
"meta": {
"instanceId": "b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363"
},
"tags": []
}

View File

@@ -0,0 +1,128 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import * as transport from '../../../../v2/transport';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
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',
},
};
}
}),
};
});
describe('Test MicrosoftOutlookV2, message => reply', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/reply.workflow.json'];
const tests = workflowToTests(workflows);
beforeAll(() => {
nock.disableNetConnect();
});
afterAll(() => {
nock.restore();
jest.unmock('../../../../v2/transport');
});
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',
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEJAABZf4De-LkrSqpPI8eyjUmAAAFXBEVwAAA=/createReply',
{
message: {
body: { content: 'Reply message', contentType: 'html' },
importance: 'High',
subject: 'Reply Subject',
},
},
);
expect(transport.microsoftApiRequest).toHaveBeenCalledWith(
'POST',
'/messages/AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEPAABZf4De-LkrSqpPI8eyjUmAAAFXBDurAAA=/send',
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => testNode(testData, nodeTypes));
}
});

View File

@@ -0,0 +1,134 @@
{
"name": "My workflow 21",
"nodes": [
{
"parameters": {},
"id": "e524f588-b6a3-4849-8777-b32a8a755ae5",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
820,
360
]
},
{
"parameters": {
"operation": "reply",
"messageId": {
"__rl": true,
"value": "AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De-LkrSqpPI8eyjUmAAAAAAAEJAABZf4De-LkrSqpPI8eyjUmAAAFXBEVwAAA=",
"mode": "list",
"cachedResultName": "Hello",
"cachedResultUrl": "https://outlook.office365.com/owa/?ItemID=AAMkADlhOTA0MTc5LWUwOTMtNDRkZS05NzE0LTNlYmI0ZWM5OWI5OABGAAAAAABPLqzvT6b9RLP0CKzHiJrRBwBZf4De%2FLkrSqpPI8eyjUmAAAAAAAEJAABZf4De%2FLkrSqpPI8eyjUmAAAFXBEVwAAA%3D&exvsurl=1&viewmodel=ReadMessageItem"
},
"replyToSenderOnly": true,
"message": "Reply message",
"additionalFields": {
"importance": "High",
"bodyContentType": "html",
"subject": "Reply Subject"
},
"options": {}
},
"id": "baff6798-0304-4255-bdb0-dd3f2659373b",
"name": "Microsoft Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
1040,
360
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "iXJCki7i5Vz0bdks",
"name": "Microsoft Outlook account 2"
}
}
}
],
"pinData": {
"Microsoft Outlook": [
{
"json": {
"@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"
}
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Outlook",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "edd34dd1-0321-4d5b-a935-0c47d4c746b8",
"id": "1CYHzBXQw1nfPGtB",
"meta": {
"instanceId": "b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363"
},
"tags": []
}

View File

@@ -0,0 +1,67 @@
import type { INodeTypes } from 'n8n-workflow';
import nock from 'nock';
import * as transport from '../../../../v2/transport';
import { getResultNodeData, setup, workflowToTests } from '@test/nodes/Helpers';
import type { WorkflowTestData } from '@test/nodes/types';
import { executeWorkflow } from '@test/nodes/ExecuteWorkflow';
jest.mock('../../../../v2/transport', () => {
const originalModule = jest.requireActual('../../../../v2/transport');
return {
...originalModule,
microsoftApiRequest: jest.fn(async function (method: string) {
if (method === 'POST') {
return {};
}
}),
};
});
describe('Test MicrosoftOutlookV2, message => send', () => {
const workflows = ['nodes/Microsoft/Outlook/test/v2/node/message/send.workflow.json'];
const tests = workflowToTests(workflows);
beforeAll(() => {
nock.disableNetConnect();
});
afterAll(() => {
nock.restore();
jest.unmock('../../../../v2/transport');
});
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,
},
{},
);
expect(result.finished).toEqual(true);
};
for (const testData of tests) {
test(testData.description, async () => testNode(testData, nodeTypes));
}
});

View File

@@ -0,0 +1,73 @@
{
"name": "My workflow 21",
"nodes": [
{
"parameters": {},
"id": "e524f588-b6a3-4849-8777-b32a8a755ae5",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
820,
360
]
},
{
"parameters": {
"toRecipients": "to@mail.com",
"subject": "Hello",
"bodyContent": "message description",
"additionalFields": {
"bodyContentType": "Text",
"replyTo": "reply@mail.com"
}
},
"id": "baff6798-0304-4255-bdb0-dd3f2659373b",
"name": "Microsoft Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
1040,
360
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"id": "iXJCki7i5Vz0bdks",
"name": "Microsoft Outlook account 2"
}
}
}
],
"pinData": {
"Microsoft Outlook": [
{
"json": {
"success": true
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Microsoft Outlook",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "fed8ec2e-8663-4dfc-8234-33eb83257260",
"id": "1CYHzBXQw1nfPGtB",
"meta": {
"instanceId": "b888bd11cd1ddbb95450babf3e199556799d999b896f650de768b8370ee50363"
},
"tags": []
}