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

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,253 @@
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
import {
type IExecuteFunctions,
type ILoadOptionsFunctions,
type IHookFunctions,
NodeApiError,
} from 'n8n-workflow';
import {
getCustomFields,
mailerliteApiRequest,
mailerliteApiRequestAllItems,
} from '../GenericFunctions';
describe('MailerLite -> mailerliteApiRequest', () => {
let mockExecuteFunctions: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
const setupMockFunctions = (typeVersion: number) => {
mockExecuteFunctions = {
getNode: jest.fn().mockReturnValue({ typeVersion }),
helpers: {
httpRequestWithAuthentication: jest.fn(),
},
} as unknown as IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
jest.clearAllMocks();
};
beforeEach(() => {
setupMockFunctions(1);
});
it('should make a successful API request for type version 1', async () => {
const method = 'GET';
const path = '/test';
const body = {};
const qs = {};
const responseData = { success: true };
(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockResolvedValue(
responseData,
);
const result = await mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs);
expect(result).toEqual(responseData);
expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'mailerLiteApi',
{
method,
qs,
url: 'https://api.mailerlite.com/api/v2/test',
json: true,
},
);
});
it('should make a successful API request for type version 2', async () => {
setupMockFunctions(2);
const method = 'GET';
const path = '/test';
const body = {};
const qs = {};
const responseData = { success: true };
(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockResolvedValue(
responseData,
);
const result = await mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs);
expect(result).toEqual(responseData);
expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'mailerLiteApi',
{
method,
qs,
url: 'https://connect.mailerlite.com/api/test',
json: true,
},
);
});
it('should make an API request with an empty body', async () => {
const method = 'GET';
const path = '/test';
const body = {};
const qs = {};
const responseData = { success: true };
(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockResolvedValue(
responseData,
);
const result = await mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs);
expect(result).toEqual(responseData);
expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
'mailerLiteApi',
{
method,
qs,
url: 'https://api.mailerlite.com/api/v2/test',
json: true,
},
);
});
it('should throw an error if the API request fails', async () => {
const method = 'GET';
const path = '/test';
const body = {};
const qs = {};
const errorResponse = { message: 'Error' };
(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockRejectedValue(
errorResponse,
);
await expect(
mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs),
).rejects.toThrow(NodeApiError);
});
});
describe('MailerLite -> mailerliteApiRequestAllItems', () => {
let mockExecuteFunctions: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
const setupMockFunctions = (typeVersion: number) => {
mockExecuteFunctions = {
getNode: jest.fn().mockReturnValue({ typeVersion }),
helpers: {
httpRequestWithAuthentication: jest.fn(),
},
} as unknown as IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
jest.clearAllMocks();
};
beforeEach(() => {
setupMockFunctions(1);
});
it('should handle pagination for type version 1', async () => {
const method = 'GET';
const endpoint = '/test';
const body = {};
const query = {};
const responseDataPage1 = [{ id: 1 }, { id: 2 }];
const responseDataPage2 = [{ id: 3 }, { id: 4 }];
(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock)
.mockResolvedValueOnce(responseDataPage1)
.mockResolvedValueOnce(responseDataPage2)
.mockResolvedValueOnce([]);
const result = await mailerliteApiRequestAllItems.call(
mockExecuteFunctions,
method,
endpoint,
body,
query,
);
expect(result).toEqual([...responseDataPage1, ...responseDataPage2]);
});
it('should handle pagination for type version 2', async () => {
setupMockFunctions(2);
const method = 'GET';
const endpoint = '/test';
const body = {};
const query = {};
const responseDataPage1 = {
data: [{ id: 1 }, { id: 2 }],
meta: { next_cursor: 'cursor1' },
links: { next: 'nextLink1' },
};
const responseDataPage2 = {
data: [{ id: 3 }, { id: 4 }],
meta: { next_cursor: null },
links: { next: null },
};
(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock)
.mockResolvedValueOnce(responseDataPage1)
.mockResolvedValueOnce(responseDataPage2);
const result = await mailerliteApiRequestAllItems.call(
mockExecuteFunctions,
method,
endpoint,
body,
query,
);
expect(result).toEqual([...responseDataPage1.data, ...responseDataPage2.data]);
});
});
describe('MailerLite -> getCustomFields', () => {
let mockExecuteFunctions: ILoadOptionsFunctions;
const v1FieldResponse = [
{ name: 'Field1', key: 'field1' },
{ name: 'Field2', key: 'field2' },
];
const v2FieldResponse = {
data: v1FieldResponse,
};
const setupMockFunctions = (typeVersion: number) => {
mockExecuteFunctions = {
getNode: jest.fn().mockReturnValue({ typeVersion }),
helpers: {
httpRequestWithAuthentication: jest
.fn()
.mockResolvedValue(typeVersion === 1 ? v1FieldResponse : v2FieldResponse),
},
} as unknown as ILoadOptionsFunctions;
jest.clearAllMocks();
};
beforeEach(() => {
setupMockFunctions(1);
});
it('should return custom fields for type version 1', async () => {
const result = await getCustomFields.call(mockExecuteFunctions);
expect(result).toEqual([
{ name: 'field1', value: 'field1' },
{ name: 'field2', value: 'field2' },
]);
});
it('should return custom fields for type version 2', async () => {
setupMockFunctions(2);
const result = await getCustomFields.call(mockExecuteFunctions);
expect(result).toEqual([
{ name: 'Field1', value: 'field1' },
{ name: 'Field2', value: 'field2' },
]);
});
});
@@ -0,0 +1,411 @@
export const getUpdateSubscriberResponseClassic = {
id: 1343965485,
email: 'demo@mailerlite.com',
sent: 0,
opened: 0,
clicked: 0,
type: 'unsubscribed',
fields: [
{
key: 'email',
value: 'demo@mailerlite.com',
type: 'TEXT',
},
{
key: 'name',
value: 'Demo',
type: 'TEXT',
},
{
key: 'last_name',
value: '',
type: 'TEXT',
},
{
key: 'company',
value: '',
type: 'TEXT',
},
{
key: 'country',
value: '',
type: 'TEXT',
},
{
key: 'city',
value: '',
type: 'TEXT',
},
{
key: 'phone',
value: '',
type: 'TEXT',
},
{
key: 'state',
value: '',
type: 'TEXT',
},
{
key: 'zip',
value: '',
type: 'TEXT',
},
],
date_subscribe: null,
date_unsubscribe: '2016-04-04 12:07:26',
date_created: '2016-04-04',
date_updated: null,
};
export const getSubscriberResponseClassic = {
id: 1343965485,
name: 'John',
email: 'demo@mailerlite.com',
sent: 0,
opened: 0,
clicked: 0,
type: 'active',
signup_ip: '127.0.0.1',
signup_timestamp: '2018-01-01 01:01:01',
confirmation_ip: '127.0.0.2',
confirmation_timestamp: '2018-01-01 01:01:02',
fields: [
{
key: 'email',
value: 'demo@mailerlite.com',
type: 'TEXT',
},
{
key: 'name',
value: 'John',
type: 'TEXT',
},
{
key: 'last_name',
value: '',
type: 'TEXT',
},
{
key: 'company',
value: '',
type: 'TEXT',
},
{
key: 'country',
value: '',
type: 'TEXT',
},
{
key: 'city',
value: '',
type: 'TEXT',
},
{
key: 'phone',
value: '',
type: 'TEXT',
},
{
key: 'state',
value: '',
type: 'TEXT',
},
{
key: 'zip',
value: '',
type: 'TEXT',
},
],
date_subscribe: null,
date_unsubscribe: null,
date_created: '2016-04-04',
date_updated: null,
};
export const getCreateResponseClassic = {
id: 1343965485,
name: 'John',
email: 'demo@mailerlite.com',
sent: 0,
opened: 0,
clicked: 0,
type: 'active',
fields: [
{
key: 'email',
value: 'demo@mailerlite.com',
type: 'TEXT',
},
{
key: 'name',
value: 'John',
type: 'TEXT',
},
{
key: 'last_name',
value: '',
type: 'TEXT',
},
{
key: 'company',
value: 'MailerLite',
type: 'TEXT',
},
{
key: 'country',
value: '',
type: 'TEXT',
},
{
key: 'city',
value: '',
type: 'TEXT',
},
{
key: 'phone',
value: '',
type: 'TEXT',
},
{
key: 'state',
value: '',
type: 'TEXT',
},
{
key: 'zip',
value: '',
type: 'TEXT',
},
],
date_subscribe: null,
date_unsubscribe: null,
date_created: '2016-04-04 12:00:00',
date_updated: '2016-04-04 12:00:00',
};
export const getAllSubscribersResponseClassic = [
{
id: 1343965485,
name: 'John',
email: 'demo@mailerlite.com',
sent: 0,
opened: 0,
clicked: 0,
type: 'active',
fields: [
{
key: 'email',
value: 'demo@mailerlite.com',
type: 'TEXT',
},
{
key: 'name',
value: 'John',
type: 'TEXT',
},
{
key: 'last_name',
value: '',
type: 'TEXT',
},
{
key: 'company',
value: '',
type: 'TEXT',
},
{
key: 'country',
value: '',
type: 'TEXT',
},
{
key: 'city',
value: '',
type: 'TEXT',
},
{
key: 'phone',
value: '',
type: 'TEXT',
},
{
key: 'state',
value: '',
type: 'TEXT',
},
{
key: 'zip',
value: '',
type: 'TEXT',
},
],
date_subscribe: null,
date_unsubscribe: null,
date_created: '2016-04-04',
date_updated: null,
},
];
export const getUpdateSubscriberResponseV2 = {
data: {
id: '139872142007207563',
email: 'user@n8n.io',
status: 'junk',
source: 'api',
sent: 0,
opens_count: 0,
clicks_count: 0,
open_rate: 0,
click_rate: 0,
ip_address: null,
subscribed_at: '2024-12-05 09:54:29',
unsubscribed_at: null,
created_at: '2024-12-05 09:54:29',
updated_at: '2024-12-05 10:20:32',
fields: {
name: null,
last_name: null,
company: null,
country: null,
city: null,
phone: null,
state: null,
z_i_p: null,
},
groups: [],
opted_in_at: null,
optin_ip: '8.8.8.8',
},
};
export const getCreateResponseV2 = {
data: {
id: '139872142007207563',
email: 'user@n8n.io',
status: 'junk',
source: 'api',
sent: 0,
opens_count: 0,
clicks_count: 0,
open_rate: 0,
click_rate: 0,
ip_address: null,
subscribed_at: '2024-12-05 09:54:29',
unsubscribed_at: null,
created_at: '2024-12-05 09:54:29',
updated_at: '2024-12-05 10:20:32',
fields: {
name: null,
last_name: null,
company: null,
country: null,
city: null,
phone: null,
state: null,
z_i_p: null,
},
groups: [],
opted_in_at: null,
optin_ip: '8.8.8.8',
},
};
export const getSubscriberResponseV2 = {
data: {
id: '139872142007207563',
email: 'user@n8n.io',
status: 'junk',
source: 'api',
sent: 0,
opens_count: 0,
clicks_count: 0,
open_rate: 0,
click_rate: 0,
ip_address: null,
subscribed_at: '2024-12-05 09:54:29',
unsubscribed_at: null,
created_at: '2024-12-05 09:54:29',
updated_at: '2024-12-05 10:20:32',
fields: {
name: null,
last_name: null,
company: null,
country: null,
city: null,
phone: null,
state: null,
z_i_p: null,
},
groups: [],
opted_in_at: null,
optin_ip: '8.8.8.8',
},
};
export const getAllSubscribersResponseV2 = {
data: [
{
id: '139872142007207563',
email: 'user@n8n.io',
status: 'junk',
source: 'api',
sent: 0,
opens_count: 0,
clicks_count: 0,
open_rate: 0,
click_rate: 0,
ip_address: null,
subscribed_at: '2024-12-05 09:54:29',
unsubscribed_at: null,
created_at: '2024-12-05 09:54:29',
updated_at: '2024-12-05 10:20:32',
fields: {
name: null,
last_name: null,
company: null,
country: null,
city: null,
phone: null,
state: null,
z_i_p: null,
},
opted_in_at: null,
optin_ip: '8.8.8.8',
},
{
id: '139059851540038710',
email: 'nathan@n8n.io',
status: 'junk',
source: 'api',
sent: 0,
opens_count: 0,
clicks_count: 0,
open_rate: 0,
click_rate: 0,
ip_address: null,
subscribed_at: null,
unsubscribed_at: null,
created_at: '2024-11-26 10:43:28',
updated_at: '2024-11-27 10:09:34',
fields: {
name: 'Nathan',
last_name: 'Workflow',
company: null,
country: null,
city: null,
phone: null,
state: null,
z_i_p: null,
},
opted_in_at: null,
optin_ip: null,
},
],
links: {
first: null,
last: null,
prev: null,
next: null,
},
meta: {
path: 'https://connect.mailerlite.com/api/subscribers',
per_page: 2,
next_cursor: null,
prev_cursor: null,
},
};
@@ -0,0 +1,460 @@
{
"name": "[TEST] MailerLite v1 Node",
"nodes": [
{
"parameters": {},
"id": "be5a39ea-04bf-49a3-969f-47d4a9496f08",
"name": "When clicking Execute workflow",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [-340, 280]
},
{
"parameters": {
"email": "demo@mailerlite.com",
"additionalFields": {}
},
"id": "98d30bbe-cbdd-4313-933e-804cdf322860",
"name": "Create Subscriber",
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 1,
"position": [-140, 40],
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [80, 40],
"id": "93aa764f-5101-4961-9b51-9fa92f746337",
"name": "No Operation, do nothing"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [80, 220],
"id": "4dccb059-c4f6-4eae-b68a-5c5c36d0b8d4",
"name": "No Operation, do nothing1"
},
{
"parameters": {
"operation": "get",
"subscriberId": "demo@mailerlite.com"
},
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 1,
"position": [-140, 220],
"id": "82115adf-edf4-4ce4-9109-3ade129294d1",
"name": "Get Subscriber",
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {
"operation": "update",
"subscriberId": "demo@mailerlite.com",
"updateFields": {
"type": "active"
}
},
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 1,
"position": [-140, 420],
"id": "fae9c6bd-1bd1-4ee8-865d-283b7edb6004",
"name": "Update Subscriber",
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [80, 420],
"id": "45937d69-3956-434d-b955-a67d77d43d57",
"name": "No Operation, do nothing2"
},
{
"parameters": {
"operation": "getAll",
"limit": 1,
"filters": {}
},
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 1,
"position": [-180, 680],
"id": "6491d933-0929-44bd-89cf-977823dde650",
"name": "Get Many Subscrbers",
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [40, 680],
"id": "6e35d6e1-1ce3-4410-8558-a5d573676d8a",
"name": "No Operation, do nothing3"
}
],
"pinData": {
"No Operation, do nothing": [
{
"json": {
"id": 1343965485,
"name": "John",
"email": "demo@mailerlite.com",
"sent": 0,
"opened": 0,
"clicked": 0,
"type": "active",
"fields": [
{
"key": "email",
"value": "demo@mailerlite.com",
"type": "TEXT"
},
{
"key": "name",
"value": "John",
"type": "TEXT"
},
{
"key": "last_name",
"value": "",
"type": "TEXT"
},
{
"key": "company",
"value": "MailerLite",
"type": "TEXT"
},
{
"key": "country",
"value": "",
"type": "TEXT"
},
{
"key": "city",
"value": "",
"type": "TEXT"
},
{
"key": "phone",
"value": "",
"type": "TEXT"
},
{
"key": "state",
"value": "",
"type": "TEXT"
},
{
"key": "zip",
"value": "",
"type": "TEXT"
}
],
"date_subscribe": null,
"date_unsubscribe": null,
"date_created": "2016-04-04 12:00:00",
"date_updated": "2016-04-04 12:00:00"
}
}
],
"No Operation, do nothing1": [
{
"json": {
"id": 1343965485,
"name": "John",
"email": "demo@mailerlite.com",
"sent": 0,
"opened": 0,
"clicked": 0,
"type": "active",
"signup_ip": "127.0.0.1",
"signup_timestamp": "2018-01-01 01:01:01",
"confirmation_ip": "127.0.0.2",
"confirmation_timestamp": "2018-01-01 01:01:02",
"fields": [
{
"key": "email",
"value": "demo@mailerlite.com",
"type": "TEXT"
},
{
"key": "name",
"value": "John",
"type": "TEXT"
},
{
"key": "last_name",
"value": "",
"type": "TEXT"
},
{
"key": "company",
"value": "",
"type": "TEXT"
},
{
"key": "country",
"value": "",
"type": "TEXT"
},
{
"key": "city",
"value": "",
"type": "TEXT"
},
{
"key": "phone",
"value": "",
"type": "TEXT"
},
{
"key": "state",
"value": "",
"type": "TEXT"
},
{
"key": "zip",
"value": "",
"type": "TEXT"
}
],
"date_subscribe": null,
"date_unsubscribe": null,
"date_created": "2016-04-04",
"date_updated": null
}
}
],
"No Operation, do nothing2": [
{
"json": {
"id": 1343965485,
"email": "demo@mailerlite.com",
"sent": 0,
"opened": 0,
"clicked": 0,
"type": "unsubscribed",
"fields": [
{
"key": "email",
"value": "demo@mailerlite.com",
"type": "TEXT"
},
{
"key": "name",
"value": "Demo",
"type": "TEXT"
},
{
"key": "last_name",
"value": "",
"type": "TEXT"
},
{
"key": "company",
"value": "",
"type": "TEXT"
},
{
"key": "country",
"value": "",
"type": "TEXT"
},
{
"key": "city",
"value": "",
"type": "TEXT"
},
{
"key": "phone",
"value": "",
"type": "TEXT"
},
{
"key": "state",
"value": "",
"type": "TEXT"
},
{
"key": "zip",
"value": "",
"type": "TEXT"
}
],
"date_subscribe": null,
"date_unsubscribe": "2016-04-04 12:07:26",
"date_created": "2016-04-04",
"date_updated": null
}
}
],
"No Operation, do nothing3": [
{
"json": {
"id": 1343965485,
"name": "John",
"email": "demo@mailerlite.com",
"sent": 0,
"opened": 0,
"clicked": 0,
"type": "active",
"fields": [
{
"key": "email",
"value": "demo@mailerlite.com",
"type": "TEXT"
},
{
"key": "name",
"value": "John",
"type": "TEXT"
},
{
"key": "last_name",
"value": "",
"type": "TEXT"
},
{
"key": "company",
"value": "",
"type": "TEXT"
},
{
"key": "country",
"value": "",
"type": "TEXT"
},
{
"key": "city",
"value": "",
"type": "TEXT"
},
{
"key": "phone",
"value": "",
"type": "TEXT"
},
{
"key": "state",
"value": "",
"type": "TEXT"
},
{
"key": "zip",
"value": "",
"type": "TEXT"
}
],
"date_subscribe": null,
"date_unsubscribe": null,
"date_created": "2016-04-04",
"date_updated": null
}
}
]
},
"connections": {
"When clicking Execute workflow": {
"main": [
[
{
"node": "Create Subscriber",
"type": "main",
"index": 0
},
{
"node": "Get Subscriber",
"type": "main",
"index": 0
},
{
"node": "Update Subscriber",
"type": "main",
"index": 0
},
{
"node": "Get Many Subscrbers",
"type": "main",
"index": 0
}
]
]
},
"Create Subscriber": {
"main": [
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"Get Subscriber": {
"main": [
[
{
"node": "No Operation, do nothing1",
"type": "main",
"index": 0
}
]
]
},
"Update Subscriber": {
"main": [
[
{
"node": "No Operation, do nothing2",
"type": "main",
"index": 0
}
]
]
},
"Get Many Subscrbers": {
"main": [
[
{
"node": "No Operation, do nothing3",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "826c1711-fcea-4564-809b-0258dbdd72f4",
"meta": {
"instanceId": "8c8c5237b8e37b006a7adce87f4369350c58e41f3ca9de16196d3197f69eabcd"
},
"id": "I0absgO5t7xV2f2V",
"tags": []
}
@@ -0,0 +1,24 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import {
getCreateResponseClassic,
getSubscriberResponseClassic,
getAllSubscribersResponseClassic,
getUpdateSubscriberResponseClassic,
} from '../apiResponses';
describe('MailerLite', () => {
describe('Run v1 workflow', () => {
beforeAll(() => {
const mock = nock('https://api.mailerlite.com/api/v2');
mock.post('/subscribers').reply(200, getCreateResponseClassic);
mock.get('/subscribers/demo@mailerlite.com').reply(200, getSubscriberResponseClassic);
mock.get('/subscribers').query({ limit: 1 }).reply(200, getAllSubscribersResponseClassic);
mock.put('/subscribers/demo@mailerlite.com').reply(200, getUpdateSubscriberResponseClassic);
});
new NodeTestHarness().setupTests();
});
});
@@ -0,0 +1,370 @@
{
"name": "[TEST] MailerLite v2 Node",
"nodes": [
{
"parameters": {},
"id": "3c72284b-2b88-4d5f-81bc-b1970b14f2af",
"name": "When clicking Execute workflow",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [800, 240]
},
{
"parameters": {
"email": "user@n8n.io",
"additionalFields": {
"status": "active"
}
},
"id": "702c6598-cbe8-403e-962e-56621ec727a4",
"name": "Create Subscriber",
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 2,
"position": [1000, 0],
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [1220, 0],
"id": "540b98b5-b3bf-49a1-a406-acc6872f4b50",
"name": "No Operation, do nothing"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [1220, 180],
"id": "17c0b8e7-a9d7-4a4f-882f-c3fb3f6bc289",
"name": "No Operation, do nothing1"
},
{
"parameters": {
"operation": "get",
"subscriberId": "user@n8n.io"
},
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 2,
"position": [1000, 180],
"id": "5598f2b9-4d67-4ad7-a8e4-7b7bf723cd5a",
"name": "Get Subscriber",
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {
"operation": "update",
"subscriberId": "user@n8n.io",
"additionalFields": {
"status": "junk",
"optin_ip": "8.8.8.8"
}
},
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 2,
"position": [1000, 380],
"id": "223e4507-c88e-4066-a122-ccaf9cea7b49",
"name": "Update Subscriber",
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [1220, 380],
"id": "94d04b52-8809-4670-a8ca-135921139fc9",
"name": "No Operation, do nothing2"
},
{
"parameters": {
"operation": "getAll",
"limit": 2,
"filters": {
"status": "junk"
}
},
"type": "n8n-nodes-base.mailerLite",
"typeVersion": 2,
"position": [960, 640],
"id": "30c6e797-ceda-4c84-8f34-b61200ffd9e9",
"name": "Get Many Subscrbers",
"credentials": {
"mailerLiteApi": {
"id": "bm7VHS2C7lRgVOhb",
"name": "Mailer Lite account"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [1180, 640],
"id": "c8529a30-889b-4ac9-a509-73f5dd8eef4a",
"name": "No Operation, do nothing3"
}
],
"pinData": {
"No Operation, do nothing": [
{
"json": {
"id": "139872142007207563",
"email": "user@n8n.io",
"status": "junk",
"source": "api",
"sent": 0,
"opens_count": 0,
"clicks_count": 0,
"open_rate": 0,
"click_rate": 0,
"ip_address": null,
"subscribed_at": "2024-12-05 09:54:29",
"unsubscribed_at": null,
"created_at": "2024-12-05 09:54:29",
"updated_at": "2024-12-05 10:20:32",
"fields": {
"name": null,
"last_name": null,
"company": null,
"country": null,
"city": null,
"phone": null,
"state": null,
"z_i_p": null
},
"groups": [],
"opted_in_at": null,
"optin_ip": "8.8.8.8"
}
}
],
"No Operation, do nothing1": [
{
"json": {
"id": "139872142007207563",
"email": "user@n8n.io",
"status": "junk",
"source": "api",
"sent": 0,
"opens_count": 0,
"clicks_count": 0,
"open_rate": 0,
"click_rate": 0,
"ip_address": null,
"subscribed_at": "2024-12-05 09:54:29",
"unsubscribed_at": null,
"created_at": "2024-12-05 09:54:29",
"updated_at": "2024-12-05 10:20:32",
"fields": {
"name": null,
"last_name": null,
"company": null,
"country": null,
"city": null,
"phone": null,
"state": null,
"z_i_p": null
},
"groups": [],
"opted_in_at": null,
"optin_ip": "8.8.8.8"
}
}
],
"No Operation, do nothing2": [
{
"json": {
"data": {
"id": "139872142007207563",
"email": "user@n8n.io",
"status": "junk",
"source": "api",
"sent": 0,
"opens_count": 0,
"clicks_count": 0,
"open_rate": 0,
"click_rate": 0,
"ip_address": null,
"subscribed_at": "2024-12-05 09:54:29",
"unsubscribed_at": null,
"created_at": "2024-12-05 09:54:29",
"updated_at": "2024-12-05 10:20:32",
"fields": {
"name": null,
"last_name": null,
"company": null,
"country": null,
"city": null,
"phone": null,
"state": null,
"z_i_p": null
},
"groups": [],
"opted_in_at": null,
"optin_ip": "8.8.8.8"
}
}
}
],
"No Operation, do nothing3": [
{
"json": {
"id": "139872142007207563",
"email": "user@n8n.io",
"status": "junk",
"source": "api",
"sent": 0,
"opens_count": 0,
"clicks_count": 0,
"open_rate": 0,
"click_rate": 0,
"ip_address": null,
"subscribed_at": "2024-12-05 09:54:29",
"unsubscribed_at": null,
"created_at": "2024-12-05 09:54:29",
"updated_at": "2024-12-05 10:20:32",
"fields": {
"name": null,
"last_name": null,
"company": null,
"country": null,
"city": null,
"phone": null,
"state": null,
"z_i_p": null
},
"opted_in_at": null,
"optin_ip": "8.8.8.8"
}
},
{
"json": {
"id": "139059851540038710",
"email": "nathan@n8n.io",
"status": "junk",
"source": "api",
"sent": 0,
"opens_count": 0,
"clicks_count": 0,
"open_rate": 0,
"click_rate": 0,
"ip_address": null,
"subscribed_at": null,
"unsubscribed_at": null,
"created_at": "2024-11-26 10:43:28",
"updated_at": "2024-11-27 10:09:34",
"fields": {
"name": "Nathan",
"last_name": "Workflow",
"company": null,
"country": null,
"city": null,
"phone": null,
"state": null,
"z_i_p": null
},
"opted_in_at": null,
"optin_ip": null
}
}
]
},
"connections": {
"When clicking Execute workflow": {
"main": [
[
{
"node": "Create Subscriber",
"type": "main",
"index": 0
},
{
"node": "Get Subscriber",
"type": "main",
"index": 0
},
{
"node": "Update Subscriber",
"type": "main",
"index": 0
},
{
"node": "Get Many Subscrbers",
"type": "main",
"index": 0
}
]
]
},
"Create Subscriber": {
"main": [
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"Get Subscriber": {
"main": [
[
{
"node": "No Operation, do nothing1",
"type": "main",
"index": 0
}
]
]
},
"Update Subscriber": {
"main": [
[
{
"node": "No Operation, do nothing2",
"type": "main",
"index": 0
}
]
]
},
"Get Many Subscrbers": {
"main": [
[
{
"node": "No Operation, do nothing3",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "338331ef-1b38-47dc-9e2b-45340ea3fe3b",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "8c8c5237b8e37b006a7adce87f4369350c58e41f3ca9de16196d3197f69eabcd"
},
"id": "0Ov6Vd62DUXrWWQH",
"tags": []
}
@@ -0,0 +1,27 @@
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import nock from 'nock';
import {
getCreateResponseV2,
getSubscriberResponseV2,
getAllSubscribersResponseV2,
getUpdateSubscriberResponseV2,
} from '../apiResponses';
describe('MailerLite', () => {
describe('Run v2 workflow', () => {
beforeAll(() => {
const mock = nock('https://connect.mailerlite.com/api');
mock.post('/subscribers').reply(200, getCreateResponseV2);
mock.get('/subscribers/user@n8n.io').reply(200, getSubscriberResponseV2);
mock
.get('/subscribers')
.query({ 'filter[status]': 'junk', limit: 2 })
.reply(200, getAllSubscribersResponseV2);
mock.put('/subscribers/user@n8n.io').reply(200, getUpdateSubscriberResponseV2);
});
new NodeTestHarness().setupTests();
});
});