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,105 @@
import { mockDeep } from 'jest-mock-extended';
import type { IExecuteFunctions } from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow';
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
import { Xml } from '../../Xml.node';
describe('Test XML Node', () => {
new NodeTestHarness().setupTests();
});
describe('Xml Node - options validation', () => {
const FORBIDDEN_KEYS = ['__proto__', 'constructor', 'prototype'];
let xmlNode: Xml;
let mockExecuteFunctions: ReturnType<typeof mockDeep<IExecuteFunctions>>;
beforeEach(() => {
xmlNode = new Xml();
mockExecuteFunctions = mockDeep<IExecuteFunctions>();
mockExecuteFunctions.getNode.mockReturnValue({
id: 'xml-node',
name: 'XML',
type: 'n8n-nodes-base.xml',
typeVersion: 1,
position: [0, 0],
parameters: {},
});
mockExecuteFunctions.getInputData.mockReturnValue([
{ json: { data: '<root foo="bar">x</root>' } },
]);
});
const setupGetNodeParameter = (mode: string, options: Record<string, unknown>) => {
mockExecuteFunctions.getNodeParameter.mockImplementation(
(parameterName: string, _itemIndex: number, fallbackValue?: unknown) => {
if (parameterName === 'mode') return mode;
if (parameterName === 'dataPropertyName') return 'data';
if (parameterName === 'options') return options;
return fallbackValue as object;
},
);
};
describe('attrkey validation', () => {
test.each(FORBIDDEN_KEYS)(
'should reject invalid attrkey "%s" in xmlToJson mode',
async (forbiddenKey) => {
setupGetNodeParameter('xmlToJson', { attrkey: forbiddenKey, mergeAttrs: false });
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
`The "Attribute Key" option value "${forbiddenKey}" is not allowed`,
);
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
NodeOperationError,
);
},
);
test.each(FORBIDDEN_KEYS)(
'should reject invalid attrkey "%s" in jsonToxml mode',
async (forbiddenKey) => {
setupGetNodeParameter('jsonToxml', { attrkey: forbiddenKey });
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
`The "Attribute Key" option value "${forbiddenKey}" is not allowed`,
);
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
NodeOperationError,
);
},
);
});
describe('charkey validation', () => {
test.each(FORBIDDEN_KEYS)(
'should reject invalid charkey "%s" in xmlToJson mode',
async (forbiddenKey) => {
setupGetNodeParameter('xmlToJson', { charkey: forbiddenKey });
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
`The "Character Key" option value "${forbiddenKey}" is not allowed`,
);
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
NodeOperationError,
);
},
);
test.each(FORBIDDEN_KEYS)(
'should reject invalid charkey "%s" in jsonToxml mode',
async (forbiddenKey) => {
setupGetNodeParameter('jsonToxml', { charkey: forbiddenKey });
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
`The "Character Key" option value "${forbiddenKey}" is not allowed`,
);
await expect(xmlNode.execute.call(mockExecuteFunctions)).rejects.toThrow(
NodeOperationError,
);
},
);
});
});
@@ -0,0 +1,142 @@
{
"name": "My workflow",
"nodes": [
{
"parameters": {},
"id": "7f04c09e-5a60-4a0c-a336-ef38e4732452",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [860, 380]
},
{
"parameters": {
"data": [
{
"a": {
"b": {
"c": 1
}
}
}
]
},
"id": "be80ce82-d312-460d-ac79-05c0626845ad",
"name": "Code",
"type": "n8n-nodes-testing.testData",
"typeVersion": 1,
"position": [1080, 380]
},
{
"parameters": {
"mode": "jsonToxml",
"options": {}
},
"id": "c352655b-e0dc-4f7c-a63a-ff1bc5f1909f",
"name": "XML",
"type": "n8n-nodes-base.xml",
"typeVersion": 1,
"position": [1300, 380]
},
{
"parameters": {
"options": {}
},
"id": "21547e44-133e-4c3b-a601-0cffba1daf9b",
"name": "XML1",
"type": "n8n-nodes-base.xml",
"typeVersion": 1,
"position": [1500, 380]
},
{
"parameters": {
"values": {
"string": [
{
"name": "new",
"value": "={{ $json.a }}"
}
]
},
"options": {}
},
"id": "632dee22-10d1-424d-b1d2-673b95b32943",
"name": "Set",
"type": "n8n-nodes-base.set",
"typeVersion": 2,
"position": [1720, 380]
}
],
"pinData": {
"Set": [
{
"json": {
"a": {
"b": {
"c": "1"
}
},
"new": {
"b": {
"c": "1"
}
}
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "XML",
"type": "main",
"index": 0
}
]
]
},
"XML": {
"main": [
[
{
"node": "XML1",
"type": "main",
"index": 0
}
]
]
},
"XML1": {
"main": [
[
{
"node": "Set",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"versionId": "14c1d4b8-3546-4692-8e8a-44c244c79bcc",
"id": "0G78Fh2FTnM46kuR",
"meta": {
"instanceId": "021d3c82ba2d3bc090cbf4fc81c9312668bcc34297e022bb3438c5c88a43a5ff"
},
"tags": []
}
@@ -0,0 +1,157 @@
{
"name": "xml tests",
"nodes": [
{
"parameters": {},
"id": "745d1191-f221-4eda-9d09-611233f97edd",
"name": "When clicking \"Execute Workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [460, 520]
},
{
"parameters": {
"mode": "jsonToxml",
"options": {}
},
"id": "fb48ca4c-5ae2-4c57-9ca9-2080d06dbf65",
"name": "XML",
"type": "n8n-nodes-base.xml",
"typeVersion": 1,
"position": [960, 280]
},
{
"parameters": {
"data": {
"data": {
"id": 1,
"firstName": "Adam",
"secondName": "Smith",
"fullName": "Adam Smith"
}
}
},
"id": "6a04ca32-c9cc-4cb1-a6b9-3a505b1c2dd5",
"name": "Code",
"type": "n8n-nodes-testing.testData",
"typeVersion": 1,
"position": [700, 400]
},
{
"parameters": {
"mode": "jsonToxml",
"options": {
"headless": true
}
},
"id": "cd740e65-5117-4bec-a3b3-6863ba25f232",
"name": "XML1",
"type": "n8n-nodes-base.xml",
"typeVersion": 1,
"position": [960, 500]
},
{
"parameters": {
"data": {
"data": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?> <data> <id>1</id> <firstName>Adam</firstName> <secondName>Smith</secondName> <fullName>Adam Smith</fullName> </data>"
}
},
"id": "817afbf7-9342-403f-8dc0-c4a3905fde4d",
"name": "Code1",
"type": "n8n-nodes-testing.testData",
"typeVersion": 1,
"position": [680, 640]
},
{
"parameters": {
"options": {}
},
"id": "f0f37a8f-9136-42e8-be34-f32b77e4aa88",
"name": "XML2",
"type": "n8n-nodes-base.xml",
"typeVersion": 1,
"position": [940, 700]
}
],
"pinData": {
"XML": [
{
"json": {
"data": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<data>\n <id>1</id>\n <firstName>Adam</firstName>\n <secondName>Smith</secondName>\n <fullName>Adam Smith</fullName>\n</data>"
}
}
],
"XML1": [
{
"json": {
"data": "<data>\n <id>1</id>\n <firstName>Adam</firstName>\n <secondName>Smith</secondName>\n <fullName>Adam Smith</fullName>\n</data>"
}
}
],
"XML2": [
{
"json": {
"data": {
"id": "1",
"firstName": "Adam",
"secondName": "Smith",
"fullName": "Adam Smith"
}
}
}
]
},
"connections": {
"When clicking \"Execute Workflow\"": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
},
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "XML",
"type": "main",
"index": 0
},
{
"node": "XML1",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "XML2",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"versionId": "c1fde9d5-f27c-4e62-bc5c-8be787dcc227",
"id": "109",
"meta": {
"instanceId": "36203ea1ce3cef713fa25999bd9874ae26b9e4c2c3a90a365f2882a154d031d0"
},
"tags": []
}