mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Allow connecting node to itself on new canvas (no-changelog) (#11143)
This commit is contained in:
parent
8566b3a999
commit
2161ff1217
|
@ -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', () => {
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -1299,10 +1299,6 @@ export function useCanvasOperations({ router }: { router: ReturnType<typeof useR
|
|||
): boolean {
|
||||
const blocklist = [STICKY_NODE_TYPE];
|
||||
|
||||
if (sourceNode.id === targetNode.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sourceConnectionType !== targetConnectionType) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -63,11 +63,10 @@ export function useNodeConnections({
|
|||
connection.targetHandle,
|
||||
);
|
||||
|
||||
const isSameNode = connection.source === connection.target;
|
||||
const isSameMode = sourceMode === targetMode;
|
||||
const isSameType = sourceType === targetType;
|
||||
|
||||
return !isSameNode && !isSameMode && isSameType;
|
||||
return !isSameMode && isSameType;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
Loading…
Reference in a new issue