mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(API): Accept workflow descriptions on creation (#39705)
Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
This commit is contained in:
parent
5676882e64
commit
6c1edac204
|
|
@ -17,6 +17,22 @@ const validPayload = {
|
|||
};
|
||||
|
||||
describe('CreateWorkflowPublicDto', () => {
|
||||
test('accepts an optional workflow description', () => {
|
||||
const payload = { ...validPayload, description: 'What this workflow does' };
|
||||
|
||||
expect(CreateWorkflowPublicDto.safeParse(payload)).toMatchObject({
|
||||
success: true,
|
||||
data: { description: payload.description },
|
||||
});
|
||||
expect(CreateWorkflowPublicDto.safeParse(validPayload).success).toBe(true);
|
||||
});
|
||||
|
||||
test('rejects a non-string workflow description', () => {
|
||||
expect(CreateWorkflowPublicDto.safeParse({ ...validPayload, description: 42 }).success).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects an unknown key through both the DTO and its schema', () => {
|
||||
const payload = { ...validPayload, notAWorkflowField: 'x' };
|
||||
|
||||
|
|
|
|||
|
|
@ -151,13 +151,7 @@ const staticDataWritePublicSchema = z
|
|||
.nullable()
|
||||
.openapi(workflowCreateFieldDocs.staticData);
|
||||
|
||||
/**
|
||||
* The public workflow write surface, shared by the create and update request bodies.
|
||||
*
|
||||
* `CreateWorkflowPublicDto` uses it as-is. `UpdateWorkflowPublicDto` omits `projectId` from its
|
||||
* shape, since a project is only chosen when a workflow is created, and adds `description`, which
|
||||
* only the update body has ever accepted.
|
||||
*/
|
||||
// Each route adds `description` to its own DTO so their request schemas stay independent.
|
||||
export const workflowWritePublicShape = {
|
||||
id: readOnlyPublicSchema(workflowCreateReadOnlyFieldDocs.id),
|
||||
name: z.string().openapi(workflowCreateFieldDocs.name),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
import { workflowWritePublicShape } from './base-workflow-public.dto';
|
||||
import { workflowCreateFieldDocs } from './workflow-public.openapi';
|
||||
import { Z } from '../../zod-class';
|
||||
|
||||
export class CreateWorkflowPublicDto extends Z.class(workflowWritePublicShape, {
|
||||
strict: true,
|
||||
}) {}
|
||||
export class CreateWorkflowPublicDto extends Z.class(
|
||||
{
|
||||
...workflowWritePublicShape,
|
||||
description: z.string().optional().openapi(workflowCreateFieldDocs.description),
|
||||
},
|
||||
{ strict: true },
|
||||
) {}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@ export const workflowSettingsFieldDocs = {
|
|||
|
||||
export const workflowCreateFieldDocs = {
|
||||
name: { example: 'Workflow 1' },
|
||||
description: {
|
||||
description: 'Description of the workflow',
|
||||
example: 'My workflow description',
|
||||
},
|
||||
nodes: { description: 'Nodes that make up the workflow' },
|
||||
nodeGroups: { description: 'Visual groupings of nodes shown as frames on the canvas' },
|
||||
staticData: { description: 'Data the workflow keeps between executions', example: { lastId: 1 } },
|
||||
|
|
|
|||
|
|
@ -553,6 +553,10 @@ requestBody:
|
|||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
description:
|
||||
type: string
|
||||
description: Description of the workflow
|
||||
example: My workflow description
|
||||
required:
|
||||
- name
|
||||
- nodes
|
||||
|
|
|
|||
|
|
@ -2202,6 +2202,19 @@ describe('POST /workflows', () => {
|
|||
expect(sharedWorkflow?.role).toEqual('workflow:owner');
|
||||
});
|
||||
|
||||
test('should create a workflow with a description', async () => {
|
||||
const description = 'What this workflow does';
|
||||
const response = await authMemberAgent.post('/workflows').send({
|
||||
...mockPostWorkflowPayload(),
|
||||
description,
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.body.description).toBe(description);
|
||||
const stored = await workflowRepository.findOneBy({ id: response.body.id });
|
||||
expect(stored?.description).toBe(description);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ key: 'binaryMode', value: 'combined' },
|
||||
{ key: 'credentialResolverId', value: 'some-resolver-id' },
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user