From 6abb1f9374d23aa89373467b23ceaa87212ba721 Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Tue, 11 Feb 2025 14:52:21 +0200 Subject: [PATCH] fix(n8n Form Trigger Node): Update error in validateResponseModeConfiguration (no-changelog) (#13162) --- .../Form/test/FormTriggerV2.node.test.ts | 3 +- .../nodes-base/nodes/Form/test/utils.test.ts | 56 +++++++++++++++++++ packages/nodes-base/nodes/Form/utils.ts | 18 +++++- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/packages/nodes-base/nodes/Form/test/FormTriggerV2.node.test.ts b/packages/nodes-base/nodes/Form/test/FormTriggerV2.node.test.ts index 9c6917906697f..fe2b9a5a41db7 100644 --- a/packages/nodes-base/nodes/Form/test/FormTriggerV2.node.test.ts +++ b/packages/nodes-base/nodes/Form/test/FormTriggerV2.node.test.ts @@ -190,8 +190,9 @@ describe('FormTrigger', () => { ); await expect( - testVersionedWebhookTriggerNode(FormTrigger, 2, { + testVersionedWebhookTriggerNode(FormTrigger, 2.1, { node: { + typeVersion: 2.1, parameters: { responseMode: 'onReceived', }, diff --git a/packages/nodes-base/nodes/Form/test/utils.test.ts b/packages/nodes-base/nodes/Form/test/utils.test.ts index 8fe48b57d6ed2..432bce51215e9 100644 --- a/packages/nodes-base/nodes/Form/test/utils.test.ts +++ b/packages/nodes-base/nodes/Form/test/utils.test.ts @@ -16,6 +16,7 @@ import { resolveRawData, isFormConnected, sanitizeHtml, + validateResponseModeConfiguration, } from '../utils'; describe('FormTrigger, parseFormDescription', () => { @@ -939,3 +940,58 @@ describe('FormTrigger, isFormConnected', () => { expect(result).toBe(true); }); }); + +describe('validateResponseModeConfiguration', () => { + let webhookFunctions: ReturnType>; + + beforeEach(() => { + webhookFunctions = mock(); + + webhookFunctions.getNode.mockReturnValue({ + name: 'TestNode', + typeVersion: 2.2, + } as INode); + + webhookFunctions.getChildNodes.mockReturnValue([]); + }); + + test('throws error if responseMode is "responseNode" but no Respond to Webhook node is connected', () => { + webhookFunctions.getNodeParameter.mockReturnValue('responseNode'); + + expect(() => validateResponseModeConfiguration(webhookFunctions)).toThrow( + 'No Respond to Webhook node found in the workflow', + ); + }); + + test('throws error if "Respond to Webhook" node is connected but "responseMode" is not "responseNode" in typeVersion <= 2.1', () => { + webhookFunctions.getNodeParameter.mockReturnValue('onReceived'); + webhookFunctions.getNode.mockReturnValue({ + name: 'TestNode', + typeVersion: 2.1, + } as INode); + webhookFunctions.getChildNodes.mockReturnValue([ + { type: 'n8n-nodes-base.respondToWebhook' } as NodeTypeAndVersion, + ]); + + expect(() => validateResponseModeConfiguration(webhookFunctions)).toThrow( + 'TestNode node not correctly configured', + ); + }); + + test('throws error if "Respond to Webhook" node is connected, version >= 2.2', () => { + webhookFunctions.getNodeParameter.mockReturnValue('responseNode'); + webhookFunctions.getChildNodes.mockReturnValue([ + { type: 'n8n-nodes-base.respondToWebhook' } as NodeTypeAndVersion, + ]); + + expect(() => validateResponseModeConfiguration(webhookFunctions)).toThrow( + 'The "Respond to Webhook" node is not supported in workflows initiated by the "n8n Form Trigger"', + ); + }); + + test('does not throw an error mode in not "responseNode" and no "Respond to Webhook" node is connected', () => { + webhookFunctions.getNodeParameter.mockReturnValue('onReceived'); + + expect(() => validateResponseModeConfiguration(webhookFunctions)).not.toThrow(); + }); +}); diff --git a/packages/nodes-base/nodes/Form/utils.ts b/packages/nodes-base/nodes/Form/utils.ts index 114ccef35a9d8..e4d74bf406171 100644 --- a/packages/nodes-base/nodes/Form/utils.ts +++ b/packages/nodes-base/nodes/Form/utils.ts @@ -187,9 +187,10 @@ export function prepareFormData({ return formData; } -const validateResponseModeConfiguration = (context: IWebhookFunctions) => { +export const validateResponseModeConfiguration = (context: IWebhookFunctions) => { const responseMode = context.getNodeParameter('responseMode', 'onReceived') as string; const connectedNodes = context.getChildNodes(context.getNode().name); + const nodeVersion = context.getNode().typeVersion; const isRespondToWebhookConnected = connectedNodes.some( (node) => node.type === 'n8n-nodes-base.respondToWebhook', @@ -206,7 +207,7 @@ const validateResponseModeConfiguration = (context: IWebhookFunctions) => { ); } - if (isRespondToWebhookConnected && responseMode !== 'responseNode') { + if (isRespondToWebhookConnected && responseMode !== 'responseNode' && nodeVersion <= 2.1) { throw new NodeOperationError( context.getNode(), new Error(`${context.getNode().name} node not correctly configured`), @@ -216,6 +217,19 @@ const validateResponseModeConfiguration = (context: IWebhookFunctions) => { }, ); } + + if (isRespondToWebhookConnected && nodeVersion > 2.1) { + throw new NodeOperationError( + context.getNode(), + new Error( + 'The "Respond to Webhook" node is not supported in workflows initiated by the "n8n Form Trigger"', + ), + { + description: + 'To configure your response, add an "n8n Form" node and set the "Page Type" to "Form Ending"', + }, + ); + } }; export async function prepareFormReturnItem(