2024-05-23 01:42:10 -07:00
|
|
|
import {
|
2024-09-30 05:23:51 -07:00
|
|
|
createCanvasConnectionHandleString,
|
|
|
|
createCanvasConnectionId,
|
2024-06-04 05:36:27 -07:00
|
|
|
mapCanvasConnectionToLegacyConnection,
|
2024-09-30 05:23:51 -07:00
|
|
|
mapLegacyConnectionsToCanvasConnections,
|
|
|
|
mapLegacyEndpointsToCanvasConnectionPort,
|
2024-06-04 05:36:27 -07:00
|
|
|
parseCanvasConnectionHandleString,
|
2024-09-30 03:27:37 -07:00
|
|
|
checkOverlap,
|
2024-05-23 01:42:10 -07:00
|
|
|
} from '@/utils/canvasUtilsV2';
|
2024-11-06 06:16:47 -08:00
|
|
|
import { NodeConnectionType } from 'n8n-workflow';
|
|
|
|
import type { IConnections, INodeTypeDescription, IConnection } from 'n8n-workflow';
|
2024-05-23 01:42:10 -07:00
|
|
|
import type { CanvasConnection } from '@/types';
|
2024-09-30 05:23:51 -07:00
|
|
|
import { CanvasConnectionMode } from '@/types';
|
2024-05-23 01:42:10 -07:00
|
|
|
import type { INodeUi } from '@/Interface';
|
2024-06-04 05:36:27 -07:00
|
|
|
import type { Connection } from '@vue-flow/core';
|
|
|
|
import { createTestNode } from '@/__tests__/mocks';
|
2024-05-23 01:42:10 -07:00
|
|
|
|
|
|
|
vi.mock('uuid', () => ({
|
|
|
|
v4: vi.fn(() => 'mock-uuid'),
|
|
|
|
}));
|
|
|
|
|
|
|
|
describe('mapLegacyConnectionsToCanvasConnections', () => {
|
|
|
|
it('should map legacy connections to canvas connections', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }]],
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
2024-07-11 07:05:51 -07:00
|
|
|
const source = nodes[0].id;
|
|
|
|
const sourceHandle = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const target = nodes[1].id;
|
|
|
|
const targetHandle = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const id = createCanvasConnectionId({
|
|
|
|
source,
|
|
|
|
target,
|
|
|
|
sourceHandle,
|
|
|
|
targetHandle,
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id,
|
|
|
|
source,
|
|
|
|
target,
|
|
|
|
sourceHandle,
|
|
|
|
targetHandle,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return empty array when no matching nodes found', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }]],
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).toEqual([]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return empty array when no legacy connections provided', () => {
|
|
|
|
const legacyConnections: IConnections = {};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).toEqual([]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should map multiple connections between the same nodes', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [
|
2024-06-03 07:33:20 -07:00
|
|
|
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
|
|
|
|
[{ node: 'Node B', type: NodeConnectionType.Main, index: 1 }],
|
2024-05-23 01:42:10 -07:00
|
|
|
],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
2024-07-11 07:05:51 -07:00
|
|
|
const sourceA = nodes[0].id;
|
|
|
|
const sourceHandleA = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const targetA = nodes[1].id;
|
|
|
|
const targetHandleA = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const connectionIdA = createCanvasConnectionId({
|
|
|
|
source: sourceA,
|
|
|
|
target: targetA,
|
|
|
|
sourceHandle: sourceHandleA,
|
|
|
|
targetHandle: targetHandleA,
|
|
|
|
});
|
|
|
|
|
|
|
|
const sourceB = nodes[0].id;
|
|
|
|
const sourceHandleB = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
const targetB = nodes[1].id;
|
|
|
|
const targetHandleB = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
const connectionIdB = createCanvasConnectionId({
|
|
|
|
source: sourceB,
|
|
|
|
target: targetB,
|
|
|
|
sourceHandle: sourceHandleB,
|
|
|
|
targetHandle: targetHandleB,
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdA,
|
|
|
|
source: sourceA,
|
|
|
|
target: targetA,
|
|
|
|
sourceHandle: sourceHandleA,
|
|
|
|
targetHandle: targetHandleA,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdB,
|
|
|
|
source: sourceA,
|
|
|
|
target: targetB,
|
|
|
|
sourceHandle: sourceHandleB,
|
|
|
|
targetHandle: targetHandleB,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 1,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 1,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should map multiple connections from one node to different nodes', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [
|
2024-06-03 07:33:20 -07:00
|
|
|
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
|
|
|
|
[{ node: 'Node C', type: NodeConnectionType.Main, index: 0 }],
|
2024-05-23 01:42:10 -07:00
|
|
|
],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '3',
|
|
|
|
name: 'Node C',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [300, 300],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
2024-07-11 07:05:51 -07:00
|
|
|
const sourceA = nodes[0].id;
|
|
|
|
const sourceHandleA = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const targetA = nodes[1].id;
|
|
|
|
const targetHandleA = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const connectionIdA = createCanvasConnectionId({
|
|
|
|
source: sourceA,
|
|
|
|
target: targetA,
|
|
|
|
sourceHandle: sourceHandleA,
|
|
|
|
targetHandle: targetHandleA,
|
|
|
|
});
|
|
|
|
|
|
|
|
const sourceB = nodes[0].id;
|
|
|
|
const sourceHandleB = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
const targetB = nodes[2].id;
|
|
|
|
const targetHandleB = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const connectionIdB = createCanvasConnectionId({
|
|
|
|
source: sourceB,
|
|
|
|
target: targetB,
|
|
|
|
sourceHandle: sourceHandleB,
|
|
|
|
targetHandle: targetHandleB,
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdA,
|
|
|
|
source: sourceA,
|
|
|
|
target: targetA,
|
|
|
|
sourceHandle: sourceHandleA,
|
|
|
|
targetHandle: targetHandleA,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdB,
|
|
|
|
source: sourceB,
|
|
|
|
target: targetB,
|
|
|
|
sourceHandle: sourceHandleB,
|
|
|
|
targetHandle: targetHandleB,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 1,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should map complex node setup with mixed inputs and outputs', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }]],
|
2024-06-03 07:33:20 -07:00
|
|
|
[NodeConnectionType.AiMemory]: [
|
|
|
|
[{ node: 'Node C', type: NodeConnectionType.AiMemory, index: 1 }],
|
|
|
|
],
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
'Node B': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [[{ node: 'Node C', type: NodeConnectionType.Main, index: 0 }]],
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
typeVersion: 1,
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
typeVersion: 1,
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '3',
|
|
|
|
name: 'Node C',
|
|
|
|
typeVersion: 1,
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
position: [300, 300],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
2024-07-11 07:05:51 -07:00
|
|
|
const sourceA = nodes[0].id;
|
|
|
|
const sourceHandleA = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const targetA = nodes[1].id;
|
|
|
|
const targetHandleA = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const connectionIdA = createCanvasConnectionId({
|
|
|
|
source: sourceA,
|
|
|
|
target: targetA,
|
|
|
|
sourceHandle: sourceHandleA,
|
|
|
|
targetHandle: targetHandleA,
|
|
|
|
});
|
|
|
|
|
|
|
|
const sourceB = nodes[0].id;
|
|
|
|
const sourceHandleB = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.AiMemory,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const targetB = nodes[2].id;
|
|
|
|
const targetHandleB = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.AiMemory,
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
const connectionIdB = createCanvasConnectionId({
|
|
|
|
source: sourceB,
|
|
|
|
target: targetB,
|
|
|
|
sourceHandle: sourceHandleB,
|
|
|
|
targetHandle: targetHandleB,
|
|
|
|
});
|
|
|
|
|
|
|
|
const sourceC = nodes[1].id;
|
|
|
|
const sourceHandleC = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const targetC = nodes[2].id;
|
|
|
|
const targetHandleC = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const connectionIdC = createCanvasConnectionId({
|
|
|
|
source: sourceC,
|
|
|
|
target: targetC,
|
|
|
|
sourceHandle: sourceHandleC,
|
|
|
|
targetHandle: targetHandleC,
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdA,
|
|
|
|
source: sourceA,
|
|
|
|
target: targetA,
|
|
|
|
sourceHandle: sourceHandleA,
|
|
|
|
targetHandle: targetHandleA,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdB,
|
|
|
|
source: sourceB,
|
|
|
|
target: targetB,
|
|
|
|
sourceHandle: sourceHandleB,
|
|
|
|
targetHandle: targetHandleB,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.AiMemory,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 1,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.AiMemory,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id: connectionIdC,
|
|
|
|
source: sourceC,
|
|
|
|
target: targetC,
|
|
|
|
sourceHandle: sourceHandleC,
|
|
|
|
targetHandle: targetHandleC,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[1].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle edge cases with invalid data gracefully', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
2024-11-06 06:16:47 -08:00
|
|
|
[NodeConnectionType.Main]: [
|
2024-06-03 07:33:20 -07:00
|
|
|
[{ node: 'Nonexistent Node', type: NodeConnectionType.Main, index: 0 }],
|
|
|
|
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
|
2024-05-23 01:42:10 -07:00
|
|
|
],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
2024-07-11 07:05:51 -07:00
|
|
|
const source = nodes[0].id;
|
|
|
|
const sourceHandle = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
|
|
|
|
const target = nodes[1].id;
|
|
|
|
const targetHandle = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
|
|
|
|
const id = createCanvasConnectionId({
|
|
|
|
source,
|
|
|
|
target,
|
|
|
|
sourceHandle,
|
|
|
|
targetHandle,
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
2024-07-11 07:05:51 -07:00
|
|
|
id,
|
|
|
|
source,
|
|
|
|
target,
|
|
|
|
sourceHandle,
|
|
|
|
targetHandle,
|
2024-05-23 01:42:10 -07:00
|
|
|
data: {
|
2024-07-11 07:05:51 -07:00
|
|
|
fromNodeName: nodes[0].name,
|
2024-05-23 01:42:10 -07:00
|
|
|
source: {
|
|
|
|
index: 1,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
2024-06-03 07:33:20 -07:00
|
|
|
type: NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
2024-11-06 06:16:47 -08:00
|
|
|
|
|
|
|
// @issue https://linear.app/n8n/issue/N8N-7880/cannot-load-some-templates
|
|
|
|
it('should handle null connections gracefully', () => {
|
|
|
|
const legacyConnections: IConnections = {
|
|
|
|
'Node A': {
|
|
|
|
[NodeConnectionType.Main]: [
|
|
|
|
null as unknown as IConnection[],
|
|
|
|
[{ node: 'Node B', type: NodeConnectionType.Main, index: 0 }],
|
|
|
|
],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const nodes: INodeUi[] = [
|
|
|
|
{
|
|
|
|
id: '1',
|
|
|
|
name: 'Node A',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [100, 100],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: '2',
|
|
|
|
name: 'Node B',
|
|
|
|
type: 'n8n-nodes-base.node',
|
|
|
|
typeVersion: 1,
|
|
|
|
position: [200, 200],
|
|
|
|
parameters: {},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const result: CanvasConnection[] = mapLegacyConnectionsToCanvasConnections(
|
|
|
|
legacyConnections,
|
|
|
|
nodes,
|
|
|
|
);
|
|
|
|
|
|
|
|
const source = nodes[0].id;
|
|
|
|
const sourceHandle = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Output,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
const target = nodes[1].id;
|
|
|
|
const targetHandle = createCanvasConnectionHandleString({
|
|
|
|
mode: CanvasConnectionMode.Input,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
const id = createCanvasConnectionId({
|
|
|
|
source,
|
|
|
|
target,
|
|
|
|
sourceHandle,
|
|
|
|
targetHandle,
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
|
|
|
id,
|
|
|
|
source,
|
|
|
|
target,
|
|
|
|
sourceHandle,
|
|
|
|
targetHandle,
|
|
|
|
data: {
|
|
|
|
fromNodeName: nodes[0].name,
|
|
|
|
source: {
|
|
|
|
index: 1,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
},
|
|
|
|
target: {
|
|
|
|
index: 0,
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
2024-05-23 01:42:10 -07:00
|
|
|
});
|
|
|
|
|
2024-06-04 05:36:27 -07:00
|
|
|
describe('parseCanvasConnectionHandleString', () => {
|
|
|
|
it('should parse valid handle string', () => {
|
2024-07-08 03:25:18 -07:00
|
|
|
const handle = 'inputs/main/1';
|
2024-06-04 05:36:27 -07:00
|
|
|
const result = parseCanvasConnectionHandleString(handle);
|
|
|
|
|
|
|
|
expect(result).toEqual({
|
2024-07-08 03:25:18 -07:00
|
|
|
mode: 'inputs',
|
2024-06-04 05:36:27 -07:00
|
|
|
type: 'main',
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle null handle', () => {
|
|
|
|
const handle = null;
|
|
|
|
const result = parseCanvasConnectionHandleString(handle);
|
|
|
|
|
|
|
|
expect(result).toEqual({
|
2024-07-08 03:25:18 -07:00
|
|
|
mode: 'outputs',
|
2024-06-04 05:36:27 -07:00
|
|
|
type: 'main',
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle undefined handle', () => {
|
|
|
|
const handle = undefined;
|
|
|
|
const result = parseCanvasConnectionHandleString(handle);
|
|
|
|
|
|
|
|
expect(result).toEqual({
|
2024-07-08 03:25:18 -07:00
|
|
|
mode: 'outputs',
|
2024-06-04 05:36:27 -07:00
|
|
|
type: 'main',
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle invalid type in handle', () => {
|
|
|
|
const handle = 'outputs/invalid/1';
|
|
|
|
const result = parseCanvasConnectionHandleString(handle);
|
|
|
|
|
|
|
|
expect(result).toEqual({
|
2024-07-08 03:25:18 -07:00
|
|
|
mode: 'outputs',
|
2024-06-04 05:36:27 -07:00
|
|
|
type: 'main',
|
|
|
|
index: 1,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle invalid index in handle', () => {
|
|
|
|
const handle = 'outputs/main/invalid';
|
|
|
|
const result = parseCanvasConnectionHandleString(handle);
|
|
|
|
|
|
|
|
expect(result).toEqual({
|
2024-07-08 03:25:18 -07:00
|
|
|
mode: 'outputs',
|
2024-06-04 05:36:27 -07:00
|
|
|
type: 'main',
|
|
|
|
index: 0,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-06-25 02:11:44 -07:00
|
|
|
describe('createCanvasConnectionHandleString', () => {
|
|
|
|
it('should create handle string with default values', () => {
|
|
|
|
const result = createCanvasConnectionHandleString({ mode: 'inputs' });
|
|
|
|
expect(result).toBe('inputs/main/0');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should create handle string with provided values', () => {
|
|
|
|
const result = createCanvasConnectionHandleString({
|
|
|
|
mode: 'outputs',
|
|
|
|
type: NodeConnectionType.AiMemory,
|
|
|
|
index: 2,
|
|
|
|
});
|
|
|
|
expect(result).toBe(`outputs/${NodeConnectionType.AiMemory}/2`);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should create handle string with mode and type only', () => {
|
|
|
|
const result = createCanvasConnectionHandleString({
|
|
|
|
mode: 'inputs',
|
|
|
|
type: NodeConnectionType.AiTool,
|
|
|
|
});
|
|
|
|
expect(result).toBe(`inputs/${NodeConnectionType.AiTool}/0`);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should create handle string with mode and index only', () => {
|
|
|
|
const result = createCanvasConnectionHandleString({ mode: 'outputs', index: 3 });
|
|
|
|
expect(result).toBe('outputs/main/3');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-06-04 05:36:27 -07:00
|
|
|
describe('mapCanvasConnectionToLegacyConnection', () => {
|
|
|
|
it('should map canvas connection to legacy connection', () => {
|
|
|
|
const sourceNode = createTestNode({ name: 'sourceNode', type: 'main' });
|
|
|
|
const targetNode = createTestNode({ name: 'targetNode', type: 'main' });
|
|
|
|
const connection: Connection = {
|
|
|
|
target: '1',
|
|
|
|
source: '2',
|
|
|
|
sourceHandle: 'outputs/main/1',
|
|
|
|
targetHandle: 'inputs/main/2',
|
|
|
|
};
|
|
|
|
|
|
|
|
const result = mapCanvasConnectionToLegacyConnection(sourceNode, targetNode, connection);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
|
|
|
{ node: sourceNode.name, type: 'main', index: 1 },
|
|
|
|
{ node: targetNode.name, type: 'main', index: 2 },
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
describe('mapLegacyEndpointsToCanvasConnectionPort', () => {
|
|
|
|
it('should return an empty array and log a warning when inputs is a string', () => {
|
|
|
|
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
2024-06-25 04:53:31 -07:00
|
|
|
const endpoints: INodeTypeDescription['inputs'] = '={{some code}}';
|
2024-05-23 01:42:10 -07:00
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([]);
|
|
|
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
|
|
'Node endpoints have not been evaluated',
|
2024-06-25 04:53:31 -07:00
|
|
|
'={{some code}}',
|
2024-05-23 01:42:10 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
consoleWarnSpy.mockRestore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should map string endpoints correctly', () => {
|
2024-06-03 07:33:20 -07:00
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
|
|
|
NodeConnectionType.Main,
|
|
|
|
NodeConnectionType.AiTool,
|
|
|
|
];
|
2024-05-23 01:42:10 -07:00
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, index: 0, label: undefined },
|
2024-11-21 06:00:38 -08:00
|
|
|
{
|
|
|
|
type: NodeConnectionType.AiTool,
|
|
|
|
index: 0,
|
|
|
|
label: undefined,
|
|
|
|
maxConnections: undefined,
|
|
|
|
},
|
2024-05-23 01:42:10 -07:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should map object endpoints correctly', () => {
|
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, displayName: 'Main Input' },
|
|
|
|
{ type: NodeConnectionType.AiTool, displayName: 'AI Tool', required: true },
|
2024-05-23 01:42:10 -07:00
|
|
|
];
|
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, index: 0, label: 'Main Input' },
|
2024-11-21 06:00:38 -08:00
|
|
|
{
|
|
|
|
type: NodeConnectionType.AiTool,
|
|
|
|
index: 0,
|
|
|
|
label: 'AI Tool',
|
|
|
|
required: true,
|
|
|
|
maxConnections: undefined,
|
|
|
|
},
|
2024-05-23 01:42:10 -07:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should map mixed string and object endpoints correctly', () => {
|
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
2024-06-03 07:33:20 -07:00
|
|
|
NodeConnectionType.Main,
|
|
|
|
{ type: NodeConnectionType.AiTool, displayName: 'AI Tool' },
|
|
|
|
NodeConnectionType.Main,
|
2024-05-23 01:42:10 -07:00
|
|
|
];
|
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, index: 0, label: undefined },
|
2024-11-21 06:00:38 -08:00
|
|
|
{
|
|
|
|
type: NodeConnectionType.AiTool,
|
|
|
|
index: 0,
|
|
|
|
label: 'AI Tool',
|
|
|
|
maxConnections: undefined,
|
|
|
|
},
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, index: 1, label: undefined },
|
2024-05-23 01:42:10 -07:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should handle multiple same type object endpoints', () => {
|
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, displayName: 'Main Input' },
|
|
|
|
{ type: NodeConnectionType.Main, displayName: 'Secondary Main Input' },
|
2024-05-23 01:42:10 -07:00
|
|
|
];
|
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, index: 0, label: 'Main Input' },
|
|
|
|
{ type: NodeConnectionType.Main, index: 1, label: 'Secondary Main Input' },
|
2024-05-23 01:42:10 -07:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
2024-07-24 05:47:18 -07:00
|
|
|
it('should handle endpoints with separate names', () => {
|
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
|
|
|
NodeConnectionType.Main,
|
|
|
|
NodeConnectionType.Main,
|
|
|
|
];
|
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints, ['First', 'Second']);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
|
|
|
{ type: NodeConnectionType.Main, index: 0, label: 'First' },
|
|
|
|
{ type: NodeConnectionType.Main, index: 1, label: 'Second' },
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
2024-05-23 01:42:10 -07:00
|
|
|
it('should map required and non-required endpoints correctly', () => {
|
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, displayName: 'Main Input', required: true },
|
|
|
|
{ type: NodeConnectionType.AiTool, displayName: 'Optional Tool', required: false },
|
2024-05-23 01:42:10 -07:00
|
|
|
];
|
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
2024-06-03 07:33:20 -07:00
|
|
|
{ type: NodeConnectionType.Main, index: 0, label: 'Main Input', required: true },
|
2024-11-21 06:00:38 -08:00
|
|
|
{
|
|
|
|
type: NodeConnectionType.AiTool,
|
|
|
|
index: 0,
|
|
|
|
label: 'Optional Tool',
|
|
|
|
maxConnections: undefined,
|
|
|
|
},
|
2024-05-23 01:42:10 -07:00
|
|
|
]);
|
|
|
|
});
|
2024-09-30 05:23:51 -07:00
|
|
|
|
|
|
|
it('should map maxConnections correctly', () => {
|
|
|
|
const endpoints: INodeTypeDescription['inputs'] = [
|
|
|
|
NodeConnectionType.Main,
|
|
|
|
{
|
|
|
|
type: NodeConnectionType.AiMemory,
|
|
|
|
maxConnections: 1,
|
|
|
|
displayName: 'Optional Tool',
|
|
|
|
required: false,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
const result = mapLegacyEndpointsToCanvasConnectionPort(endpoints);
|
|
|
|
|
|
|
|
expect(result).toEqual([
|
|
|
|
{
|
|
|
|
type: NodeConnectionType.Main,
|
|
|
|
maxConnections: undefined,
|
|
|
|
index: 0,
|
|
|
|
label: undefined,
|
|
|
|
},
|
|
|
|
{ type: NodeConnectionType.AiMemory, maxConnections: 1, index: 0, label: 'Optional Tool' },
|
|
|
|
]);
|
|
|
|
});
|
2024-05-23 01:42:10 -07:00
|
|
|
});
|
|
|
|
|
2024-09-30 03:27:37 -07:00
|
|
|
describe('checkOverlap', () => {
|
|
|
|
it('should return true when nodes overlap', () => {
|
|
|
|
const node1 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 5, y: 5, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return false when node1 is completely to the left of node2', () => {
|
|
|
|
const node1 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 15, y: 0, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return false when node2 is completely to the left of node1', () => {
|
|
|
|
const node1 = { x: 15, y: 0, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return false when node1 is completely above node2', () => {
|
|
|
|
const node1 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 0, y: 15, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return false when node2 is completely above node1', () => {
|
|
|
|
const node1 = { x: 0, y: 15, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return false when nodes touch at the edges', () => {
|
|
|
|
const node1 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 10, y: 0, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return false when nodes touch at the corners', () => {
|
|
|
|
const node1 = { x: 0, y: 0, width: 10, height: 10 };
|
|
|
|
const node2 = { x: 10, y: 10, width: 10, height: 10 };
|
|
|
|
expect(checkOverlap(node1, node2)).toBe(false);
|
|
|
|
});
|
|
|
|
});
|