mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(Mandrill Node): Fix a typo in subaccount in options (#18103)
This commit is contained in:
@@ -766,8 +766,8 @@ export class Mandrill implements INodeType {
|
||||
message.from_name = options.fromName;
|
||||
}
|
||||
|
||||
if (options.subaccount) {
|
||||
message.subaccount = options.subaccount;
|
||||
if (options.subAccount) {
|
||||
message.subaccount = options.subAccount.toString();
|
||||
}
|
||||
|
||||
const body: Body = {
|
||||
|
||||
143
packages/nodes-base/nodes/Mandrill/test/GenericFunctions.test.ts
Normal file
143
packages/nodes-base/nodes/Mandrill/test/GenericFunctions.test.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import {
|
||||
getGoogleAnalyticsDomainsArray,
|
||||
getTags,
|
||||
getToEmailArray,
|
||||
validateJSON,
|
||||
} from '../GenericFunctions';
|
||||
|
||||
describe('Mandrill GenericFunctions', () => {
|
||||
describe('getToEmailArray', () => {
|
||||
it('should convert single email to array', () => {
|
||||
const result = getToEmailArray('test@example.com');
|
||||
expect(result).toEqual([
|
||||
{
|
||||
email: 'test@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should convert comma-separated emails to array', () => {
|
||||
const result = getToEmailArray('test1@example.com,test2@example.com,test3@example.com');
|
||||
expect(result).toEqual([
|
||||
{
|
||||
email: 'test1@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
{
|
||||
email: 'test2@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
{
|
||||
email: 'test3@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle emails with spaces after commas', () => {
|
||||
const result = getToEmailArray('test1@example.com, test2@example.com, test3@example.com');
|
||||
expect(result).toEqual([
|
||||
{
|
||||
email: 'test1@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
{
|
||||
email: ' test2@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
{
|
||||
email: ' test3@example.com',
|
||||
type: 'to',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getGoogleAnalyticsDomainsArray', () => {
|
||||
it('should convert single domain to array', () => {
|
||||
const result = getGoogleAnalyticsDomainsArray('example.com');
|
||||
expect(result).toEqual(['example.com']);
|
||||
});
|
||||
|
||||
it('should convert comma-separated domains to array', () => {
|
||||
const result = getGoogleAnalyticsDomainsArray('example.com,test.com,demo.org');
|
||||
expect(result).toEqual(['example.com', 'test.com', 'demo.org']);
|
||||
});
|
||||
|
||||
it('should handle domains with spaces after commas', () => {
|
||||
const result = getGoogleAnalyticsDomainsArray('example.com, test.com, demo.org');
|
||||
expect(result).toEqual(['example.com', ' test.com', ' demo.org']);
|
||||
});
|
||||
|
||||
it('should handle empty string', () => {
|
||||
const result = getGoogleAnalyticsDomainsArray('');
|
||||
expect(result).toEqual(['']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTags', () => {
|
||||
it('should convert single tag to array', () => {
|
||||
const result = getTags('newsletter');
|
||||
expect(result).toEqual(['newsletter']);
|
||||
});
|
||||
|
||||
it('should convert comma-separated tags to array', () => {
|
||||
const result = getTags('newsletter,marketing,promotion');
|
||||
expect(result).toEqual(['newsletter', 'marketing', 'promotion']);
|
||||
});
|
||||
|
||||
it('should handle tags with spaces after commas', () => {
|
||||
const result = getTags('newsletter, marketing, promotion');
|
||||
expect(result).toEqual(['newsletter', ' marketing', ' promotion']);
|
||||
});
|
||||
|
||||
it('should handle empty string', () => {
|
||||
const result = getTags('');
|
||||
expect(result).toEqual(['']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateJSON', () => {
|
||||
it('should parse valid JSON object', () => {
|
||||
const result = validateJSON('{"Test": "value", "number": 123}');
|
||||
expect(result).toEqual({ Test: 'value', number: 123 });
|
||||
});
|
||||
|
||||
it('should parse valid JSON array', () => {
|
||||
const result = validateJSON('[{"name": "Test", "value": "data"}]');
|
||||
expect(result).toEqual([{ name: 'Test', value: 'data' }]);
|
||||
});
|
||||
|
||||
it('should return empty array for invalid JSON', () => {
|
||||
const result = validateJSON('invalid json');
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return empty array for undefined input', () => {
|
||||
const result = validateJSON(undefined);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return null for null JSON string', () => {
|
||||
const result = validateJSON('null');
|
||||
expect(result).toEqual(null);
|
||||
});
|
||||
|
||||
it('should parse nested JSON correctly', () => {
|
||||
const result = validateJSON('{"metadata": {"key": "value"}, "array": [1, 2, 3]}');
|
||||
expect(result).toEqual({
|
||||
metadata: { key: 'value' },
|
||||
array: [1, 2, 3],
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle JSON with special characters', () => {
|
||||
const result = validateJSON('{"message": "Hello\\nWorld\\t!", "emoji": "🎉"}');
|
||||
expect(result).toEqual({
|
||||
message: 'Hello\nWorld\t!',
|
||||
emoji: '🎉',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
101
packages/nodes-base/nodes/Mandrill/test/Mandrill.node.test.ts
Normal file
101
packages/nodes-base/nodes/Mandrill/test/Mandrill.node.test.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||
import { mock, mockDeep } from 'jest-mock-extended';
|
||||
import type { ILoadOptionsFunctions, INode } from 'n8n-workflow';
|
||||
import nock from 'nock';
|
||||
|
||||
import { Mandrill } from '../Mandrill.node';
|
||||
|
||||
describe('Test Mandrill Node', () => {
|
||||
describe('Messages', () => {
|
||||
const mandrillNock = nock('https://mandrillapp.com/api/1.0');
|
||||
|
||||
beforeAll(() => {
|
||||
// Mock sendTemplate API call with subaccount verification
|
||||
mandrillNock
|
||||
.post('/messages/send-template.json', (body) => {
|
||||
// Verify that subaccount is properly passed to the API
|
||||
return (
|
||||
body.message &&
|
||||
body.message.subaccount === 'test-subaccount' &&
|
||||
body.template_name === 'test-template'
|
||||
);
|
||||
})
|
||||
.reply(200, [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
status: 'sent',
|
||||
reject_reason: null,
|
||||
_id: 'test-message-id-456',
|
||||
},
|
||||
]);
|
||||
|
||||
// Mock sendTemplate API call specifically for subaccount regression test
|
||||
mandrillNock
|
||||
.post('/messages/send-template.json', (body) => {
|
||||
// Verify regression test scenario: subaccount is properly passed
|
||||
return (
|
||||
body.message &&
|
||||
body.message.subaccount === 'regression-test-subaccount' &&
|
||||
body.template_name === 'test-template-subaccount'
|
||||
);
|
||||
})
|
||||
.reply(200, [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
status: 'sent',
|
||||
reject_reason: null,
|
||||
_id: 'test-subaccount-message-id',
|
||||
},
|
||||
]);
|
||||
|
||||
// Mock sendHtml API call
|
||||
mandrillNock.post('/messages/send.json').reply(200, [
|
||||
{
|
||||
email: 'recipient@example.com',
|
||||
status: 'rejected',
|
||||
_id: 'test-message-id-123',
|
||||
reject_reason: 'global-block',
|
||||
queued_reason: null,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
afterAll(() => mandrillNock.done());
|
||||
|
||||
new NodeTestHarness().setupTests({
|
||||
workflowFiles: [
|
||||
'sendTemplate.workflow.json',
|
||||
'sendTemplateWithSubaccount.workflow.json',
|
||||
'sendHtml.workflow.json',
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadOptions', () => {
|
||||
describe('getTemplates', () => {
|
||||
it('should return a list of Mandrill templates', async () => {
|
||||
const mandrill = new Mandrill();
|
||||
const loadOptionsFunctions = mockDeep<ILoadOptionsFunctions>();
|
||||
loadOptionsFunctions.getNode.mockReturnValue(mock<INode>());
|
||||
loadOptionsFunctions.getCredentials.mockResolvedValue({ apiKey: 'test-api-key' });
|
||||
loadOptionsFunctions.helpers.request.mockResolvedValue([
|
||||
{
|
||||
slug: 'template-1',
|
||||
name: 'Test Template 1',
|
||||
},
|
||||
{
|
||||
slug: 'template-2',
|
||||
name: 'Test Template 2',
|
||||
},
|
||||
]);
|
||||
|
||||
const result = await mandrill.methods.loadOptions.getTemplates.call(loadOptionsFunctions);
|
||||
|
||||
expect(result).toEqual([
|
||||
{ name: 'Test Template 1', value: 'template-1' },
|
||||
{ name: 'Test Template 2', value: 'template-2' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "sendHtml",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "test-trigger-node-id",
|
||||
"name": "When clicking 'Execute workflow'",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [0, 0]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"operation": "sendHtml",
|
||||
"fromEmail": "sender@example.com",
|
||||
"toEmail": "recipient@example.com",
|
||||
"options": {
|
||||
"html": "<h1>Test HTML Content</h1>",
|
||||
"subject": "Test HTML Subject"
|
||||
}
|
||||
},
|
||||
"id": "test-mandrill-node-id",
|
||||
"name": "Mandrill",
|
||||
"type": "n8n-nodes-base.mandrill",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 0],
|
||||
"credentials": {
|
||||
"mandrillApi": {
|
||||
"id": "test-credentials-id",
|
||||
"name": "Test Mandrill API"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking 'Execute workflow'": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Mandrill",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {
|
||||
"Mandrill": [
|
||||
{
|
||||
"json": {
|
||||
"email": "recipient@example.com",
|
||||
"status": "rejected",
|
||||
"_id": "test-message-id-123",
|
||||
"reject_reason": "global-block",
|
||||
"queued_reason": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "test-version-id",
|
||||
"meta": {
|
||||
"templateCredsSetupCompleted": true,
|
||||
"instanceId": "test-instance-id"
|
||||
},
|
||||
"id": "test-workflow-id-2",
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "sendTemplate",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "test-trigger-node-id",
|
||||
"name": "When clicking 'Execute workflow'",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [0, 0]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "sendTemplate",
|
||||
"template": "test-template",
|
||||
"fromEmail": "sender@example.com",
|
||||
"toEmail": "recipient@example.com",
|
||||
"options": {
|
||||
"subAccount": "test-subaccount"
|
||||
}
|
||||
},
|
||||
"id": "test-mandrill-node-id",
|
||||
"name": "Mandrill",
|
||||
"type": "n8n-nodes-base.mandrill",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 0],
|
||||
"credentials": {
|
||||
"mandrillApi": {
|
||||
"id": "test-credentials-id",
|
||||
"name": "Test Mandrill API"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking 'Execute workflow'": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Mandrill",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {
|
||||
"Mandrill": [
|
||||
{
|
||||
"json": {
|
||||
"email": "recipient@example.com",
|
||||
"status": "sent",
|
||||
"reject_reason": null,
|
||||
"_id": "test-message-id-456"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "test-version-id",
|
||||
"meta": {
|
||||
"instanceId": "test-instance"
|
||||
},
|
||||
"id": "test-workflow-id",
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "sendTemplateWithSubaccount",
|
||||
"nodes": [
|
||||
{
|
||||
"parameters": {},
|
||||
"id": "test-trigger-node-id",
|
||||
"name": "When clicking 'Execute workflow'",
|
||||
"type": "n8n-nodes-base.manualTrigger",
|
||||
"typeVersion": 1,
|
||||
"position": [0, 0]
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"resource": "message",
|
||||
"operation": "sendTemplate",
|
||||
"template": "test-template-subaccount",
|
||||
"fromEmail": "sender@example.com",
|
||||
"toEmail": "recipient@example.com",
|
||||
"options": {
|
||||
"subAccount": "regression-test-subaccount",
|
||||
"subject": "Testing subaccount functionality"
|
||||
}
|
||||
},
|
||||
"id": "test-mandrill-node-id",
|
||||
"name": "Mandrill",
|
||||
"type": "n8n-nodes-base.mandrill",
|
||||
"typeVersion": 1,
|
||||
"position": [220, 0],
|
||||
"credentials": {
|
||||
"mandrillApi": {
|
||||
"id": "test-credentials-id",
|
||||
"name": "Test Mandrill API"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"When clicking 'Execute workflow'": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Mandrill",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"pinData": {
|
||||
"Mandrill": [
|
||||
{
|
||||
"json": {
|
||||
"email": "recipient@example.com",
|
||||
"status": "sent",
|
||||
"reject_reason": null,
|
||||
"_id": "test-subaccount-message-id"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"active": false,
|
||||
"settings": {
|
||||
"executionOrder": "v1"
|
||||
},
|
||||
"versionId": "test-version-id",
|
||||
"meta": {
|
||||
"instanceId": "test-instance"
|
||||
},
|
||||
"id": "test-workflow-subaccount-id",
|
||||
"tags": []
|
||||
}
|
||||
Reference in New Issue
Block a user