@xtr-dev/payload-automation 0.0.38 → 0.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/collections/Workflow.js +2 -4
- package/dist/collections/Workflow.js.map +1 -1
- package/dist/components/WorkflowBuilder/StepConfigurationForm.js +316 -0
- package/dist/components/WorkflowBuilder/StepConfigurationForm.js.map +1 -0
- package/dist/components/WorkflowBuilder/WorkflowBuilder.js +211 -0
- package/dist/components/WorkflowBuilder/WorkflowBuilder.js.map +1 -0
- package/dist/components/WorkflowBuilder/WorkflowToolbar.js +107 -0
- package/dist/components/WorkflowBuilder/WorkflowToolbar.js.map +1 -0
- package/dist/components/WorkflowBuilder/index.js +6 -0
- package/dist/components/WorkflowBuilder/index.js.map +1 -0
- package/dist/components/WorkflowBuilder/nodes/StepNode.js +139 -0
- package/dist/components/WorkflowBuilder/nodes/StepNode.js.map +1 -0
- package/dist/core/workflow-executor.js +150 -116
- package/dist/core/workflow-executor.js.map +1 -1
- package/dist/fields/WorkflowBuilderField.js +119 -0
- package/dist/fields/WorkflowBuilderField.js.map +1 -0
- package/dist/plugin/collection-hook.js +34 -0
- package/dist/plugin/collection-hook.js.map +1 -1
- package/package.json +4 -3
- package/dist/collections/Workflow.d.ts +0 -3
- package/dist/collections/WorkflowRuns.d.ts +0 -2
- package/dist/components/ErrorDisplay.d.ts +0 -9
- package/dist/components/StatusCell.d.ts +0 -6
- package/dist/core/trigger-custom-workflow.d.ts +0 -52
- package/dist/core/workflow-executor.d.ts +0 -90
- package/dist/exports/client.d.ts +0 -2
- package/dist/exports/fields.d.ts +0 -1
- package/dist/exports/rsc.d.ts +0 -1
- package/dist/exports/server.d.ts +0 -5
- package/dist/exports/views.d.ts +0 -1
- package/dist/fields/parameter.d.ts +0 -4
- package/dist/index.d.ts +0 -2
- package/dist/plugin/collection-hook.d.ts +0 -1
- package/dist/plugin/config-types.d.ts +0 -18
- package/dist/plugin/global-hook.d.ts +0 -1
- package/dist/plugin/index.d.ts +0 -4
- package/dist/plugin/logger.d.ts +0 -20
- package/dist/steps/create-document-handler.d.ts +0 -2
- package/dist/steps/create-document.d.ts +0 -46
- package/dist/steps/delete-document-handler.d.ts +0 -2
- package/dist/steps/delete-document.d.ts +0 -39
- package/dist/steps/http-request-handler.d.ts +0 -2
- package/dist/steps/http-request.d.ts +0 -155
- package/dist/steps/index.d.ts +0 -12
- package/dist/steps/read-document-handler.d.ts +0 -2
- package/dist/steps/read-document.d.ts +0 -46
- package/dist/steps/send-email-handler.d.ts +0 -2
- package/dist/steps/send-email.d.ts +0 -44
- package/dist/steps/update-document-handler.d.ts +0 -2
- package/dist/steps/update-document.d.ts +0 -46
- package/dist/test/basic.test.js +0 -14
- package/dist/test/basic.test.js.map +0 -1
- package/dist/test/create-document-step.test.js +0 -378
- package/dist/test/create-document-step.test.js.map +0 -1
- package/dist/test/http-request-step.test.js +0 -361
- package/dist/test/http-request-step.test.js.map +0 -1
- package/dist/test/workflow-executor.test.js +0 -530
- package/dist/test/workflow-executor.test.js.map +0 -1
- package/dist/triggers/collection-trigger.d.ts +0 -2
- package/dist/triggers/global-trigger.d.ts +0 -2
- package/dist/triggers/index.d.ts +0 -2
- package/dist/triggers/types.d.ts +0 -5
- package/dist/types/index.d.ts +0 -31
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { createDocumentHandler } from '../steps/create-document-handler.js';
|
|
3
|
-
describe('CreateDocumentStepHandler', ()=>{
|
|
4
|
-
let mockPayload;
|
|
5
|
-
let mockReq;
|
|
6
|
-
beforeEach(()=>{
|
|
7
|
-
mockPayload = {
|
|
8
|
-
create: vi.fn()
|
|
9
|
-
};
|
|
10
|
-
mockReq = {
|
|
11
|
-
payload: mockPayload,
|
|
12
|
-
user: {
|
|
13
|
-
id: 'user-123',
|
|
14
|
-
email: 'test@example.com'
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
vi.clearAllMocks();
|
|
18
|
-
});
|
|
19
|
-
describe('Document creation', ()=>{
|
|
20
|
-
it('should create document successfully', async ()=>{
|
|
21
|
-
const createdDoc = {
|
|
22
|
-
id: 'doc-123',
|
|
23
|
-
title: 'Test Document',
|
|
24
|
-
content: 'Test content'
|
|
25
|
-
};
|
|
26
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
27
|
-
const input = {
|
|
28
|
-
collectionSlug: 'posts',
|
|
29
|
-
data: {
|
|
30
|
-
title: 'Test Document',
|
|
31
|
-
content: 'Test content'
|
|
32
|
-
},
|
|
33
|
-
stepName: 'test-create-step'
|
|
34
|
-
};
|
|
35
|
-
const result = await createDocumentHandler({
|
|
36
|
-
input,
|
|
37
|
-
req: mockReq
|
|
38
|
-
});
|
|
39
|
-
expect(result.state).toBe('succeeded');
|
|
40
|
-
expect(result.output.document).toEqual(createdDoc);
|
|
41
|
-
expect(result.output.id).toBe('doc-123');
|
|
42
|
-
expect(mockPayload.create).toHaveBeenCalledWith({
|
|
43
|
-
collection: 'posts',
|
|
44
|
-
data: {
|
|
45
|
-
title: 'Test Document',
|
|
46
|
-
content: 'Test content'
|
|
47
|
-
},
|
|
48
|
-
req: mockReq
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
it('should create document with relationship fields', async ()=>{
|
|
52
|
-
const createdDoc = {
|
|
53
|
-
id: 'doc-456',
|
|
54
|
-
title: 'Related Document',
|
|
55
|
-
author: 'user-123',
|
|
56
|
-
category: 'cat-789'
|
|
57
|
-
};
|
|
58
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
59
|
-
const input = {
|
|
60
|
-
collectionSlug: 'articles',
|
|
61
|
-
data: {
|
|
62
|
-
title: 'Related Document',
|
|
63
|
-
author: 'user-123',
|
|
64
|
-
category: 'cat-789'
|
|
65
|
-
},
|
|
66
|
-
stepName: 'test-create-with-relations'
|
|
67
|
-
};
|
|
68
|
-
const result = await createDocumentHandler({
|
|
69
|
-
input,
|
|
70
|
-
req: mockReq
|
|
71
|
-
});
|
|
72
|
-
expect(result.state).toBe('succeeded');
|
|
73
|
-
expect(result.output.document).toEqual(createdDoc);
|
|
74
|
-
expect(mockPayload.create).toHaveBeenCalledWith({
|
|
75
|
-
collection: 'articles',
|
|
76
|
-
data: {
|
|
77
|
-
title: 'Related Document',
|
|
78
|
-
author: 'user-123',
|
|
79
|
-
category: 'cat-789'
|
|
80
|
-
},
|
|
81
|
-
req: mockReq
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
it('should create document with complex nested data', async ()=>{
|
|
85
|
-
const complexData = {
|
|
86
|
-
title: 'Complex Document',
|
|
87
|
-
metadata: {
|
|
88
|
-
tags: [
|
|
89
|
-
'tag1',
|
|
90
|
-
'tag2'
|
|
91
|
-
],
|
|
92
|
-
settings: {
|
|
93
|
-
featured: true,
|
|
94
|
-
priority: 5
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
blocks: [
|
|
98
|
-
{
|
|
99
|
-
type: 'text',
|
|
100
|
-
content: 'Text block'
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
type: 'image',
|
|
104
|
-
src: 'image.jpg',
|
|
105
|
-
alt: 'Test image'
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
};
|
|
109
|
-
const createdDoc = {
|
|
110
|
-
id: 'doc-complex',
|
|
111
|
-
...complexData
|
|
112
|
-
};
|
|
113
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
114
|
-
const input = {
|
|
115
|
-
collectionSlug: 'pages',
|
|
116
|
-
data: complexData,
|
|
117
|
-
stepName: 'test-create-complex'
|
|
118
|
-
};
|
|
119
|
-
const result = await createDocumentHandler({
|
|
120
|
-
input,
|
|
121
|
-
req: mockReq
|
|
122
|
-
});
|
|
123
|
-
expect(result.state).toBe('succeeded');
|
|
124
|
-
expect(result.output.document).toEqual(createdDoc);
|
|
125
|
-
expect(mockPayload.create).toHaveBeenCalledWith({
|
|
126
|
-
collection: 'pages',
|
|
127
|
-
data: complexData,
|
|
128
|
-
req: mockReq
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe('Error handling', ()=>{
|
|
133
|
-
it('should handle PayloadCMS validation errors', async ()=>{
|
|
134
|
-
const validationError = new Error('Validation failed');
|
|
135
|
-
validationError.data = [
|
|
136
|
-
{
|
|
137
|
-
message: 'Title is required',
|
|
138
|
-
path: 'title',
|
|
139
|
-
value: undefined
|
|
140
|
-
}
|
|
141
|
-
];
|
|
142
|
-
mockPayload.create.mockRejectedValue(validationError);
|
|
143
|
-
const input = {
|
|
144
|
-
collectionSlug: 'posts',
|
|
145
|
-
data: {
|
|
146
|
-
content: 'Missing title'
|
|
147
|
-
},
|
|
148
|
-
stepName: 'test-validation-error'
|
|
149
|
-
};
|
|
150
|
-
const result = await createDocumentHandler({
|
|
151
|
-
input,
|
|
152
|
-
req: mockReq
|
|
153
|
-
});
|
|
154
|
-
expect(result.state).toBe('failed');
|
|
155
|
-
expect(result.error).toContain('Validation failed');
|
|
156
|
-
});
|
|
157
|
-
it('should handle permission errors', async ()=>{
|
|
158
|
-
const permissionError = new Error('Insufficient permissions');
|
|
159
|
-
permissionError.status = 403;
|
|
160
|
-
mockPayload.create.mockRejectedValue(permissionError);
|
|
161
|
-
const input = {
|
|
162
|
-
collectionSlug: 'admin-only',
|
|
163
|
-
data: {
|
|
164
|
-
secret: 'confidential data'
|
|
165
|
-
},
|
|
166
|
-
stepName: 'test-permission-error'
|
|
167
|
-
};
|
|
168
|
-
const result = await createDocumentHandler({
|
|
169
|
-
input,
|
|
170
|
-
req: mockReq
|
|
171
|
-
});
|
|
172
|
-
expect(result.state).toBe('failed');
|
|
173
|
-
expect(result.error).toContain('Insufficient permissions');
|
|
174
|
-
});
|
|
175
|
-
it('should handle database connection errors', async ()=>{
|
|
176
|
-
const dbError = new Error('Database connection failed');
|
|
177
|
-
mockPayload.create.mockRejectedValue(dbError);
|
|
178
|
-
const input = {
|
|
179
|
-
collectionSlug: 'posts',
|
|
180
|
-
data: {
|
|
181
|
-
title: 'Test'
|
|
182
|
-
},
|
|
183
|
-
stepName: 'test-db-error'
|
|
184
|
-
};
|
|
185
|
-
const result = await createDocumentHandler({
|
|
186
|
-
input,
|
|
187
|
-
req: mockReq
|
|
188
|
-
});
|
|
189
|
-
expect(result.state).toBe('failed');
|
|
190
|
-
expect(result.error).toContain('Database connection failed');
|
|
191
|
-
});
|
|
192
|
-
it('should handle unknown collection errors', async ()=>{
|
|
193
|
-
const collectionError = new Error('Collection "unknown" not found');
|
|
194
|
-
mockPayload.create.mockRejectedValue(collectionError);
|
|
195
|
-
const input = {
|
|
196
|
-
collectionSlug: 'unknown-collection',
|
|
197
|
-
data: {
|
|
198
|
-
title: 'Test'
|
|
199
|
-
},
|
|
200
|
-
stepName: 'test-unknown-collection'
|
|
201
|
-
};
|
|
202
|
-
const result = await createDocumentHandler({
|
|
203
|
-
input,
|
|
204
|
-
req: mockReq
|
|
205
|
-
});
|
|
206
|
-
expect(result.state).toBe('failed');
|
|
207
|
-
expect(result.error).toContain('Collection "unknown" not found');
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
describe('Input validation', ()=>{
|
|
211
|
-
it('should validate required collection slug', async ()=>{
|
|
212
|
-
const input = {
|
|
213
|
-
data: {
|
|
214
|
-
title: 'Test'
|
|
215
|
-
},
|
|
216
|
-
stepName: 'test-missing-collection'
|
|
217
|
-
};
|
|
218
|
-
const result = await createDocumentStepHandler({
|
|
219
|
-
input,
|
|
220
|
-
req: mockReq
|
|
221
|
-
});
|
|
222
|
-
expect(result.state).toBe('failed');
|
|
223
|
-
expect(result.error).toContain('Collection slug is required');
|
|
224
|
-
});
|
|
225
|
-
it('should validate required data field', async ()=>{
|
|
226
|
-
const input = {
|
|
227
|
-
collectionSlug: 'posts',
|
|
228
|
-
stepName: 'test-missing-data'
|
|
229
|
-
};
|
|
230
|
-
const result = await createDocumentStepHandler({
|
|
231
|
-
input,
|
|
232
|
-
req: mockReq
|
|
233
|
-
});
|
|
234
|
-
expect(result.state).toBe('failed');
|
|
235
|
-
expect(result.error).toContain('Data is required');
|
|
236
|
-
});
|
|
237
|
-
it('should validate data is an object', async ()=>{
|
|
238
|
-
const input = {
|
|
239
|
-
collectionSlug: 'posts',
|
|
240
|
-
data: 'invalid-data-type',
|
|
241
|
-
stepName: 'test-invalid-data-type'
|
|
242
|
-
};
|
|
243
|
-
const result = await createDocumentStepHandler({
|
|
244
|
-
input,
|
|
245
|
-
req: mockReq
|
|
246
|
-
});
|
|
247
|
-
expect(result.state).toBe('failed');
|
|
248
|
-
expect(result.error).toContain('Data must be an object');
|
|
249
|
-
});
|
|
250
|
-
it('should handle empty data object', async ()=>{
|
|
251
|
-
const createdDoc = {
|
|
252
|
-
id: 'empty-doc'
|
|
253
|
-
};
|
|
254
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
255
|
-
const input = {
|
|
256
|
-
collectionSlug: 'posts',
|
|
257
|
-
data: {},
|
|
258
|
-
stepName: 'test-empty-data'
|
|
259
|
-
};
|
|
260
|
-
const result = await createDocumentHandler({
|
|
261
|
-
input,
|
|
262
|
-
req: mockReq
|
|
263
|
-
});
|
|
264
|
-
expect(result.state).toBe('succeeded');
|
|
265
|
-
expect(result.output.document).toEqual(createdDoc);
|
|
266
|
-
expect(mockPayload.create).toHaveBeenCalledWith({
|
|
267
|
-
collection: 'posts',
|
|
268
|
-
data: {},
|
|
269
|
-
req: mockReq
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
describe('Request context', ()=>{
|
|
274
|
-
it('should pass user context from request', async ()=>{
|
|
275
|
-
const createdDoc = {
|
|
276
|
-
id: 'user-doc',
|
|
277
|
-
title: 'User Document'
|
|
278
|
-
};
|
|
279
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
280
|
-
const input = {
|
|
281
|
-
collectionSlug: 'posts',
|
|
282
|
-
data: {
|
|
283
|
-
title: 'User Document'
|
|
284
|
-
},
|
|
285
|
-
stepName: 'test-user-context'
|
|
286
|
-
};
|
|
287
|
-
await createDocumentStepHandler({
|
|
288
|
-
input,
|
|
289
|
-
req: mockReq
|
|
290
|
-
});
|
|
291
|
-
const createCall = mockPayload.create.mock.calls[0][0];
|
|
292
|
-
expect(createCall.req).toBe(mockReq);
|
|
293
|
-
expect(createCall.req.user).toEqual({
|
|
294
|
-
id: 'user-123',
|
|
295
|
-
email: 'test@example.com'
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
it('should handle requests without user context', async ()=>{
|
|
299
|
-
const reqWithoutUser = {
|
|
300
|
-
payload: mockPayload,
|
|
301
|
-
user: null
|
|
302
|
-
};
|
|
303
|
-
const createdDoc = {
|
|
304
|
-
id: 'anonymous-doc'
|
|
305
|
-
};
|
|
306
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
307
|
-
const input = {
|
|
308
|
-
collectionSlug: 'posts',
|
|
309
|
-
data: {
|
|
310
|
-
title: 'Anonymous Document'
|
|
311
|
-
},
|
|
312
|
-
stepName: 'test-anonymous'
|
|
313
|
-
};
|
|
314
|
-
const result = await createDocumentStepHandler({
|
|
315
|
-
input,
|
|
316
|
-
req: reqWithoutUser
|
|
317
|
-
});
|
|
318
|
-
expect(result.state).toBe('succeeded');
|
|
319
|
-
expect(mockPayload.create).toHaveBeenCalledWith({
|
|
320
|
-
collection: 'posts',
|
|
321
|
-
data: {
|
|
322
|
-
title: 'Anonymous Document'
|
|
323
|
-
},
|
|
324
|
-
req: reqWithoutUser
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
describe('Output structure', ()=>{
|
|
329
|
-
it('should return correct output structure on success', async ()=>{
|
|
330
|
-
const createdDoc = {
|
|
331
|
-
id: 'output-test-doc',
|
|
332
|
-
title: 'Output Test',
|
|
333
|
-
createdAt: '2024-01-01T00:00:00.000Z',
|
|
334
|
-
updatedAt: '2024-01-01T00:00:00.000Z'
|
|
335
|
-
};
|
|
336
|
-
mockPayload.create.mockResolvedValue(createdDoc);
|
|
337
|
-
const input = {
|
|
338
|
-
collectionSlug: 'posts',
|
|
339
|
-
data: {
|
|
340
|
-
title: 'Output Test'
|
|
341
|
-
},
|
|
342
|
-
stepName: 'test-output-structure'
|
|
343
|
-
};
|
|
344
|
-
const result = await createDocumentHandler({
|
|
345
|
-
input,
|
|
346
|
-
req: mockReq
|
|
347
|
-
});
|
|
348
|
-
expect(result).toEqual({
|
|
349
|
-
state: 'succeeded',
|
|
350
|
-
output: {
|
|
351
|
-
document: createdDoc,
|
|
352
|
-
id: 'output-test-doc'
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
it('should return correct error structure on failure', async ()=>{
|
|
357
|
-
const error = new Error('Test error');
|
|
358
|
-
mockPayload.create.mockRejectedValue(error);
|
|
359
|
-
const input = {
|
|
360
|
-
collectionSlug: 'posts',
|
|
361
|
-
data: {
|
|
362
|
-
title: 'Error Test'
|
|
363
|
-
},
|
|
364
|
-
stepName: 'test-error-structure'
|
|
365
|
-
};
|
|
366
|
-
const result = await createDocumentHandler({
|
|
367
|
-
input,
|
|
368
|
-
req: mockReq
|
|
369
|
-
});
|
|
370
|
-
expect(result).toEqual({
|
|
371
|
-
state: 'failed',
|
|
372
|
-
error: 'Test error'
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
});
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
//# sourceMappingURL=create-document-step.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/create-document-step.test.ts"],"sourcesContent":["import { describe, it, expect, vi, beforeEach } from 'vitest'\nimport { createDocumentHandler } from '../steps/create-document-handler.js'\nimport type { Payload } from 'payload'\n\ndescribe('CreateDocumentStepHandler', () => {\n let mockPayload: Payload\n let mockReq: any\n\n beforeEach(() => {\n mockPayload = {\n create: vi.fn()\n } as any\n\n mockReq = {\n payload: mockPayload,\n user: { id: 'user-123', email: 'test@example.com' }\n }\n vi.clearAllMocks()\n })\n\n describe('Document creation', () => {\n it('should create document successfully', async () => {\n const createdDoc = {\n id: 'doc-123',\n title: 'Test Document',\n content: 'Test content'\n }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'posts',\n data: {\n title: 'Test Document',\n content: 'Test content'\n },\n stepName: 'test-create-step'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('succeeded')\n expect(result.output.document).toEqual(createdDoc)\n expect(result.output.id).toBe('doc-123')\n\n expect(mockPayload.create).toHaveBeenCalledWith({\n collection: 'posts',\n data: {\n title: 'Test Document',\n content: 'Test content'\n },\n req: mockReq\n })\n })\n\n it('should create document with relationship fields', async () => {\n const createdDoc = {\n id: 'doc-456',\n title: 'Related Document',\n author: 'user-123',\n category: 'cat-789'\n }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'articles',\n data: {\n title: 'Related Document',\n author: 'user-123',\n category: 'cat-789'\n },\n stepName: 'test-create-with-relations'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('succeeded')\n expect(result.output.document).toEqual(createdDoc)\n expect(mockPayload.create).toHaveBeenCalledWith({\n collection: 'articles',\n data: {\n title: 'Related Document',\n author: 'user-123',\n category: 'cat-789'\n },\n req: mockReq\n })\n })\n\n it('should create document with complex nested data', async () => {\n const complexData = {\n title: 'Complex Document',\n metadata: {\n tags: ['tag1', 'tag2'],\n settings: {\n featured: true,\n priority: 5\n }\n },\n blocks: [\n { type: 'text', content: 'Text block' },\n { type: 'image', src: 'image.jpg', alt: 'Test image' }\n ]\n }\n\n const createdDoc = { id: 'doc-complex', ...complexData }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'pages',\n data: complexData,\n stepName: 'test-create-complex'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('succeeded')\n expect(result.output.document).toEqual(createdDoc)\n expect(mockPayload.create).toHaveBeenCalledWith({\n collection: 'pages',\n data: complexData,\n req: mockReq\n })\n })\n })\n\n describe('Error handling', () => {\n it('should handle PayloadCMS validation errors', async () => {\n const validationError = new Error('Validation failed')\n ;(validationError as any).data = [\n {\n message: 'Title is required',\n path: 'title',\n value: undefined\n }\n ]\n ;(mockPayload.create as any).mockRejectedValue(validationError)\n\n const input = {\n collectionSlug: 'posts',\n data: {\n content: 'Missing title'\n },\n stepName: 'test-validation-error'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Validation failed')\n })\n\n it('should handle permission errors', async () => {\n const permissionError = new Error('Insufficient permissions')\n ;(permissionError as any).status = 403\n ;(mockPayload.create as any).mockRejectedValue(permissionError)\n\n const input = {\n collectionSlug: 'admin-only',\n data: {\n secret: 'confidential data'\n },\n stepName: 'test-permission-error'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Insufficient permissions')\n })\n\n it('should handle database connection errors', async () => {\n const dbError = new Error('Database connection failed')\n ;(mockPayload.create as any).mockRejectedValue(dbError)\n\n const input = {\n collectionSlug: 'posts',\n data: { title: 'Test' },\n stepName: 'test-db-error'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Database connection failed')\n })\n\n it('should handle unknown collection errors', async () => {\n const collectionError = new Error('Collection \"unknown\" not found')\n ;(mockPayload.create as any).mockRejectedValue(collectionError)\n\n const input = {\n collectionSlug: 'unknown-collection',\n data: { title: 'Test' },\n stepName: 'test-unknown-collection'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Collection \"unknown\" not found')\n })\n })\n\n describe('Input validation', () => {\n it('should validate required collection slug', async () => {\n const input = {\n data: { title: 'Test' },\n stepName: 'test-missing-collection'\n }\n\n const result = await createDocumentStepHandler({ input, req: mockReq } as any)\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Collection slug is required')\n })\n\n it('should validate required data field', async () => {\n const input = {\n collectionSlug: 'posts',\n stepName: 'test-missing-data'\n }\n\n const result = await createDocumentStepHandler({ input, req: mockReq } as any)\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Data is required')\n })\n\n it('should validate data is an object', async () => {\n const input = {\n collectionSlug: 'posts',\n data: 'invalid-data-type',\n stepName: 'test-invalid-data-type'\n }\n\n const result = await createDocumentStepHandler({ input, req: mockReq } as any)\n\n expect(result.state).toBe('failed')\n expect(result.error).toContain('Data must be an object')\n })\n\n it('should handle empty data object', async () => {\n const createdDoc = { id: 'empty-doc' }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'posts',\n data: {},\n stepName: 'test-empty-data'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result.state).toBe('succeeded')\n expect(result.output.document).toEqual(createdDoc)\n expect(mockPayload.create).toHaveBeenCalledWith({\n collection: 'posts',\n data: {},\n req: mockReq\n })\n })\n })\n\n describe('Request context', () => {\n it('should pass user context from request', async () => {\n const createdDoc = { id: 'user-doc', title: 'User Document' }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'posts',\n data: { title: 'User Document' },\n stepName: 'test-user-context'\n }\n\n await createDocumentStepHandler({ input, req: mockReq })\n\n const createCall = (mockPayload.create as any).mock.calls[0][0]\n expect(createCall.req).toBe(mockReq)\n expect(createCall.req.user).toEqual({\n id: 'user-123',\n email: 'test@example.com'\n })\n })\n\n it('should handle requests without user context', async () => {\n const reqWithoutUser = {\n payload: mockPayload,\n user: null\n }\n\n const createdDoc = { id: 'anonymous-doc' }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'posts',\n data: { title: 'Anonymous Document' },\n stepName: 'test-anonymous'\n }\n\n const result = await createDocumentStepHandler({ input, req: reqWithoutUser })\n\n expect(result.state).toBe('succeeded')\n expect(mockPayload.create).toHaveBeenCalledWith({\n collection: 'posts',\n data: { title: 'Anonymous Document' },\n req: reqWithoutUser\n })\n })\n })\n\n describe('Output structure', () => {\n it('should return correct output structure on success', async () => {\n const createdDoc = {\n id: 'output-test-doc',\n title: 'Output Test',\n createdAt: '2024-01-01T00:00:00.000Z',\n updatedAt: '2024-01-01T00:00:00.000Z'\n }\n ;(mockPayload.create as any).mockResolvedValue(createdDoc)\n\n const input = {\n collectionSlug: 'posts',\n data: { title: 'Output Test' },\n stepName: 'test-output-structure'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result).toEqual({\n state: 'succeeded',\n output: {\n document: createdDoc,\n id: 'output-test-doc'\n }\n })\n })\n\n it('should return correct error structure on failure', async () => {\n const error = new Error('Test error')\n ;(mockPayload.create as any).mockRejectedValue(error)\n\n const input = {\n collectionSlug: 'posts',\n data: { title: 'Error Test' },\n stepName: 'test-error-structure'\n }\n\n const result = await createDocumentHandler({ input, req: mockReq })\n\n expect(result).toEqual({\n state: 'failed',\n error: 'Test error'\n })\n })\n })\n})"],"names":["describe","it","expect","vi","beforeEach","createDocumentHandler","mockPayload","mockReq","create","fn","payload","user","id","email","clearAllMocks","createdDoc","title","content","mockResolvedValue","input","collectionSlug","data","stepName","result","req","state","toBe","output","document","toEqual","toHaveBeenCalledWith","collection","author","category","complexData","metadata","tags","settings","featured","priority","blocks","type","src","alt","validationError","Error","message","path","value","undefined","mockRejectedValue","error","toContain","permissionError","status","secret","dbError","collectionError","createDocumentStepHandler","createCall","mock","calls","reqWithoutUser","createdAt","updatedAt"],"mappings":"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"}
|