Files
n8n-enterprise-unlocked/packages/editor-ui/src/utils/__tests__/mappingUtils.test.ts

258 lines
7.3 KiB
TypeScript

import { INodeProperties } from 'n8n-workflow';
import { getMappedResult, getMappedExpression } from '../mappingUtils';
const RLC_PARAM: INodeProperties = {
displayName: 'Base',
name: 'application',
type: 'resourceLocator',
default: {
mode: 'url',
value: '',
},
required: true,
description: 'The Airtable Base in which to operate on',
modes: [
{
displayName: 'ID',
name: 'id',
type: 'string',
validation: [
{
type: 'regex',
properties: {
regex: '[a-zA-Z0-9]{2,}',
errorMessage: 'Not a valid Airtable Base ID',
},
},
],
placeholder: 'appD3dfaeidke',
url: '=https://airtable.com/{{$value}}',
},
],
};
const STRING_PARAM: INodeProperties = {
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'The string value to write in the property',
};
const SINGLE_DATA_PATH_PARAM: INodeProperties = {
displayName: 'Name',
name: 'name',
type: 'string',
default: 'propertyName',
requiresDataPath: 'single',
description:
'Name of the property to write data to. Supports dot-notation. Example: "data.person[0].name"',
};
const MULTIPLE_DATA_PATH_PARAM: INodeProperties = {
displayName: 'For Everything Except',
name: 'exceptWhenMix',
type: 'string',
default: '',
placeholder: 'e.g. id, country',
hint: 'Enter the names of the input fields as text, separated by commas',
displayOptions: {
show: {
resolve: ['mix'],
},
},
requiresDataPath: 'multiple',
};
const JSON_PARAM: INodeProperties = {
displayName: 'JSON Payload',
name: 'payloadJson',
type: 'json',
typeOptions: {
alwaysOpenEditWindow: true,
editor: 'code',
},
default: '',
};
const BOOLEAN_PARAM: INodeProperties = {
displayName: 'Value',
name: 'value',
type: 'boolean',
default: false,
description: 'The boolean value to write in the property',
};
const NUMBER_PARAM: INodeProperties = {
displayName: 'Value',
name: 'value',
type: 'number',
default: 0,
description: 'The number value to write in the property',
};
describe('Mapping Utils', () => {
describe('getMappedResult', () => {
it('turns empty string into expression', () => {
expect(getMappedResult(STRING_PARAM, '{{ $json["Readable date"] }}', '')).toEqual(
'={{ $json["Readable date"] }}',
);
});
it('keeps spaces when mapping data to fixed value', () => {
expect(getMappedResult(STRING_PARAM, '{{ $json["Readable date"] }}', ' ')).toEqual(
'= {{ $json["Readable date"] }}',
);
});
it('sets expression when mapping to an empty expression', () => {
expect(getMappedResult(STRING_PARAM, '{{ $json["Readable date"] }}', '=')).toEqual(
'={{ $json["Readable date"] }}',
);
});
it('keeps spaces when mapping data to expression value', () => {
expect(getMappedResult(STRING_PARAM, '{{ $json["Readable date"] }}', '= ')).toEqual(
'= {{ $json["Readable date"] }}',
);
});
it('appends to string fixed value and turns into expression', () => {
expect(getMappedResult(STRING_PARAM, '{{ $json["Readable date"] }}', 'test')).toEqual(
'=test {{ $json["Readable date"] }}',
);
});
it('appends to json fixed value', () => {
expect(getMappedResult(JSON_PARAM, '{{ $json["Readable date"] }}', 'test')).toEqual(
'=test {{ $json["Readable date"] }}',
);
});
it('replaces number value with expression', () => {
expect(getMappedResult(NUMBER_PARAM, '{{ $json["Readable date"] }}', 0)).toEqual(
'={{ $json["Readable date"] }}',
);
});
it('replaces boolean value with expression', () => {
expect(getMappedResult(BOOLEAN_PARAM, '{{ $json["Readable date"] }}', false)).toEqual(
'={{ $json["Readable date"] }}',
);
});
it('appends existing expression value', () => {
expect(
getMappedResult(STRING_PARAM, '{{ $json["Readable date"] }}', '={{$json.test}}'),
).toEqual('={{$json.test}} {{ $json["Readable date"] }}');
});
it('sets data path, replacing if expecting single path', () => {
expect(
getMappedResult(SINGLE_DATA_PATH_PARAM, '{{ $json["Readable date"] }}', '={{$json.test}}'),
).toEqual('["Readable date"]');
expect(
getMappedResult(SINGLE_DATA_PATH_PARAM, '{{ $json.path }}', '={{$json.test}}'),
).toEqual('path');
});
it('appends to existing data path, if multiple', () => {
expect(
getMappedResult(MULTIPLE_DATA_PATH_PARAM, '{{ $json["Readable date"] }}', 'path'),
).toEqual('path, ["Readable date"]');
});
it('replaces existing dadata path if multiple and is empty expression', () => {
expect(getMappedResult(MULTIPLE_DATA_PATH_PARAM, '{{ $json.test }}', '=')).toEqual('test');
});
it('handles data when dragging from grand-parent nodes', () => {
expect(
getMappedResult(
MULTIPLE_DATA_PATH_PARAM,
'{{ $node["Schedule Trigger"].json["Day of week"] }}',
'',
),
).toEqual('={{ $node["Schedule Trigger"].json["Day of week"] }}');
expect(
getMappedResult(
SINGLE_DATA_PATH_PARAM,
'{{ $node["Schedule Trigger"].json["Day of week"] }}',
'=data',
),
).toEqual('=data {{ $node["Schedule Trigger"].json["Day of week"] }}');
expect(
getMappedResult(
SINGLE_DATA_PATH_PARAM,
'{{ $node["Schedule Trigger"].json["Day of week"] }}',
'= ',
),
).toEqual('= {{ $node["Schedule Trigger"].json["Day of week"] }}');
});
it('handles RLC values', () => {
expect(getMappedResult(RLC_PARAM, '{{ test }}', '')).toEqual('={{ test }}');
expect(getMappedResult(RLC_PARAM, '{{ test }}', '=')).toEqual('={{ test }}');
expect(getMappedResult(RLC_PARAM, '{{ test }}', '=test')).toEqual('=test {{ test }}');
});
});
describe('getMappedExpression', () => {
it('should generate a mapped expression with simple array path', () => {
const input = {
nodeName: 'nodeName',
distanceFromActive: 2,
path: ['sample', 'path'],
};
const result = getMappedExpression(input);
expect(result).toBe('{{ $node.nodeName.json.sample.path }}');
});
it('should generate a mapped expression with mixed array path', () => {
const input = {
nodeName: 'nodeName',
distanceFromActive: 2,
path: ['sample', 0, 'path'],
};
const result = getMappedExpression(input);
expect(result).toBe('{{ $node.nodeName.json.sample[0].path }}');
});
it('should generate a mapped expression with special characters in array path', () => {
const input = {
nodeName: 'nodeName',
distanceFromActive: 2,
path: ['sample', 'path with-space', 'path-with-hyphen'],
};
const result = getMappedExpression(input);
expect(result).toBe(
'{{ $node.nodeName.json.sample["path with-space"]["path-with-hyphen"] }}',
);
});
it('should generate a mapped expression with various path elements', () => {
const input = {
nodeName: 'nodeName',
distanceFromActive: 1,
path: ['propertyName', 'capitalizedName', 'hyphen-prop'],
};
const result = getMappedExpression(input);
expect(result).toBe('{{ $json.propertyName.capitalizedName["hyphen-prop"] }}');
});
it('should generate a mapped expression with a complex path', () => {
const input = {
nodeName: 'nodeName',
distanceFromActive: 1,
path: ['propertyName', 'capitalizedName', 'stringVal', 'some-value', 'capitalizedProp'],
};
const result = getMappedExpression(input);
expect(result).toBe(
'{{ $json.propertyName.capitalizedName.stringVal["some-value"].capitalizedProp }}',
);
});
});
});