Files
n8n-enterprise-unlocked/packages/editor-ui/src/composables/__tests__/useDataSchema.test.ts

528 lines
12 KiB
TypeScript

import jp from 'jsonpath';
import { useDataSchema } from '@/composables/useDataSchema';
import type { Schema } from '@/Interface';
describe('useDataSchema', () => {
const getSchema = useDataSchema().getSchema;
describe('getSchema', () => {
test.each([
[, { type: 'undefined', value: 'undefined', path: '' }],
[undefined, { type: 'undefined', value: 'undefined', path: '' }],
[null, { type: 'null', value: '[null]', path: '' }],
['John', { type: 'string', value: 'John', path: '' }],
['123', { type: 'string', value: '123', path: '' }],
[123, { type: 'number', value: '123', path: '' }],
[true, { type: 'boolean', value: 'true', path: '' }],
[false, { type: 'boolean', value: 'false', path: '' }],
[() => {}, { type: 'function', value: '', path: '' }],
[{}, { type: 'object', value: [], path: '' }],
[[], { type: 'array', value: [], path: '' }],
[
new Date('2022-11-22T00:00:00.000Z'),
{ type: 'string', value: '2022-11-22T00:00:00.000Z', path: '' },
],
[Symbol('x'), { type: 'symbol', value: 'Symbol(x)', path: '' }],
[1n, { type: 'bigint', value: '1', path: '' }],
[
['John', 1, true],
{
type: 'array',
value: [
{ type: 'string', value: 'John', key: '0', path: '[0]' },
{ type: 'number', value: '1', key: '1', path: '[1]' },
{ type: 'boolean', value: 'true', key: '2', path: '[2]' },
],
path: '',
},
],
[
{ people: ['Joe', 'John'] },
{
type: 'object',
value: [
{
type: 'array',
key: 'people',
value: [
{ type: 'string', value: 'Joe', key: '0', path: '.people[0]' },
{ type: 'string', value: 'John', key: '1', path: '.people[1]' },
],
path: '.people',
},
],
path: '',
},
],
[
{ 'with space': [], 'with.dot': 'test' },
{
type: 'object',
value: [
{
type: 'array',
key: 'with space',
value: [],
path: "['with space']",
},
{
type: 'string',
key: 'with.dot',
value: 'test',
path: "['with.dot']",
},
],
path: '',
},
],
[
[
{ name: 'John', age: 22 },
{ name: 'Joe', age: 33 },
],
{
type: 'array',
value: [
{
type: 'object',
key: '0',
value: [
{ type: 'string', key: 'name', value: 'John', path: '[0].name' },
{ type: 'number', key: 'age', value: '22', path: '[0].age' },
],
path: '[0]',
},
{
type: 'object',
key: '1',
value: [
{ type: 'string', key: 'name', value: 'Joe', path: '[1].name' },
{ type: 'number', key: 'age', value: '33', path: '[1].age' },
],
path: '[1]',
},
],
path: '',
},
],
[
[
{ name: 'John', age: 22, hobbies: ['surfing', 'traveling'] },
{ name: 'Joe', age: 33, hobbies: ['skateboarding', 'gaming'] },
],
{
type: 'array',
value: [
{
type: 'object',
key: '0',
value: [
{ type: 'string', key: 'name', value: 'John', path: '[0].name' },
{ type: 'number', key: 'age', value: '22', path: '[0].age' },
{
type: 'array',
key: 'hobbies',
value: [
{ type: 'string', key: '0', value: 'surfing', path: '[0].hobbies[0]' },
{ type: 'string', key: '1', value: 'traveling', path: '[0].hobbies[1]' },
],
path: '[0].hobbies',
},
],
path: '[0]',
},
{
type: 'object',
key: '1',
value: [
{ type: 'string', key: 'name', value: 'Joe', path: '[1].name' },
{ type: 'number', key: 'age', value: '33', path: '[1].age' },
{
type: 'array',
key: 'hobbies',
value: [
{ type: 'string', key: '0', value: 'skateboarding', path: '[1].hobbies[0]' },
{ type: 'string', key: '1', value: 'gaming', path: '[1].hobbies[1]' },
],
path: '[1].hobbies',
},
],
path: '[1]',
},
],
path: '',
},
],
[[], { type: 'array', value: [], path: '' }],
[
[[1, 2]],
{
type: 'array',
value: [
{
type: 'array',
key: '0',
value: [
{ type: 'number', key: '0', value: '1', path: '[0][0]' },
{ type: 'number', key: '1', value: '2', path: '[0][1]' },
],
path: '[0]',
},
],
path: '',
},
],
[
[
[
{ name: 'John', age: 22 },
{ name: 'Joe', age: 33 },
],
],
{
type: 'array',
value: [
{
type: 'array',
key: '0',
value: [
{
type: 'object',
key: '0',
value: [
{ type: 'string', key: 'name', value: 'John', path: '[0][0].name' },
{ type: 'number', key: 'age', value: '22', path: '[0][0].age' },
],
path: '[0][0]',
},
{
type: 'object',
key: '1',
value: [
{ type: 'string', key: 'name', value: 'Joe', path: '[0][1].name' },
{ type: 'number', key: 'age', value: '33', path: '[0][1].age' },
],
path: '[0][1]',
},
],
path: '[0]',
},
],
path: '',
},
],
[
[
{
dates: [
[new Date('2022-11-22T00:00:00.000Z'), new Date('2022-11-23T00:00:00.000Z')],
[new Date('2022-12-22T00:00:00.000Z'), new Date('2022-12-23T00:00:00.000Z')],
],
},
],
{
type: 'array',
value: [
{
type: 'object',
key: '0',
value: [
{
type: 'array',
key: 'dates',
value: [
{
type: 'array',
key: '0',
value: [
{
type: 'string',
key: '0',
value: '2022-11-22T00:00:00.000Z',
path: '[0].dates[0][0]',
},
{
type: 'string',
key: '1',
value: '2022-11-23T00:00:00.000Z',
path: '[0].dates[0][1]',
},
],
path: '[0].dates[0]',
},
{
type: 'array',
key: '1',
value: [
{
type: 'string',
key: '0',
value: '2022-12-22T00:00:00.000Z',
path: '[0].dates[1][0]',
},
{
type: 'string',
key: '1',
value: '2022-12-23T00:00:00.000Z',
path: '[0].dates[1][1]',
},
],
path: '[0].dates[1]',
},
],
path: '[0].dates',
},
],
path: '[0]',
},
],
path: '',
},
],
])('should return the correct json schema for %s', (input, schema) => {
expect(getSchema(input)).toEqual(schema);
});
it('should return the correct data when using the generated json path on an object', () => {
const input = { people: ['Joe', 'John'] };
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${((schema.value as Schema[])[0].value as Schema[])[0].path}`,
);
expect(pathData).toEqual(['Joe']);
});
it('should return the correct data when using the generated json path on a list', () => {
const input = [
{ name: 'John', age: 22, hobbies: ['surfing', 'traveling'] },
{ name: 'Joe', age: 33, hobbies: ['skateboarding', 'gaming'] },
];
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${(((schema.value as Schema[])[0].value as Schema[])[2].value as Schema[])[1].path}`,
);
expect(pathData).toEqual(['traveling']);
});
it('should return the correct data when using the generated json path on a list of list', () => {
const input = [[1, 2]];
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${((schema.value as Schema[])[0].value as Schema[])[1].path}`,
);
expect(pathData).toEqual([2]);
});
it('should return the correct data when using the generated json path on a list of list of objects', () => {
const input = [
[
{ name: 'John', age: 22 },
{ name: 'Joe', age: 33 },
],
];
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${(((schema.value as Schema[])[0].value as Schema[])[1].value as Schema[])[1].path}`,
);
expect(pathData).toEqual([33]);
});
it('should return the correct data when using the generated json path on a list of objects with a list of date tuples', () => {
const input = [
{
dates: [
[new Date('2022-11-22T00:00:00.000Z'), new Date('2022-11-23T00:00:00.000Z')],
[new Date('2022-12-22T00:00:00.000Z'), new Date('2022-12-23T00:00:00.000Z')],
],
},
];
const schema = getSchema(input);
const pathData = jp.query(
input,
`$${
(
(((schema.value as Schema[])[0].value as Schema[])[0].value as Schema[])[0]
.value as Schema[]
)[0].path
}`,
);
expect(pathData).toEqual([new Date('2022-11-22T00:00:00.000Z')]);
});
});
describe('filterSchema', () => {
const filterSchema = useDataSchema().filterSchema;
it('should correctly filter a flat schema', () => {
const flatSchema: Schema = {
type: 'object',
value: [
{
key: 'name',
type: 'string',
value: 'First item',
path: '.name',
},
{
key: 'code',
type: 'number',
value: '1',
path: '.code',
},
{
key: 'email',
type: 'string',
value: 'first item@gmail.com',
path: '.email',
},
],
path: '',
};
expect(filterSchema(flatSchema, 'mail')).toEqual({
path: '',
type: 'object',
value: [
{
key: 'email',
path: '.email',
type: 'string',
value: 'first item@gmail.com',
},
],
});
expect(filterSchema(flatSchema, '1')).toEqual({
path: '',
type: 'object',
value: [
{
key: 'code',
path: '.code',
type: 'number',
value: '1',
},
],
});
expect(filterSchema(flatSchema, 'no match')).toEqual(null);
});
it('should correctly filter a nested schema', () => {
const nestedSchema: Schema = {
type: 'object',
value: [
{
key: 'name',
type: 'string',
value: 'First item',
path: '.name',
},
{
key: 'code',
type: 'number',
value: '1',
path: '.code',
},
{
key: 'email',
type: 'string',
value: 'first item@gmail.com',
path: '.email',
},
{
key: 'obj',
type: 'object',
value: [
{
key: 'foo',
type: 'object',
value: [
{
key: 'nested',
type: 'string',
value: 'bar',
path: '.obj.foo.nested',
},
],
path: '.obj.foo',
},
],
path: '.obj',
},
],
path: '',
};
expect(filterSchema(nestedSchema, 'bar')).toEqual({
path: '',
type: 'object',
value: [
{
key: 'obj',
path: '.obj',
type: 'object',
value: [
{
key: 'foo',
path: '.obj.foo',
type: 'object',
value: [
{
key: 'nested',
path: '.obj.foo.nested',
type: 'string',
value: 'bar',
},
],
},
],
},
],
});
expect(filterSchema(nestedSchema, '1')).toEqual({
path: '',
type: 'object',
value: [
{
key: 'code',
path: '.code',
type: 'number',
value: '1',
},
],
});
expect(filterSchema(nestedSchema, 'no match')).toEqual(null);
});
it('should not filter schema with empty search', () => {
const flatSchema: Schema = {
type: 'object',
value: [
{
key: 'name',
type: 'string',
value: 'First item',
path: '.name',
},
{
key: 'code',
type: 'number',
value: '1',
path: '.code',
},
{
key: 'email',
type: 'string',
value: 'first item@gmail.com',
path: '.email',
},
],
path: '',
};
expect(filterSchema(flatSchema, '')).toEqual(flatSchema);
});
});
});