mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +00:00
fix: Check if form trigger URL is live before oppening pop-up (#15800)
This commit is contained in:
@@ -381,7 +381,7 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
displayForm({
|
await displayForm({
|
||||||
nodes: workflowData.nodes,
|
nodes: workflowData.nodes,
|
||||||
runData: workflowsStore.getWorkflowExecution?.data?.resultData?.runData,
|
runData: workflowsStore.getWorkflowExecution?.data?.resultData?.runData,
|
||||||
destinationNode: options.destinationNode,
|
destinationNode: options.destinationNode,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { MockInstance } from 'vitest';
|
||||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
import {
|
import {
|
||||||
displayForm,
|
displayForm,
|
||||||
@@ -48,12 +49,24 @@ vi.mock('@/plugins/i18n', () => ({
|
|||||||
|
|
||||||
describe('displayForm', () => {
|
describe('displayForm', () => {
|
||||||
const getTestUrlMock = vi.fn();
|
const getTestUrlMock = vi.fn();
|
||||||
|
let fetchMock: MockInstance;
|
||||||
|
const successResponse = {
|
||||||
|
ok: true,
|
||||||
|
} as unknown as Response;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
fetchMock = vi.spyOn(global, 'fetch');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
fetchMock.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not call openPopUpWindow if node has already run or is pinned', () => {
|
it('should not call openPopUpWindow if node has already run or is pinned', async () => {
|
||||||
const nodes: INode[] = [
|
const nodes: INode[] = [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -76,7 +89,9 @@ describe('displayForm', () => {
|
|||||||
const runData: IRunData = { Node1: [] };
|
const runData: IRunData = { Node1: [] };
|
||||||
const pinData: IPinData = { Node2: [{ json: { data: {} } }] };
|
const pinData: IPinData = { Node2: [{ json: { data: {} } }] };
|
||||||
|
|
||||||
displayForm({
|
fetchMock.mockResolvedValue(successResponse);
|
||||||
|
|
||||||
|
await displayForm({
|
||||||
nodes,
|
nodes,
|
||||||
runData,
|
runData,
|
||||||
pinData,
|
pinData,
|
||||||
@@ -90,7 +105,7 @@ describe('displayForm', () => {
|
|||||||
expect(windowOpenSpy).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', async () => {
|
||||||
const nodes: INode[] = [
|
const nodes: INode[] = [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -110,7 +125,8 @@ describe('displayForm', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
displayForm({
|
fetchMock.mockResolvedValue(successResponse);
|
||||||
|
await displayForm({
|
||||||
nodes,
|
nodes,
|
||||||
runData: undefined,
|
runData: undefined,
|
||||||
pinData: {},
|
pinData: {},
|
||||||
@@ -124,7 +140,7 @@ describe('displayForm', () => {
|
|||||||
expect(windowOpenSpy).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"', async () => {
|
||||||
const nodes: INode[] = [
|
const nodes: INode[] = [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -138,7 +154,9 @@ describe('displayForm', () => {
|
|||||||
|
|
||||||
getTestUrlMock.mockReturnValue('http://test-url.com');
|
getTestUrlMock.mockReturnValue('http://test-url.com');
|
||||||
|
|
||||||
displayForm({
|
fetchMock.mockResolvedValue(successResponse);
|
||||||
|
|
||||||
|
await displayForm({
|
||||||
nodes,
|
nodes,
|
||||||
runData: undefined,
|
runData: undefined,
|
||||||
pinData: {},
|
pinData: {},
|
||||||
@@ -162,8 +180,9 @@ describe('displayForm', () => {
|
|||||||
getTestUrlMock.mockReturnValue('http://test-url.com');
|
getTestUrlMock.mockReturnValue('http://test-url.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open pop-up if the trigger node is a form node', () => {
|
it('should open pop-up if the trigger node is a form node', async () => {
|
||||||
displayForm({
|
fetchMock.mockResolvedValue(successResponse);
|
||||||
|
await displayForm({
|
||||||
nodes,
|
nodes,
|
||||||
runData: undefined,
|
runData: undefined,
|
||||||
pinData: {},
|
pinData: {},
|
||||||
@@ -177,8 +196,41 @@ describe('displayForm', () => {
|
|||||||
expect(windowOpenSpy).toHaveBeenCalled();
|
expect(windowOpenSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not open pop-up if the trigger node is specified and it isn't a form node", () => {
|
it('should not open pop-up if the trigger node is a form node but webhook url is not live', async () => {
|
||||||
displayForm({
|
fetchMock.mockResolvedValue({ ok: false });
|
||||||
|
await displayForm({
|
||||||
|
nodes,
|
||||||
|
runData: undefined,
|
||||||
|
pinData: {},
|
||||||
|
destinationNode: undefined,
|
||||||
|
triggerNode: 'Node1',
|
||||||
|
directParentNodes: [],
|
||||||
|
source: undefined,
|
||||||
|
getTestUrl: getTestUrlMock,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(windowOpenSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not open pop-up if the trigger node is a form node but fetch of webhook url throws', async () => {
|
||||||
|
fetchMock.mockRejectedValue(new Error());
|
||||||
|
await displayForm({
|
||||||
|
nodes,
|
||||||
|
runData: undefined,
|
||||||
|
pinData: {},
|
||||||
|
destinationNode: undefined,
|
||||||
|
triggerNode: 'Node1',
|
||||||
|
directParentNodes: [],
|
||||||
|
source: undefined,
|
||||||
|
getTestUrl: getTestUrlMock,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(windowOpenSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not open pop-up if the trigger node is specified and it isn't a form node", async () => {
|
||||||
|
fetchMock.mockResolvedValue(successResponse);
|
||||||
|
await displayForm({
|
||||||
nodes,
|
nodes,
|
||||||
runData: undefined,
|
runData: undefined,
|
||||||
pinData: {},
|
pinData: {},
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export const openFormPopupWindow = (url: string) => {
|
|||||||
|
|
||||||
export const clearPopupWindowState = () => (formPopupWindow = false);
|
export const clearPopupWindowState = () => (formPopupWindow = false);
|
||||||
|
|
||||||
export function displayForm({
|
export async function displayForm({
|
||||||
nodes,
|
nodes,
|
||||||
runData,
|
runData,
|
||||||
pinData,
|
pinData,
|
||||||
@@ -137,6 +137,14 @@ export function displayForm({
|
|||||||
if (node.name === destinationNode || !node.disabled) {
|
if (node.name === destinationNode || !node.disabled) {
|
||||||
let testUrl = '';
|
let testUrl = '';
|
||||||
if (node.type === FORM_TRIGGER_NODE_TYPE) testUrl = getTestUrl(node);
|
if (node.type === FORM_TRIGGER_NODE_TYPE) testUrl = getTestUrl(node);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(testUrl, { method: 'GET' });
|
||||||
|
if (!res.ok) continue;
|
||||||
|
} catch (error) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (testUrl && source !== 'RunData.ManualChatMessage') {
|
if (testUrl && source !== 'RunData.ManualChatMessage') {
|
||||||
clearPopupWindowState();
|
clearPopupWindowState();
|
||||||
openFormPopupWindow(testUrl);
|
openFormPopupWindow(testUrl);
|
||||||
|
|||||||
Reference in New Issue
Block a user