fix(editor): Fix schema view bugs (#14734)

Co-authored-by: Michael Kret <michael.k@radency.com>
This commit is contained in:
Elias Meire
2025-04-24 08:53:02 +02:00
committed by GitHub
parent 1b1d6043d6
commit 022f4755c2
14 changed files with 1040 additions and 781 deletions

View File

@@ -1,5 +1,5 @@
import jp from 'jsonpath';
import { useDataSchema, useFlattenSchema } from '@/composables/useDataSchema';
import { useDataSchema, useFlattenSchema, type SchemaNode } from '@/composables/useDataSchema';
import type { IExecutionResponse, INodeUi, Schema } from '@/Interface';
import { setActivePinia } from 'pinia';
import { createTestingPinia } from '@pinia/testing';
@@ -10,6 +10,7 @@ import {
} from 'n8n-workflow';
import { useWorkflowsStore } from '@/stores/workflows.store';
import type { JSONSchema7 } from 'json-schema';
import { mock } from 'vitest-mock-extended';
vi.mock('@/stores/workflows.store');
@@ -785,57 +786,197 @@ describe('useDataSchema', () => {
});
describe('useFlattenSchema', () => {
it('flattens a schema', () => {
const schema: Schema = {
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(
useFlattenSchema().flattenSchema({
schema,
}).length,
).toBe(3);
describe('flattenSchema', () => {
it('flattens a schema', () => {
const schema: Schema = {
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(
useFlattenSchema().flattenSchema({
schema,
}).length,
).toBe(3);
});
it('items ids should be unique', () => {
const { flattenSchema } = useFlattenSchema();
const schema: Schema = {
path: '',
type: 'object',
value: [
{
key: 'index',
type: 'number',
value: '0',
path: '.index',
},
],
};
const node1Schema = flattenSchema({ schema, expressionPrefix: '$("First Node")', depth: 1 });
const node2Schema = flattenSchema({ schema, expressionPrefix: '$("Second Node")', depth: 1 });
expect(node1Schema[0].id).not.toBe(node2Schema[0].id);
});
});
it('items ids should be unique', () => {
const { flattenSchema } = useFlattenSchema();
const schema: Schema = {
path: '',
type: 'object',
value: [
{
key: 'index',
type: 'number',
value: '0',
path: '.index',
},
],
};
const node1Schema = flattenSchema({ schema, expressionPrefix: '$("First Node")', depth: 1 });
const node2Schema = flattenSchema({ schema, expressionPrefix: '$("Second Node")', depth: 1 });
describe('flattenMultipleSchemas', () => {
it('should handle empty data', () => {
const { flattenMultipleSchemas } = useFlattenSchema();
expect(node1Schema[0].id).not.toBe(node2Schema[0].id);
const result = flattenMultipleSchemas(
[
mock<SchemaNode>({
node: { name: 'Test Node' },
isDataEmpty: true,
schema: { type: 'object', value: [] },
}),
],
vi.fn(),
);
expect(result).toHaveLength(2);
expect(result[0]).toEqual(expect.objectContaining({ type: 'header', title: 'Test Node' }));
expect(result[1]).toEqual(
expect.objectContaining({ type: 'empty', key: 'emptyData', level: 1 }),
);
});
it('should handle unexecuted nodes', () => {
const { flattenMultipleSchemas } = useFlattenSchema();
const result = flattenMultipleSchemas(
[
mock<SchemaNode>({
node: { name: 'Test Node' },
isNodeExecuted: false,
schema: { type: 'object', value: [] },
}),
],
vi.fn(),
);
expect(result).toHaveLength(2);
expect(result[0]).toEqual(expect.objectContaining({ type: 'header', title: 'Test Node' }));
expect(result[1]).toEqual(
expect.objectContaining({ type: 'empty', key: 'executeSchema', level: 1 }),
);
});
it('should handle empty schema', () => {
const { flattenMultipleSchemas } = useFlattenSchema();
const result = flattenMultipleSchemas(
[
mock<SchemaNode>({
node: { name: 'Test Node' },
isDataEmpty: false,
hasBinary: false,
schema: { type: 'object', value: [] },
}),
],
vi.fn(),
);
expect(result).toHaveLength(2);
expect(result[0]).toEqual(expect.objectContaining({ type: 'header', title: 'Test Node' }));
expect(result[1]).toEqual(
expect.objectContaining({ type: 'empty', key: 'emptySchema', level: 1 }),
);
});
it('should handle empty schema with binary', () => {
const { flattenMultipleSchemas } = useFlattenSchema();
const result = flattenMultipleSchemas(
[
mock<SchemaNode>({
node: { name: 'Test Node' },
isDataEmpty: false,
hasBinary: true,
schema: { type: 'object', value: [] },
}),
],
vi.fn(),
);
expect(result).toHaveLength(2);
expect(result[0]).toEqual(expect.objectContaining({ type: 'header', title: 'Test Node' }));
expect(result[1]).toEqual(
expect.objectContaining({ type: 'empty', key: 'emptySchemaWithBinary', level: 1 }),
);
});
it('should flatten node schemas', () => {
const { flattenMultipleSchemas } = useFlattenSchema();
const schema: Schema = {
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',
},
],
},
],
},
],
};
const result = flattenMultipleSchemas(
[
mock<SchemaNode>({
node: { name: 'Test Node' },
isDataEmpty: false,
hasBinary: false,
preview: false,
schema,
}),
mock<SchemaNode>({
node: { name: 'Test Node' },
isDataEmpty: false,
hasBinary: false,
preview: false,
schema,
}),
],
vi.fn(),
);
expect(result).toHaveLength(10);
expect(result.filter((item) => item.type === 'header')).toHaveLength(2);
expect(result.filter((item) => item.type === 'item')).toHaveLength(8);
expect(result).toMatchSnapshot();
});
});
});