diff --git a/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts b/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts index 68bd19e3f12c2..0ad0dd85c3135 100644 --- a/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts +++ b/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts @@ -8,7 +8,16 @@ import type { INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { jsonParse, BINARY_ENCODING, NodeOperationError, NodeConnectionType } from 'n8n-workflow'; +import { + jsonParse, + BINARY_ENCODING, + NodeOperationError, + NodeConnectionType, + WEBHOOK_NODE_TYPE, + FORM_TRIGGER_NODE_TYPE, + CHAT_TRIGGER_NODE_TYPE, + WAIT_NODE_TYPE, +} from 'n8n-workflow'; import set from 'lodash/set'; import jwt from 'jsonwebtoken'; import { formatPrivateKey, generatePairedItemData } from '../../utils/utilities'; @@ -291,9 +300,10 @@ export class RespondToWebhook implements INodeType { const nodeVersion = this.getNode().typeVersion; const WEBHOOK_NODE_TYPES = [ - 'n8n-nodes-base.webhook', - 'n8n-nodes-base.formTrigger', - '@n8n/n8n-nodes-langchain.chatTrigger', + WEBHOOK_NODE_TYPE, + FORM_TRIGGER_NODE_TYPE, + CHAT_TRIGGER_NODE_TYPE, + WAIT_NODE_TYPE, ]; try { diff --git a/packages/nodes-base/nodes/RespondToWebhook/test/RespondToWebhook.test.ts b/packages/nodes-base/nodes/RespondToWebhook/test/RespondToWebhook.test.ts new file mode 100644 index 0000000000000..c090511552ea1 --- /dev/null +++ b/packages/nodes-base/nodes/RespondToWebhook/test/RespondToWebhook.test.ts @@ -0,0 +1,47 @@ +import type { MockProxy } from 'jest-mock-extended'; +import { mock } from 'jest-mock-extended'; +import { + WAIT_NODE_TYPE, + type IExecuteFunctions, + type INode, + type NodeTypeAndVersion, +} from 'n8n-workflow'; + +import { RespondToWebhook } from '../RespondToWebhook.node'; + +describe('RespondToWebhook Node', () => { + let respondToWebhook: RespondToWebhook; + let mockExecuteFunctions: MockProxy; + + beforeEach(() => { + respondToWebhook = new RespondToWebhook(); + mockExecuteFunctions = mock(); + }); + + describe('execute method', () => { + it('should throw an error if no WEBHOOK_NODE_TYPES in parents', async () => { + mockExecuteFunctions.getInputData.mockReturnValue([]); + mockExecuteFunctions.getNode.mockReturnValue(mock({ typeVersion: 1.1 })); + mockExecuteFunctions.getParentNodes.mockReturnValue([ + mock({ type: 'n8n-nodes-base.someNode' }), + ]); + + await expect(respondToWebhook.execute.call(mockExecuteFunctions)).rejects.toThrow( + 'No Webhook node found in the workflow', + ); + }); + it('should not throw an error if WEBHOOK_NODE_TYPES is in parents', async () => { + mockExecuteFunctions.getInputData.mockReturnValue([]); + mockExecuteFunctions.getNode.mockReturnValue(mock({ typeVersion: 1.1 })); + mockExecuteFunctions.getParentNodes.mockReturnValue([ + mock({ type: WAIT_NODE_TYPE }), + ]); + mockExecuteFunctions.getNodeParameter.mockReturnValue('text'); + mockExecuteFunctions.getNodeParameter.mockReturnValue({}); + mockExecuteFunctions.getNodeParameter.mockReturnValue('noData'); + mockExecuteFunctions.sendResponse.mockReturnValue(); + + await expect(respondToWebhook.execute.call(mockExecuteFunctions)).resolves.not.toThrow(); + }); + }); +}); diff --git a/packages/workflow/src/Constants.ts b/packages/workflow/src/Constants.ts index 95123c9793467..6ec9d47bb6ce5 100644 --- a/packages/workflow/src/Constants.ts +++ b/packages/workflow/src/Constants.ts @@ -38,6 +38,9 @@ export const FUNCTION_NODE_TYPE = 'n8n-nodes-base.function'; export const FUNCTION_ITEM_NODE_TYPE = 'n8n-nodes-base.functionItem'; export const MERGE_NODE_TYPE = 'n8n-nodes-base.merge'; export const AI_TRANSFORM_NODE_TYPE = 'n8n-nodes-base.aiTransform'; +export const FORM_TRIGGER_NODE_TYPE = 'n8n-nodes-base.formTrigger'; +export const CHAT_TRIGGER_NODE_TYPE = '@n8n/n8n-nodes-langchain.chatTrigger'; +export const WAIT_NODE_TYPE = 'n8n-nodes-base.wait'; export const STARTING_NODE_TYPES = [ MANUAL_TRIGGER_NODE_TYPE,