decap-server 1.4.0-beta.0

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.
@@ -0,0 +1,617 @@
1
+ import { defaultSchema, joi } from '.';
2
+
3
+ import type express from 'express';
4
+ import type Joi from '@hapi/joi';
5
+
6
+ function assetFailure(result: Joi.ValidationResult, expectedMessage: string) {
7
+ const { error } = result;
8
+ expect(error).not.toBeNull();
9
+ expect(error!.details).toHaveLength(1);
10
+ const message = error!.details.map(({ message }) => message)[0];
11
+ expect(message).toBe(expectedMessage);
12
+ }
13
+
14
+ const defaultParams = {
15
+ branch: 'master',
16
+ };
17
+
18
+ describe('defaultSchema', () => {
19
+ it('should fail on unsupported body', () => {
20
+ const schema = defaultSchema();
21
+
22
+ assetFailure(schema.validate({}), '"action" is required');
23
+ });
24
+
25
+ it('should fail on unsupported action', () => {
26
+ const schema = defaultSchema();
27
+
28
+ assetFailure(
29
+ schema.validate({ action: 'unknown', params: {} }),
30
+ '"action" must be one of [info, entriesByFolder, entriesByFiles, getEntry, unpublishedEntries, unpublishedEntry, unpublishedEntryDataFile, unpublishedEntryMediaFile, deleteUnpublishedEntry, persistEntry, updateUnpublishedEntryStatus, publishUnpublishedEntry, getMedia, getMediaFile, persistMedia, deleteFile, deleteFiles, getDeployPreview]',
31
+ );
32
+ });
33
+
34
+ describe('info', () => {
35
+ it('should pass with no params', () => {
36
+ const schema = defaultSchema();
37
+ const { error } = schema.validate({
38
+ action: 'info',
39
+ });
40
+
41
+ expect(error).toBeUndefined();
42
+ });
43
+ });
44
+
45
+ describe('entriesByFolder', () => {
46
+ it('should fail on invalid params', () => {
47
+ const schema = defaultSchema();
48
+
49
+ assetFailure(
50
+ schema.validate({ action: 'entriesByFolder', params: { ...defaultParams } }),
51
+ '"params.folder" is required',
52
+ );
53
+ assetFailure(
54
+ schema.validate({
55
+ action: 'entriesByFolder',
56
+ params: { ...defaultParams, folder: 'folder' },
57
+ }),
58
+ '"params.extension" is required',
59
+ );
60
+ assetFailure(
61
+ schema.validate({
62
+ action: 'entriesByFolder',
63
+ params: { ...defaultParams, folder: 'folder', extension: 'md' },
64
+ }),
65
+ '"params.depth" is required',
66
+ );
67
+ });
68
+
69
+ it('should pass on valid params', () => {
70
+ const schema = defaultSchema();
71
+ const { error } = schema.validate({
72
+ action: 'entriesByFolder',
73
+ params: { ...defaultParams, folder: 'folder', extension: 'md', depth: 1 },
74
+ });
75
+
76
+ expect(error).toBeUndefined();
77
+ });
78
+ });
79
+
80
+ describe('entriesByFiles', () => {
81
+ it('should fail on invalid params', () => {
82
+ const schema = defaultSchema();
83
+
84
+ assetFailure(
85
+ schema.validate({ action: 'entriesByFiles', params: { ...defaultParams } }),
86
+ '"params.files" is required',
87
+ );
88
+ assetFailure(
89
+ schema.validate({ action: 'entriesByFiles', params: { ...defaultParams, files: {} } }),
90
+ '"params.files" must be an array',
91
+ );
92
+ assetFailure(
93
+ schema.validate({
94
+ action: 'entriesByFiles',
95
+ params: { ...defaultParams, files: [{ id: 'id' }] },
96
+ }),
97
+ '"params.files[0].path" is required',
98
+ );
99
+ });
100
+
101
+ it('should pass on valid params', () => {
102
+ const schema = defaultSchema();
103
+ const { error } = schema.validate({
104
+ action: 'entriesByFiles',
105
+ params: { ...defaultParams, files: [{ path: 'path' }] },
106
+ });
107
+
108
+ expect(error).toBeUndefined();
109
+ });
110
+ });
111
+
112
+ describe('getEntry', () => {
113
+ it('should fail on invalid params', () => {
114
+ const schema = defaultSchema();
115
+
116
+ assetFailure(
117
+ schema.validate({ action: 'getEntry', params: { ...defaultParams } }),
118
+ '"params.path" is required',
119
+ );
120
+ assetFailure(
121
+ schema.validate({ action: 'getEntry', params: { ...defaultParams, path: 1 } }),
122
+ '"params.path" must be a string',
123
+ );
124
+ });
125
+
126
+ it('should pass on valid params', () => {
127
+ const schema = defaultSchema();
128
+ const { error } = schema.validate({
129
+ action: 'getEntry',
130
+ params: { ...defaultParams, path: 'path' },
131
+ });
132
+
133
+ expect(error).toBeUndefined();
134
+ });
135
+ });
136
+
137
+ describe('unpublishedEntries', () => {
138
+ it('should fail on invalid params', () => {
139
+ const schema = defaultSchema();
140
+
141
+ assetFailure(
142
+ schema.validate({ action: 'unpublishedEntries', params: {} }),
143
+ '"params.branch" is required',
144
+ );
145
+ });
146
+
147
+ it('should pass on valid params', () => {
148
+ const schema = defaultSchema();
149
+ const { error } = schema.validate({
150
+ action: 'unpublishedEntries',
151
+ params: { ...defaultParams, branch: 'master' },
152
+ });
153
+
154
+ expect(error).toBeUndefined();
155
+ });
156
+ });
157
+
158
+ describe('unpublishedEntry', () => {
159
+ it('should fail on invalid params', () => {
160
+ const schema = defaultSchema();
161
+ assetFailure(
162
+ schema.validate({ action: 'unpublishedEntry', params: {} }),
163
+ '"params.branch" is required',
164
+ );
165
+ });
166
+
167
+ it('should pass on valid collection and slug', () => {
168
+ const schema = defaultSchema();
169
+ const { error } = schema.validate({
170
+ action: 'unpublishedEntry',
171
+ params: { ...defaultParams, collection: 'collection', slug: 'slug' },
172
+ });
173
+
174
+ expect(error).toBeUndefined();
175
+ });
176
+
177
+ it('should pass on valid id', () => {
178
+ const schema = defaultSchema();
179
+ const { error } = schema.validate({
180
+ action: 'unpublishedEntry',
181
+ params: { ...defaultParams, id: 'id' },
182
+ });
183
+
184
+ expect(error).toBeUndefined();
185
+ });
186
+ });
187
+
188
+ ['unpublishedEntryDataFile', 'unpublishedEntryMediaFile'].forEach(action => {
189
+ describe(action, () => {
190
+ it('should fail on invalid params', () => {
191
+ const schema = defaultSchema();
192
+
193
+ assetFailure(
194
+ schema.validate({ action, params: { ...defaultParams } }),
195
+ '"params.collection" is required',
196
+ );
197
+ assetFailure(
198
+ schema.validate({
199
+ action,
200
+ params: { ...defaultParams, collection: 'collection' },
201
+ }),
202
+ '"params.slug" is required',
203
+ );
204
+ assetFailure(
205
+ schema.validate({
206
+ action,
207
+ params: { ...defaultParams, collection: 'collection', slug: 'slug' },
208
+ }),
209
+ '"params.id" is required',
210
+ );
211
+ assetFailure(
212
+ schema.validate({
213
+ action,
214
+ params: { ...defaultParams, collection: 'collection', slug: 'slug', id: 'id' },
215
+ }),
216
+ '"params.path" is required',
217
+ );
218
+ });
219
+
220
+ it('should pass on valid params', () => {
221
+ const schema = defaultSchema();
222
+ const { error } = schema.validate({
223
+ action,
224
+ params: {
225
+ ...defaultParams,
226
+ collection: 'collection',
227
+ slug: 'slug',
228
+ id: 'id',
229
+ path: 'path',
230
+ },
231
+ });
232
+
233
+ expect(error).toBeUndefined();
234
+ });
235
+ });
236
+ });
237
+
238
+ describe('deleteUnpublishedEntry', () => {
239
+ it('should fail on invalid params', () => {
240
+ const schema = defaultSchema();
241
+
242
+ assetFailure(
243
+ schema.validate({ action: 'deleteUnpublishedEntry', params: { ...defaultParams } }),
244
+ '"params.collection" is required',
245
+ );
246
+ assetFailure(
247
+ schema.validate({
248
+ action: 'deleteUnpublishedEntry',
249
+ params: { ...defaultParams, collection: 'collection' },
250
+ }),
251
+ '"params.slug" is required',
252
+ );
253
+ assetFailure(
254
+ schema.validate({
255
+ action: 'deleteUnpublishedEntry',
256
+ params: { ...defaultParams, collection: 'collection', slug: 1 },
257
+ }),
258
+ '"params.slug" must be a string',
259
+ );
260
+ });
261
+
262
+ it('should pass on valid params', () => {
263
+ const schema = defaultSchema();
264
+ const { error } = schema.validate({
265
+ action: 'deleteUnpublishedEntry',
266
+ params: { ...defaultParams, collection: 'collection', slug: 'slug' },
267
+ });
268
+
269
+ expect(error).toBeUndefined();
270
+ });
271
+ });
272
+
273
+ describe('persistEntry', () => {
274
+ it('should fail on invalid params', () => {
275
+ const schema = defaultSchema();
276
+
277
+ assetFailure(
278
+ schema.validate({
279
+ action: 'persistEntry',
280
+ params: {
281
+ ...defaultParams,
282
+ assets: [],
283
+ options: {
284
+ commitMessage: 'commitMessage',
285
+ useWorkflow: true,
286
+ status: 'draft',
287
+ },
288
+ },
289
+ }),
290
+ '"params" must contain at least one of [entry, dataFiles]',
291
+ );
292
+ assetFailure(
293
+ schema.validate({
294
+ action: 'persistEntry',
295
+ params: { ...defaultParams, entry: { slug: 'slug', path: 'path', raw: 'content' } },
296
+ }),
297
+ '"params.assets" is required',
298
+ );
299
+ assetFailure(
300
+ schema.validate({
301
+ action: 'persistEntry',
302
+ params: {
303
+ ...defaultParams,
304
+ entry: { slug: 'slug', path: 'path', raw: 'content' },
305
+ assets: [],
306
+ },
307
+ }),
308
+ '"params.options" is required',
309
+ );
310
+ assetFailure(
311
+ schema.validate({
312
+ action: 'persistEntry',
313
+ params: {
314
+ ...defaultParams,
315
+ entry: { slug: 'slug', path: 'path', raw: 'content' },
316
+ assets: [],
317
+ options: {},
318
+ },
319
+ }),
320
+ '"params.options.commitMessage" is required',
321
+ );
322
+ });
323
+
324
+ it('should pass on valid params (entry argument)', () => {
325
+ const schema = defaultSchema();
326
+ const { error } = schema.validate({
327
+ action: 'persistEntry',
328
+ params: {
329
+ ...defaultParams,
330
+ entry: { slug: 'slug', path: 'path', raw: 'content' },
331
+ assets: [{ path: 'path', content: 'content', encoding: 'base64' }],
332
+ options: {
333
+ commitMessage: 'commitMessage',
334
+ useWorkflow: true,
335
+ status: 'draft',
336
+ },
337
+ },
338
+ });
339
+
340
+ expect(error).toBeUndefined();
341
+ });
342
+
343
+ it('should pass on valid params (dataFiles argument)', () => {
344
+ const schema = defaultSchema();
345
+ const { error } = schema.validate({
346
+ action: 'persistEntry',
347
+ params: {
348
+ ...defaultParams,
349
+ dataFiles: [{ slug: 'slug', path: 'path', raw: 'content' }],
350
+ assets: [{ path: 'path', content: 'content', encoding: 'base64' }],
351
+ options: {
352
+ commitMessage: 'commitMessage',
353
+ useWorkflow: true,
354
+ status: 'draft',
355
+ },
356
+ },
357
+ });
358
+
359
+ expect(error).toBeUndefined();
360
+ });
361
+ });
362
+
363
+ describe('updateUnpublishedEntryStatus', () => {
364
+ it('should fail on invalid params', () => {
365
+ const schema = defaultSchema();
366
+
367
+ assetFailure(
368
+ schema.validate({ action: 'updateUnpublishedEntryStatus', params: { ...defaultParams } }),
369
+ '"params.collection" is required',
370
+ );
371
+ assetFailure(
372
+ schema.validate({
373
+ action: 'updateUnpublishedEntryStatus',
374
+ params: { ...defaultParams, collection: 'collection' },
375
+ }),
376
+ '"params.slug" is required',
377
+ );
378
+ assetFailure(
379
+ schema.validate({
380
+ action: 'updateUnpublishedEntryStatus',
381
+ params: { ...defaultParams, collection: 'collection', slug: 'slug' },
382
+ }),
383
+ '"params.newStatus" is required',
384
+ );
385
+ });
386
+
387
+ it('should pass on valid params', () => {
388
+ const schema = defaultSchema();
389
+ const { error } = schema.validate({
390
+ action: 'updateUnpublishedEntryStatus',
391
+ params: { ...defaultParams, collection: 'collection', slug: 'slug', newStatus: 'draft' },
392
+ });
393
+
394
+ expect(error).toBeUndefined();
395
+ });
396
+ });
397
+
398
+ describe('publishUnpublishedEntry', () => {
399
+ it('should fail on invalid params', () => {
400
+ const schema = defaultSchema();
401
+
402
+ assetFailure(
403
+ schema.validate({ action: 'publishUnpublishedEntry', params: { ...defaultParams } }),
404
+ '"params.collection" is required',
405
+ );
406
+ assetFailure(
407
+ schema.validate({
408
+ action: 'publishUnpublishedEntry',
409
+ params: { ...defaultParams, collection: 'collection' },
410
+ }),
411
+ '"params.slug" is required',
412
+ );
413
+ });
414
+
415
+ it('should pass on valid params', () => {
416
+ const schema = defaultSchema();
417
+ const { error } = schema.validate({
418
+ action: 'publishUnpublishedEntry',
419
+ params: { ...defaultParams, collection: 'collection', slug: 'slug' },
420
+ });
421
+
422
+ expect(error).toBeUndefined();
423
+ });
424
+ });
425
+
426
+ describe('getMedia', () => {
427
+ it('should fail on invalid params', () => {
428
+ const schema = defaultSchema();
429
+
430
+ assetFailure(
431
+ schema.validate({ action: 'getMedia', params: { ...defaultParams } }),
432
+ '"params.mediaFolder" is required',
433
+ );
434
+ });
435
+
436
+ it('should pass on valid params', () => {
437
+ const schema = defaultSchema();
438
+ const { error } = schema.validate({
439
+ action: 'getMedia',
440
+ params: { ...defaultParams, mediaFolder: 'src/static/images' },
441
+ });
442
+
443
+ expect(error).toBeUndefined();
444
+ });
445
+ });
446
+
447
+ describe('getMediaFile', () => {
448
+ it('should fail on invalid params', () => {
449
+ const schema = defaultSchema();
450
+
451
+ assetFailure(
452
+ schema.validate({ action: 'getMediaFile', params: { ...defaultParams } }),
453
+ '"params.path" is required',
454
+ );
455
+ });
456
+
457
+ it('should pass on valid params', () => {
458
+ const schema = defaultSchema();
459
+ const { error } = schema.validate({
460
+ action: 'getMediaFile',
461
+ params: { ...defaultParams, path: 'src/static/images/image.png' },
462
+ });
463
+
464
+ expect(error).toBeUndefined();
465
+ });
466
+ });
467
+
468
+ describe('persistMedia', () => {
469
+ it('should fail on invalid params', () => {
470
+ const schema = defaultSchema();
471
+
472
+ assetFailure(
473
+ schema.validate({ action: 'persistMedia', params: { ...defaultParams } }),
474
+ '"params.asset" is required',
475
+ );
476
+ assetFailure(
477
+ schema.validate({
478
+ action: 'persistMedia',
479
+ params: { ...defaultParams, asset: { path: 'path' } },
480
+ }),
481
+ '"params.asset.content" is required',
482
+ );
483
+ });
484
+
485
+ it('should pass on valid params', () => {
486
+ const schema = defaultSchema();
487
+ const { error } = schema.validate({
488
+ action: 'persistMedia',
489
+ params: {
490
+ ...defaultParams,
491
+ asset: { path: 'path', content: 'content', encoding: 'base64' },
492
+ options: { commitMessage: 'commitMessage' },
493
+ },
494
+ });
495
+
496
+ expect(error).toBeUndefined();
497
+ });
498
+ });
499
+
500
+ describe('deleteFile', () => {
501
+ it('should fail on invalid params', () => {
502
+ const schema = defaultSchema();
503
+
504
+ assetFailure(
505
+ schema.validate({ action: 'deleteFile', params: { ...defaultParams } }),
506
+ '"params.path" is required',
507
+ );
508
+ });
509
+
510
+ it('should pass on valid params', () => {
511
+ const schema = defaultSchema();
512
+ const { error } = schema.validate({
513
+ action: 'deleteFile',
514
+ params: {
515
+ ...defaultParams,
516
+ path: 'src/static/images/image.png',
517
+ options: { commitMessage: 'commitMessage' },
518
+ },
519
+ });
520
+
521
+ expect(error).toBeUndefined();
522
+ });
523
+ });
524
+
525
+ describe('deleteFiles', () => {
526
+ it('should fail on invalid params', () => {
527
+ const schema = defaultSchema();
528
+
529
+ assetFailure(
530
+ schema.validate({ action: 'deleteFiles', params: { ...defaultParams } }),
531
+ '"params.paths" is required',
532
+ );
533
+ });
534
+
535
+ it('should pass on valid params', () => {
536
+ const schema = defaultSchema();
537
+ const { error } = schema.validate({
538
+ action: 'deleteFiles',
539
+ params: {
540
+ ...defaultParams,
541
+ paths: ['src/static/images/image.png'],
542
+ options: { commitMessage: 'commitMessage' },
543
+ },
544
+ });
545
+
546
+ expect(error).toBeUndefined();
547
+ });
548
+ });
549
+
550
+ describe('getDeployPreview', () => {
551
+ it('should fail on invalid params', () => {
552
+ const schema = defaultSchema();
553
+
554
+ assetFailure(
555
+ schema.validate({ action: 'getDeployPreview', params: { ...defaultParams } }),
556
+ '"params.collection" is required',
557
+ );
558
+ assetFailure(
559
+ schema.validate({
560
+ action: 'getDeployPreview',
561
+ params: { ...defaultParams, collection: 'collection' },
562
+ }),
563
+ '"params.slug" is required',
564
+ );
565
+ });
566
+
567
+ it('should pass on valid params', () => {
568
+ const schema = defaultSchema();
569
+ const { error } = schema.validate({
570
+ action: 'getDeployPreview',
571
+ params: { ...defaultParams, collection: 'collection', slug: 'slug' },
572
+ });
573
+
574
+ expect(error).toBeUndefined();
575
+ });
576
+ });
577
+ });
578
+
579
+ describe('joi', () => {
580
+ it('should call next on valid schema', () => {
581
+ const next = jest.fn();
582
+
583
+ const req = {
584
+ body: {
585
+ action: 'entriesByFolder',
586
+ params: { branch: 'master', folder: 'folder', extension: 'md', depth: 1 },
587
+ },
588
+ } as express.Request;
589
+ const res: express.Response = {} as express.Response;
590
+ joi(defaultSchema())(req, res, next);
591
+
592
+ expect(next).toHaveBeenCalledTimes(1);
593
+ });
594
+
595
+ it('should send error on invalid schema', () => {
596
+ const next = jest.fn();
597
+
598
+ const req = {
599
+ body: {
600
+ action: 'entriesByFolder',
601
+ },
602
+ } as express.Request;
603
+ const json = jest.fn();
604
+ const status = jest.fn(() => ({ json }));
605
+ const res: express.Response = { status } as unknown as express.Response;
606
+
607
+ joi(defaultSchema())(req, res, next);
608
+
609
+ expect(next).toHaveBeenCalledTimes(0);
610
+
611
+ expect(status).toHaveBeenCalledTimes(1);
612
+ expect(json).toHaveBeenCalledTimes(1);
613
+
614
+ expect(status).toHaveBeenCalledWith(422);
615
+ expect(json).toHaveBeenCalledWith({ error: '"params" is required' });
616
+ });
617
+ });