From c8a3de6c6591905c2d2efbc4ef79f65f6e84da33 Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Tue, 14 Apr 2026 14:21:48 +0200 Subject: [PATCH] Test workflow with webhook expected body (#19688) As title. Currently payload is always undefined when testing --- .../TestWorkflowSingleRecordCommand.tsx | 10 ++- .../getTestPayloadFromTrigger.test.ts | 75 +++++++++++++++++++ .../utils/getTestPayloadFromTrigger.ts | 28 +++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 packages/twenty-front/src/modules/workflow/workflow-trigger/utils/__tests__/getTestPayloadFromTrigger.test.ts create mode 100644 packages/twenty-front/src/modules/workflow/workflow-trigger/utils/getTestPayloadFromTrigger.ts diff --git a/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow/components/TestWorkflowSingleRecordCommand.tsx b/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow/components/TestWorkflowSingleRecordCommand.tsx index 2cddfd1ca3f..ee2bb611e64 100644 --- a/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow/components/TestWorkflowSingleRecordCommand.tsx +++ b/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow/components/TestWorkflowSingleRecordCommand.tsx @@ -2,6 +2,7 @@ import { HeadlessEngineCommandWrapperEffect } from '@/command-menu-item/engine-c import { useHeadlessCommandContextApi } from '@/command-menu-item/engine-command/hooks/useHeadlessCommandContextApi'; import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; +import { getTestPayloadFromTrigger } from '@/workflow/workflow-trigger/utils/getTestPayloadFromTrigger'; import { isDefined } from 'twenty-shared/utils'; export const TestWorkflowSingleRecordCommand = () => { @@ -22,9 +23,16 @@ export const TestWorkflowSingleRecordCommand = () => { return; } + const { currentVersion } = workflowWithCurrentVersion; + + if (!isDefined(currentVersion.trigger)) { + return; + } + runWorkflowVersion({ - workflowVersionId: workflowWithCurrentVersion.currentVersion.id, + workflowVersionId: currentVersion.id, workflowId: workflowWithCurrentVersion.id, + payload: getTestPayloadFromTrigger(currentVersion.trigger), }); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-trigger/utils/__tests__/getTestPayloadFromTrigger.test.ts b/packages/twenty-front/src/modules/workflow/workflow-trigger/utils/__tests__/getTestPayloadFromTrigger.test.ts new file mode 100644 index 00000000000..29950af3748 --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/workflow-trigger/utils/__tests__/getTestPayloadFromTrigger.test.ts @@ -0,0 +1,75 @@ +import { type WorkflowTrigger } from '@/workflow/types/Workflow'; +import { getTestPayloadFromTrigger } from '@/workflow/workflow-trigger/utils/getTestPayloadFromTrigger'; + +describe('getTestPayloadFromTrigger', () => { + it('returns undefined for a manual trigger', () => { + const trigger: WorkflowTrigger = { + type: 'MANUAL', + name: 'Test', + settings: { + outputSchema: {}, + }, + }; + + expect(getTestPayloadFromTrigger(trigger)).toBeUndefined(); + }); + + it('returns undefined for a cron trigger', () => { + const trigger: WorkflowTrigger = { + type: 'CRON', + name: 'Test', + settings: { + type: 'DAYS', + schedule: { day: 1, hour: 0, minute: 0 }, + outputSchema: {}, + }, + }; + + expect(getTestPayloadFromTrigger(trigger)).toBeUndefined(); + }); + + it('returns expectedBody for a POST webhook trigger', () => { + const expectedBody = { message: 'Workflow was started', count: 42 }; + const trigger: WorkflowTrigger = { + type: 'WEBHOOK', + name: 'Test', + settings: { + httpMethod: 'POST', + expectedBody, + outputSchema: {}, + authentication: null, + }, + }; + + expect(getTestPayloadFromTrigger(trigger)).toEqual(expectedBody); + }); + + it('returns undefined for a GET webhook trigger', () => { + const trigger: WorkflowTrigger = { + type: 'WEBHOOK', + name: 'Test', + settings: { + httpMethod: 'GET', + outputSchema: {}, + authentication: null, + }, + }; + + expect(getTestPayloadFromTrigger(trigger)).toBeUndefined(); + }); + + it('throws for a database event trigger', () => { + const trigger: WorkflowTrigger = { + type: 'DATABASE_EVENT', + name: 'Test', + settings: { + eventName: 'company.created', + outputSchema: {}, + }, + }; + + expect(() => getTestPayloadFromTrigger(trigger)).toThrow( + 'Test workflow is not supported for database event triggers', + ); + }); +}); diff --git a/packages/twenty-front/src/modules/workflow/workflow-trigger/utils/getTestPayloadFromTrigger.ts b/packages/twenty-front/src/modules/workflow/workflow-trigger/utils/getTestPayloadFromTrigger.ts new file mode 100644 index 00000000000..95e6c0c939c --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/workflow-trigger/utils/getTestPayloadFromTrigger.ts @@ -0,0 +1,28 @@ +import { type WorkflowTrigger } from '@/workflow/types/Workflow'; +import { assertUnreachable } from 'twenty-shared/utils'; + +export const getTestPayloadFromTrigger = ( + trigger: WorkflowTrigger, +): Record | undefined => { + switch (trigger.type) { + case 'MANUAL': + case 'CRON': { + return undefined; + } + case 'WEBHOOK': { + if (trigger.settings.httpMethod === 'POST') { + return trigger.settings.expectedBody; + } + + return undefined; + } + case 'DATABASE_EVENT': { + throw new Error( + 'Test workflow is not supported for database event triggers', + ); + } + default: { + return assertUnreachable(trigger, 'Unknown trigger type'); + } + } +};