From 2161ff121746cf359af302b1d4c596b8869fb719 Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Tue, 8 Oct 2024 11:15:36 +0300 Subject: [PATCH] fix(editor): Allow connecting node to itself on new canvas (no-changelog) (#11143) --- .../__tests__/useCanvasOperations.spec.ts | 160 +++++++++++------- .../__tests__/useNodeConnections.spec.ts | 4 +- .../src/composables/useCanvasOperations.ts | 4 - .../src/composables/useNodeConnections.ts | 3 +- 4 files changed, 98 insertions(+), 73 deletions(-) diff --git a/packages/editor-ui/src/composables/__tests__/useCanvasOperations.spec.ts b/packages/editor-ui/src/composables/__tests__/useCanvasOperations.spec.ts index a440fb338b..e4ece8768f 100644 --- a/packages/editor-ui/src/composables/__tests__/useCanvasOperations.spec.ts +++ b/packages/editor-ui/src/composables/__tests__/useCanvasOperations.spec.ts @@ -1093,14 +1093,6 @@ describe('useCanvasOperations', () => { }); describe('isConnectionAllowed', () => { - it('should return false if source and target nodes are the same', () => { - const node = mockNode({ id: '1', type: 'testType', name: 'Test Node' }); - const { isConnectionAllowed } = useCanvasOperations({ router }); - expect( - isConnectionAllowed(node, node, NodeConnectionType.Main, NodeConnectionType.Main), - ).toBe(false); - }); - it('should return false if target node type does not have inputs', () => { const workflowsStore = mockedStore(useWorkflowsStore); const nodeTypesStore = mockedStore(useNodeTypesStore); @@ -1342,63 +1334,63 @@ describe('useCanvasOperations', () => { ).toBe(false); }); - // it('should return true if all conditions including filter are met', () => { - // const workflowsStore = mockedStore(useWorkflowsStore); - // const nodeTypesStore = mockedStore(useNodeTypesStore); - // - // const sourceNode = mockNode({ - // id: '1', - // type: 'sourceType', - // name: 'Source Node', - // typeVersion: 1, - // }); - // const sourceNodeTypeDescription = mockNodeTypeDescription({ - // name: sourceNode.type, - // outputs: [NodeConnectionType.Main], - // }); - // - // const targetNode = mockNode({ - // id: '2', - // type: 'targetType', - // name: 'Target Node', - // typeVersion: 1, - // }); - // const targetNodeTypeDescription = mockNodeTypeDescription({ - // name: targetNode.type, - // inputs: [ - // { - // type: NodeConnectionType.Main, - // filter: { - // nodes: [sourceNode.type], - // }, - // }, - // ], - // }); - // - // const workflowObject = createTestWorkflowObject(workflowsStore.workflow); - // workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject); - // - // const { isConnectionAllowed, editableWorkflowObject } = useCanvasOperations({ router }); - // - // editableWorkflowObject.value.nodes[sourceNode.name] = sourceNode; - // editableWorkflowObject.value.nodes[targetNode.name] = targetNode; - // nodeTypesStore.getNodeType = vi.fn( - // (nodeTypeName: string) => - // ({ - // [sourceNode.type]: sourceNodeTypeDescription, - // [targetNode.type]: targetNodeTypeDescription, - // })[nodeTypeName], - // ); - // - // expect( - // isConnectionAllowed( - // sourceNode, - // targetNode, - // NodeConnectionType.Main, - // NodeConnectionType.Main, - // ), - // ).toBe(true); - // }); + it('should return true if all conditions including filter are met', () => { + const workflowsStore = mockedStore(useWorkflowsStore); + const nodeTypesStore = mockedStore(useNodeTypesStore); + + const sourceNode = mockNode({ + id: '1', + type: 'sourceType', + name: 'Source Node', + typeVersion: 1, + }); + const sourceNodeTypeDescription = mockNodeTypeDescription({ + name: sourceNode.type, + outputs: [NodeConnectionType.Main], + }); + + const targetNode = mockNode({ + id: '2', + type: 'targetType', + name: 'Target Node', + typeVersion: 1, + }); + const targetNodeTypeDescription = mockNodeTypeDescription({ + name: targetNode.type, + inputs: [ + { + type: NodeConnectionType.Main, + filter: { + nodes: [sourceNode.type], + }, + }, + ], + }); + + const workflowObject = createTestWorkflowObject(workflowsStore.workflow); + workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject); + + const { isConnectionAllowed, editableWorkflowObject } = useCanvasOperations({ router }); + + editableWorkflowObject.value.nodes[sourceNode.name] = sourceNode; + editableWorkflowObject.value.nodes[targetNode.name] = targetNode; + nodeTypesStore.getNodeType = vi.fn( + (nodeTypeName: string) => + ({ + [sourceNode.type]: sourceNodeTypeDescription, + [targetNode.type]: targetNodeTypeDescription, + })[nodeTypeName], + ); + + expect( + isConnectionAllowed( + sourceNode, + targetNode, + NodeConnectionType.Main, + NodeConnectionType.Main, + ), + ).toBe(true); + }); it('should return true if all conditions are met and no filter is set', () => { const workflowsStore = mockedStore(useWorkflowsStore); @@ -1454,6 +1446,44 @@ describe('useCanvasOperations', () => { ), ).toBe(true); }); + + it('should return true if node connecting to itself', () => { + const workflowsStore = mockedStore(useWorkflowsStore); + const nodeTypesStore = mockedStore(useNodeTypesStore); + + const sourceNode = mockNode({ + id: '1', + type: 'sourceType', + name: 'Source Node', + typeVersion: 1, + }); + const sourceNodeTypeDescription = mockNodeTypeDescription({ + name: sourceNode.type, + outputs: [NodeConnectionType.Main], + }); + + const workflowObject = createTestWorkflowObject(workflowsStore.workflow); + workflowsStore.getCurrentWorkflow.mockReturnValue(workflowObject); + + const { isConnectionAllowed, editableWorkflowObject } = useCanvasOperations({ router }); + + editableWorkflowObject.value.nodes[sourceNode.name] = sourceNode; + nodeTypesStore.getNodeType = vi.fn( + (nodeTypeName: string) => + ({ + [sourceNode.type]: sourceNodeTypeDescription, + })[nodeTypeName], + ); + + expect( + isConnectionAllowed( + sourceNode, + sourceNode, + NodeConnectionType.Main, + NodeConnectionType.Main, + ), + ).toBe(true); + }); }); describe('deleteConnection', () => { diff --git a/packages/editor-ui/src/composables/__tests__/useNodeConnections.spec.ts b/packages/editor-ui/src/composables/__tests__/useNodeConnections.spec.ts index e4fef99039..fa532d6cd8 100644 --- a/packages/editor-ui/src/composables/__tests__/useNodeConnections.spec.ts +++ b/packages/editor-ui/src/composables/__tests__/useNodeConnections.spec.ts @@ -176,7 +176,7 @@ describe('useNodeConnections', () => { connections: defaultConnections, }); - it('returns false if source and target nodes are the same', () => { + it('returns true if source and target nodes are the same', () => { const connection = { source: 'node1', target: 'node1', @@ -191,7 +191,7 @@ describe('useNodeConnections', () => { index: 0, }), }; - expect(isValidConnection(connection)).toBe(false); + expect(isValidConnection(connection)).toBe(true); }); it('returns false if source and target handles are of the same mode', () => { diff --git a/packages/editor-ui/src/composables/useCanvasOperations.ts b/packages/editor-ui/src/composables/useCanvasOperations.ts index f4e3968364..00071e5a99 100644 --- a/packages/editor-ui/src/composables/useCanvasOperations.ts +++ b/packages/editor-ui/src/composables/useCanvasOperations.ts @@ -1299,10 +1299,6 @@ export function useCanvasOperations({ router }: { router: ReturnType