n8n/packages/core/test/WorkflowExecutionMetadata.test.ts
Iván Ovejero dff8456382
refactor(core): Reorganize error hierarchy in core and workflow packages (no-changelog) (#7820)
Ensure all errors in `core` and `workflow` inherit from
`ApplicationError` so that we start normalizing all the errors we report
to Sentry

Follow-up to:
https://github.com/n8n-io/n8n/pull/7757#discussion_r1404338844

### `core` package

`ApplicationError`
- `FileSystemError` (abstract)
	- `FileNotFoundError`
	- `DisallowedFilepathError`
- `BinaryDataError` (abstract)
	- `InvalidModeError`
	- `InvalidManagerError`
- `InvalidExecutionMetadataError`

### `workflow` package

`ApplicationError`
- `ExecutionBaseError` (abstract)
	- `WorkflowActivationError`
		- `WorkflowDeactivationError`
		- `WebhookTakenError`
	- `WorkflowOperationError`
		- `SubworkflowOperationError`
			- `CliWorkflowOperationError`
	- `ExpressionError`
		- `ExpressionExtensionError`
	- `NodeError` (abstract)
		- `NodeOperationError`
		- `NodeApiError`
	- `NodeSSLError`

Up next:
- Reorganize errors in `cli`
- Flatten the hierarchy in `workflow` (do we really need
`ExecutionBaseError`?)
- Remove `ExecutionError` type
- Stop throwing plain `Error`s
- Replace `severity` with `level`
- Add node and credential types as `tags`
- Add workflow IDs and execution IDs as `extras`
2023-11-27 15:33:21 +01:00

218 lines
5.6 KiB
TypeScript

import {
setWorkflowExecutionMetadata,
setAllWorkflowExecutionMetadata,
KV_LIMIT,
getWorkflowExecutionMetadata,
getAllWorkflowExecutionMetadata,
} from '@/ExecutionMetadata';
import { InvalidExecutionMetadataError } from '@/errors/invalid-execution-metadata.error';
import type { IRunExecutionData } from 'n8n-workflow';
describe('Execution Metadata functions', () => {
test('setWorkflowExecutionMetadata will set a value', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
setWorkflowExecutionMetadata(executionData, 'test1', 'value1');
expect(metadata).toEqual({
test1: 'value1',
});
});
test('setAllWorkflowExecutionMetadata will set multiple values', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
setAllWorkflowExecutionMetadata(executionData, {
test1: 'value1',
test2: 'value2',
});
expect(metadata).toEqual({
test1: 'value1',
test2: 'value2',
});
});
test('setWorkflowExecutionMetadata should only convert numbers to strings', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
expect(() => setWorkflowExecutionMetadata(executionData, 'test1', 1234)).not.toThrow(
InvalidExecutionMetadataError,
);
expect(metadata).toEqual({
test1: '1234',
});
expect(() => setWorkflowExecutionMetadata(executionData, 'test2', {})).toThrow(
InvalidExecutionMetadataError,
);
expect(metadata).not.toEqual({
test1: '1234',
test2: {},
});
});
test('setAllWorkflowExecutionMetadata should not convert values to strings and should set other values correctly', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
expect(() =>
setAllWorkflowExecutionMetadata(executionData, {
test1: {} as unknown as string,
test2: [] as unknown as string,
test3: 'value3',
test4: 'value4',
}),
).toThrow(InvalidExecutionMetadataError);
expect(metadata).toEqual({
test3: 'value3',
test4: 'value4',
});
});
test('setWorkflowExecutionMetadata should validate key characters', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
expect(() => setWorkflowExecutionMetadata(executionData, 'te$t1$', 1234)).toThrow(
InvalidExecutionMetadataError,
);
expect(metadata).not.toEqual({
test1: '1234',
});
});
test('setWorkflowExecutionMetadata should limit the number of metadata entries', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
const expected: Record<string, string> = {};
for (let i = 0; i < KV_LIMIT; i++) {
expected[`test${i + 1}`] = `value${i + 1}`;
}
for (let i = 0; i < KV_LIMIT + 10; i++) {
setWorkflowExecutionMetadata(executionData, `test${i + 1}`, `value${i + 1}`);
}
expect(metadata).toEqual(expected);
});
test('getWorkflowExecutionMetadata should return a single value for an existing key', () => {
const metadata: Record<string, string> = { test1: 'value1' };
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
expect(getWorkflowExecutionMetadata(executionData, 'test1')).toBe('value1');
});
test('getWorkflowExecutionMetadata should return undefined for an unset key', () => {
const metadata: Record<string, string> = { test1: 'value1' };
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
expect(getWorkflowExecutionMetadata(executionData, 'test2')).toBeUndefined();
});
test('getAllWorkflowExecutionMetadata should return all metadata', () => {
const metadata: Record<string, string> = { test1: 'value1', test2: 'value2' };
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
expect(getAllWorkflowExecutionMetadata(executionData)).toEqual(metadata);
});
test('getAllWorkflowExecutionMetadata should not an object that modifies internal state', () => {
const metadata: Record<string, string> = { test1: 'value1', test2: 'value2' };
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
getAllWorkflowExecutionMetadata(executionData).test1 = 'changed';
expect(metadata.test1).not.toBe('changed');
expect(metadata.test1).toBe('value1');
});
test('setWorkflowExecutionMetadata should truncate long keys', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
setWorkflowExecutionMetadata(
executionData,
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab',
'value1',
);
expect(metadata).toEqual({
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: 'value1',
});
});
test('setWorkflowExecutionMetadata should truncate long values', () => {
const metadata = {};
const executionData = {
resultData: {
metadata,
},
} as IRunExecutionData;
setWorkflowExecutionMetadata(
executionData,
'test1',
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab',
);
expect(metadata).toEqual({
test1:
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
});
});
});