Skip to content

Commit

Permalink
fix(core): Fix validation of items returned in the task runner (#11897)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomi authored Nov 26, 2024
1 parent 30c6d96 commit a535e88
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { ValidationError } from '@/js-task-runner/errors/validation-error';
import {
validateRunForAllItemsOutput,
validateRunForEachItemOutput,
} from '@/js-task-runner/result-validation';

describe('result validation', () => {
describe('validateRunForAllItemsOutput', () => {
it('should throw an error if the output is not an object', () => {
expect(() => {
validateRunForAllItemsOutput(undefined);
}).toThrowError(ValidationError);
});

it('should throw an error if the output is an array and at least one item has a non-n8n key', () => {
expect(() => {
validateRunForAllItemsOutput([{ json: {} }, { json: {}, unknownKey: {} }]);
}).toThrowError(ValidationError);
});

it('should not throw an error if the output is an array and all items are json wrapped', () => {
expect(() => {
validateRunForAllItemsOutput([{ json: {} }, { json: {} }, { json: {} }]);
}).not.toThrow();
});

test.each([
['binary', {}],
['pairedItem', {}],
['error', {}],
])(
'should not throw an error if the output item has %s key in addition to json',
(key, value) => {
expect(() => {
validateRunForAllItemsOutput([{ json: {} }, { json: {}, [key]: value }]);
}).not.toThrow();
},
);

it('should not throw an error if the output is an array and all items are not json wrapped', () => {
expect(() => {
validateRunForAllItemsOutput([
{
id: 1,
name: 'test3',
},
{
id: 2,
name: 'test4',
},
{
id: 3,
name: 'test5',
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
] as any);
}).not.toThrow();
});

it('should throw if json is not an object', () => {
expect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
validateRunForAllItemsOutput([{ json: 1 } as any]);
}).toThrowError(ValidationError);
});
});

describe('validateRunForEachItemOutput', () => {
const index = 0;

it('should throw an error if the output is not an object', () => {
expect(() => {
validateRunForEachItemOutput(undefined, index);
}).toThrowError(ValidationError);
});

it('should throw an error if the output is an array', () => {
expect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
validateRunForEachItemOutput([] as any, index);
}).toThrowError(ValidationError);
});

it('should throw if json is not an object', () => {
expect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
validateRunForEachItemOutput({ json: 1 } as any, index);
}).toThrowError(ValidationError);
});

it('should throw an error if the output is an array and at least one item has a non-n8n key', () => {
expect(() => {
validateRunForEachItemOutput({ json: {}, unknownKey: {} }, index);
}).toThrowError(ValidationError);
});

test.each([
['binary', {}],
['pairedItem', {}],
['error', {}],
])(
'should not throw an error if the output item has %s key in addition to json',
(key, value) => {
expect(() => {
validateRunForEachItemOutput({ json: {}, [key]: value }, index);
}).not.toThrow();
},
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const REQUIRED_N8N_ITEM_KEYS = new Set(['json', 'binary', 'pairedItem', '
function validateTopLevelKeys(item: INodeExecutionData, itemIndex: number) {
for (const key in item) {
if (Object.prototype.hasOwnProperty.call(item, key)) {
if (REQUIRED_N8N_ITEM_KEYS.has(key)) return;
if (REQUIRED_N8N_ITEM_KEYS.has(key)) continue;

throw new ValidationError({
message: `Unknown top-level item key: ${key}`,
Expand Down

0 comments on commit a535e88

Please sign in to comment.