mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Don't open form popup window if different trigger node is used (#13391)
This commit is contained in:
parent
415e25b5d5
commit
57a9a5b15f
|
@ -351,6 +351,7 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
|
||||||
nodes: workflowData.nodes,
|
nodes: workflowData.nodes,
|
||||||
runData: workflowsStore.getWorkflowExecution?.data?.resultData?.runData,
|
runData: workflowsStore.getWorkflowExecution?.data?.resultData?.runData,
|
||||||
destinationNode: options.destinationNode,
|
destinationNode: options.destinationNode,
|
||||||
|
triggerNode: options.triggerNode,
|
||||||
pinData,
|
pinData,
|
||||||
directParentNodes,
|
directParentNodes,
|
||||||
source: options.source,
|
source: options.source,
|
||||||
|
|
|
@ -1,23 +1,13 @@
|
||||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
import {
|
import { displayForm, executionFilterToQueryFilter, waitingNodeTooltip } from './executionUtils';
|
||||||
displayForm,
|
|
||||||
openFormPopupWindow,
|
|
||||||
executionFilterToQueryFilter,
|
|
||||||
waitingNodeTooltip,
|
|
||||||
} from './executionUtils';
|
|
||||||
import type { INode, IRunData, IPinData } from 'n8n-workflow';
|
import type { INode, IRunData, IPinData } from 'n8n-workflow';
|
||||||
import { type INodeUi } from '../Interface';
|
import { type INodeUi } from '../Interface';
|
||||||
|
import { CHAT_TRIGGER_NODE_TYPE, FORM_TRIGGER_NODE_TYPE } from '@/constants';
|
||||||
|
import { createTestNode } from '@/__tests__/mocks';
|
||||||
|
|
||||||
const FORM_TRIGGER_NODE_TYPE = 'formTrigger';
|
|
||||||
const WAIT_NODE_TYPE = 'waitNode';
|
const WAIT_NODE_TYPE = 'waitNode';
|
||||||
|
|
||||||
vi.mock('./executionUtils', async () => {
|
const windowOpenSpy = vi.spyOn(window, 'open');
|
||||||
const actual = await vi.importActual('./executionUtils');
|
|
||||||
return {
|
|
||||||
...actual,
|
|
||||||
openFormPopupWindow: vi.fn(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock('@/stores/root.store', () => ({
|
vi.mock('@/stores/root.store', () => ({
|
||||||
useRootStore: () => ({
|
useRootStore: () => ({
|
||||||
|
@ -81,12 +71,13 @@ describe('displayForm', () => {
|
||||||
runData,
|
runData,
|
||||||
pinData,
|
pinData,
|
||||||
destinationNode: undefined,
|
destinationNode: undefined,
|
||||||
|
triggerNode: undefined,
|
||||||
directParentNodes: [],
|
directParentNodes: [],
|
||||||
source: undefined,
|
source: undefined,
|
||||||
getTestUrl: getTestUrlMock,
|
getTestUrl: getTestUrlMock,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(openFormPopupWindow).not.toHaveBeenCalled();
|
expect(windowOpenSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should skip nodes if destinationNode does not match and node is not a directParentNode', () => {
|
it('should skip nodes if destinationNode does not match and node is not a directParentNode', () => {
|
||||||
|
@ -114,12 +105,13 @@ describe('displayForm', () => {
|
||||||
runData: undefined,
|
runData: undefined,
|
||||||
pinData: {},
|
pinData: {},
|
||||||
destinationNode: 'Node3',
|
destinationNode: 'Node3',
|
||||||
|
triggerNode: undefined,
|
||||||
directParentNodes: ['Node4'],
|
directParentNodes: ['Node4'],
|
||||||
source: undefined,
|
source: undefined,
|
||||||
getTestUrl: getTestUrlMock,
|
getTestUrl: getTestUrlMock,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(openFormPopupWindow).not.toHaveBeenCalled();
|
expect(windowOpenSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not open pop-up if source is "RunData.ManualChatMessage"', () => {
|
it('should not open pop-up if source is "RunData.ManualChatMessage"', () => {
|
||||||
|
@ -141,20 +133,62 @@ describe('displayForm', () => {
|
||||||
runData: undefined,
|
runData: undefined,
|
||||||
pinData: {},
|
pinData: {},
|
||||||
destinationNode: undefined,
|
destinationNode: undefined,
|
||||||
|
triggerNode: undefined,
|
||||||
directParentNodes: [],
|
directParentNodes: [],
|
||||||
source: 'RunData.ManualChatMessage',
|
source: 'RunData.ManualChatMessage',
|
||||||
getTestUrl: getTestUrlMock,
|
getTestUrl: getTestUrlMock,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(openFormPopupWindow).not.toHaveBeenCalled();
|
expect(windowOpenSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('executionFilterToQueryFilter()', () => {
|
describe('with trigger node', () => {
|
||||||
it('adds "new" to the filter', () => {
|
const nodes: INode[] = [
|
||||||
expect(executionFilterToQueryFilter({ status: 'new' }).status).toStrictEqual(
|
createTestNode({ name: 'Node1', type: FORM_TRIGGER_NODE_TYPE }),
|
||||||
expect.arrayContaining(['new']),
|
createTestNode({ name: 'Node2', type: CHAT_TRIGGER_NODE_TYPE }),
|
||||||
);
|
];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
getTestUrlMock.mockReturnValue('http://test-url.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should open pop-up if the trigger node is a form node', () => {
|
||||||
|
displayForm({
|
||||||
|
nodes,
|
||||||
|
runData: undefined,
|
||||||
|
pinData: {},
|
||||||
|
destinationNode: undefined,
|
||||||
|
triggerNode: 'Node1',
|
||||||
|
directParentNodes: [],
|
||||||
|
source: undefined,
|
||||||
|
getTestUrl: getTestUrlMock,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(windowOpenSpy).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not open pop-up if the trigger node is specified and it isn't a form node", () => {
|
||||||
|
displayForm({
|
||||||
|
nodes,
|
||||||
|
runData: undefined,
|
||||||
|
pinData: {},
|
||||||
|
destinationNode: undefined,
|
||||||
|
triggerNode: 'Node2',
|
||||||
|
directParentNodes: [],
|
||||||
|
source: undefined,
|
||||||
|
getTestUrl: getTestUrlMock,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(windowOpenSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('executionFilterToQueryFilter()', () => {
|
||||||
|
it('adds "new" to the filter', () => {
|
||||||
|
expect(executionFilterToQueryFilter({ status: 'new' }).status).toStrictEqual(
|
||||||
|
expect.arrayContaining(['new']),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ export function displayForm({
|
||||||
runData,
|
runData,
|
||||||
pinData,
|
pinData,
|
||||||
destinationNode,
|
destinationNode,
|
||||||
|
triggerNode,
|
||||||
directParentNodes,
|
directParentNodes,
|
||||||
source,
|
source,
|
||||||
getTestUrl,
|
getTestUrl,
|
||||||
|
@ -113,11 +114,14 @@ export function displayForm({
|
||||||
runData: IRunData | undefined;
|
runData: IRunData | undefined;
|
||||||
pinData: IPinData;
|
pinData: IPinData;
|
||||||
destinationNode: string | undefined;
|
destinationNode: string | undefined;
|
||||||
|
triggerNode: string | undefined;
|
||||||
directParentNodes: string[];
|
directParentNodes: string[];
|
||||||
source: string | undefined;
|
source: string | undefined;
|
||||||
getTestUrl: (node: INode) => string;
|
getTestUrl: (node: INode) => string;
|
||||||
}) {
|
}) {
|
||||||
for (const node of nodes) {
|
for (const node of nodes) {
|
||||||
|
if (triggerNode !== undefined && triggerNode !== node.name) continue;
|
||||||
|
|
||||||
const hasNodeRun = runData && runData?.hasOwnProperty(node.name);
|
const hasNodeRun = runData && runData?.hasOwnProperty(node.name);
|
||||||
|
|
||||||
if (hasNodeRun || pinData[node.name]) continue;
|
if (hasNodeRun || pinData[node.name]) continue;
|
||||||
|
|
Loading…
Reference in a new issue