mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +00:00
fix(core): Fix partial execution in triggerless parent case (#16833)
This commit is contained in:
@@ -970,6 +970,47 @@ describe('WorkflowExecute', () => {
|
|||||||
expect.objectContaining({ executionIndex: 1 }),
|
expect.objectContaining({ executionIndex: 1 }),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ►►
|
||||||
|
// ┌─────┐1 ┌─────┐
|
||||||
|
// │node1├──────►node2│
|
||||||
|
// └─────┘ └─────┘
|
||||||
|
test('should find closest parent with run data when no trigger exists', async () => {
|
||||||
|
// ARRANGE
|
||||||
|
const waitPromise = createDeferredPromise<IRun>();
|
||||||
|
const additionalData = Helpers.WorkflowExecuteAdditionalData(waitPromise);
|
||||||
|
const workflowExecute = new WorkflowExecute(additionalData, 'manual');
|
||||||
|
|
||||||
|
const node1 = createNodeData({ name: 'node1' });
|
||||||
|
const node2 = createNodeData({ name: 'node2' });
|
||||||
|
const workflow = new DirectedGraph()
|
||||||
|
.addNodes(node1, node2)
|
||||||
|
.addConnections({ from: node1, to: node2 })
|
||||||
|
.toWorkflow({ name: '', active: false, nodeTypes });
|
||||||
|
|
||||||
|
const pinData: IPinData = {};
|
||||||
|
const runData: IRunData = {
|
||||||
|
[node1.name]: [toITaskData([{ data: { name: node1.name } }])],
|
||||||
|
};
|
||||||
|
const dirtyNodeNames: string[] = [];
|
||||||
|
const destinationNode = node2.name;
|
||||||
|
|
||||||
|
const processRunExecutionDataSpy = jest
|
||||||
|
.spyOn(workflowExecute, 'processRunExecutionData')
|
||||||
|
.mockImplementationOnce(jest.fn());
|
||||||
|
|
||||||
|
// ACT
|
||||||
|
await workflowExecute.runPartialWorkflow2(
|
||||||
|
workflow,
|
||||||
|
runData,
|
||||||
|
pinData,
|
||||||
|
dirtyNodeNames,
|
||||||
|
destinationNode,
|
||||||
|
);
|
||||||
|
|
||||||
|
// ASSERT
|
||||||
|
expect(processRunExecutionDataSpy).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('checkReadyForExecution', () => {
|
describe('checkReadyForExecution', () => {
|
||||||
|
|||||||
@@ -424,9 +424,27 @@ export class WorkflowExecute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1. Find the Trigger
|
// 1. Find the Trigger
|
||||||
const trigger = findTriggerForPartialExecution(workflow, destinationNodeName, runData);
|
let trigger = findTriggerForPartialExecution(workflow, destinationNodeName, runData);
|
||||||
if (trigger === undefined) {
|
if (trigger === undefined) {
|
||||||
throw new UserError('Connect a trigger to run this node');
|
// destination has parents but none of them are triggers, so find the closest
|
||||||
|
// parent node that has run data, and treat that parent as starting point
|
||||||
|
|
||||||
|
let startNode;
|
||||||
|
|
||||||
|
const parentNodes = workflow.getParentNodes(destinationNodeName);
|
||||||
|
|
||||||
|
for (const nodeName of parentNodes) {
|
||||||
|
if (runData[nodeName]) {
|
||||||
|
startNode = workflow.getNode(nodeName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!startNode) {
|
||||||
|
throw new UserError('Connect a trigger to run this node');
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger = startNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Find the Subgraph
|
// 2. Find the Subgraph
|
||||||
|
|||||||
Reference in New Issue
Block a user