@vida-global/core 1.3.1 → 1.3.3

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.
@@ -8,7 +8,7 @@ const TestHelpers = require('@vida-global/test-helpers');
8
8
  const { VidaServerController } = require('../../lib/server');
9
9
 
10
10
  describe('VidaServerController', () => {
11
- describe('VidaServerController.actionNames', () => {
11
+ describe('.actionNames', () => {
12
12
  it ('returns actions based on method names', () => {
13
13
  const names = FooController.actionNames;
14
14
  const expected = ['postIndex',
@@ -23,7 +23,7 @@ describe('VidaServerController', () => {
23
23
  });
24
24
 
25
25
 
26
- describe('VidaServerController.autoLoadHelpers', () => {
26
+ describe('.autoLoadHelpers', () => {
27
27
  class AutoLoadTestController extends VidaServerController {
28
28
  static get autoLoadHelperPath() {
29
29
  return `${process.cwd()}/test/server/helpers/autoload/${this.name}.js`;
@@ -60,7 +60,7 @@ describe('VidaServerController', () => {
60
60
  });
61
61
 
62
62
 
63
- describe('VidaServerController._constructAction', () => {
63
+ describe('._constructAction', () => {
64
64
  class UsersController extends VidaServerController {
65
65
  static get routes() {
66
66
  return {getBazBan: '/baz/:id/ban'};
@@ -123,7 +123,7 @@ describe('VidaServerController', () => {
123
123
  });
124
124
 
125
125
 
126
- describe('VidaServerController.validateParameters', () => {
126
+ describe('.validateParameters', () => {
127
127
  const paramName1 = TestHelpers.Faker.Text.randomString();
128
128
  const paramName2 = TestHelpers.Faker.Text.randomString();
129
129
  const value1 = TestHelpers.Faker.Text.randomString();
@@ -165,20 +165,20 @@ describe('VidaServerController', () => {
165
165
  expect(validator2).toHaveBeenCalledWith(value1, options2);
166
166
  });
167
167
 
168
- it ('throws a `ValidationError` when there\'s an error', async () => {
168
+ it ('throws a `ValidationError` when there\'s an error', () => {
169
169
  validator1.mockImplementation(() => error1);
170
- await expect(async () => {
171
- await controller.validateParameters(validations);
172
- }).rejects.toThrow(Errors.ValidationError);
170
+ expect(() => {
171
+ controller.validateParameters(validations);
172
+ }).toThrow(Errors.ValidationError);
173
173
  });
174
174
 
175
- it ('throws a `ValidationError` when there are multiple errors', async () => {
175
+ it ('throws a `ValidationError` when there are multiple errors', () => {
176
176
  validator1.mockImplementation(() => error1);
177
177
  validator2.mockImplementation(() => error2);
178
178
 
179
- await expect(async () => {
180
- await controller.validateParameters(validations);
181
- }).rejects.toThrow(Errors.ValidationError);
179
+ expect(() => {
180
+ controller.validateParameters(validations);
181
+ }).toThrow(Errors.ValidationError);
182
182
  });
183
183
 
184
184
  it ('sets nothing when there is no error', () => {
@@ -186,10 +186,38 @@ describe('VidaServerController', () => {
186
186
  expect(controller.render).toHaveBeenCalledTimes(0);
187
187
  expect(response.statusCode).toEqual(200);
188
188
  });
189
+
190
+ it ('ignores details where there is no validator', () => {
191
+ const validations = {
192
+ [paramName2]: {[validationType1]: options2, 'foo': true}
193
+ };
194
+ controller.validateParameters(validations);
195
+
196
+ expect(validator1).toHaveBeenCalledTimes(1);
197
+ expect(validator1).toHaveBeenCalledWith(value2, options2);
198
+ });
199
+
200
+ it ('does not error when optional parameters are not included', () => {
201
+ const validations = {foo: {isString: true, optional: true}};
202
+ expect(() => {
203
+ controller.validateParameters(validations);
204
+ }).not.toThrow();
205
+ });
206
+
207
+ it ('does error when optional parameters are invalid', () => {
208
+ const validations = {foo: {isString: {length: {gte: 2}}, optional: true}};
209
+ params.foo = '';
210
+
211
+ expect(() => {
212
+ controller.validateParameters(validations);
213
+ }).toThrow(Errors.ValidationError);
214
+
215
+ delete params.foo;
216
+ });
189
217
  });
190
218
 
191
219
 
192
- describe('VidaServerController.validatePresence', () => {
220
+ describe('.validatePresence', () => {
193
221
  const controller = new FooController({}, {});
194
222
  it ('returns undefined when there is a value', () => {
195
223
  const result = controller.validatePresence(TestHelpers.Faker.Text.randomString());
@@ -203,7 +231,7 @@ describe('VidaServerController', () => {
203
231
  });
204
232
 
205
233
 
206
- describe('VidaServerController.validateIsInteger', () => {
234
+ describe('.validateIsInteger', () => {
207
235
  const controller = new FooController({}, {});
208
236
  it ('returns undefined when there is an integer', () => {
209
237
  const val = Math.ceil(Math.random() * 100);
@@ -230,6 +258,21 @@ describe('VidaServerController', () => {
230
258
  expect(result).toEqual('must be an integer');
231
259
  });
232
260
 
261
+ it ('returns an error when the value is null', () => {
262
+ const result = controller.validateIsInteger(null)
263
+ expect(result).toEqual('must be an integer');
264
+ });
265
+
266
+ it ('returns an error when the value is undefined', () => {
267
+ const result = controller.validateIsInteger(undefined)
268
+ expect(result).toEqual('must be an integer');
269
+ });
270
+
271
+ it ('returns an error when the value is an object', () => {
272
+ const result = controller.validateIsInteger({})
273
+ expect(result).toEqual('must be an integer');
274
+ });
275
+
233
276
  it ('returns an error when the number is less than the gte option', () => {
234
277
  const result = controller.validateIsInteger(1, {gte: 2});
235
278
  expect(result).toEqual('must be greater than or equal to 2');
@@ -244,10 +287,116 @@ describe('VidaServerController', () => {
244
287
  const result = controller.validateIsInteger(2, {gte: 2});
245
288
  expect(result).toEqual(undefined);
246
289
  });
290
+
291
+ it ('returns an error when the number is greater than the lte option', () => {
292
+ const result = controller.validateIsInteger(3, {lte: 2});
293
+ expect(result).toEqual('must be less than or equal to 2');
294
+ });
295
+
296
+ it ('returns undefined when the number is less than the lte option', () => {
297
+ const result = controller.validateIsInteger(1, {lte: 2});
298
+ expect(result).toEqual(undefined);
299
+ });
300
+
301
+ it ('returns undefined when the number is equal to the lte option', () => {
302
+ const result = controller.validateIsInteger(2, {lte: 2});
303
+ expect(result).toEqual(undefined);
304
+ });
305
+
306
+ it ('supports both the lte and gte options', () => {
307
+ let result = controller.validateIsInteger(1, {lte: 2, gte: 0});
308
+ expect(result).toEqual(undefined);
309
+
310
+ result = controller.validateIsInteger(-1, {lte: 2, gte: 0});
311
+ expect(result).toEqual('must be greater than or equal to 0');
312
+
313
+ result = controller.validateIsInteger(3, {lte: 2, gte: 0});
314
+ expect(result).toEqual('must be less than or equal to 2');
315
+ });
247
316
  });
248
317
 
249
318
 
250
- describe('VidaServerController.validateIsDateTime', () => {
319
+ describe('.validateIsString', () => {
320
+ const controller = new FooController({}, {});
321
+ it ('returns undefined when there is an string', () => {
322
+ const result = controller.validateIsString('')
323
+ expect(result).toEqual(undefined);
324
+ });
325
+
326
+ it ('returns an error when there is a number', () => {
327
+ const result = controller.validateIsString(Math.random());
328
+ expect(result).toEqual('must be a string');
329
+ });
330
+
331
+ it ('returns an error when the value is null', () => {
332
+ const result = controller.validateIsString(null)
333
+ expect(result).toEqual('must be a string');
334
+ });
335
+
336
+ it ('returns an error when the value is undefined', () => {
337
+ const result = controller.validateIsString(undefined)
338
+ expect(result).toEqual('must be a string');
339
+ });
340
+
341
+ it ('returns an error when the value is an object', () => {
342
+ const result = controller.validateIsString({})
343
+ expect(result).toEqual('must be a string');
344
+ });
345
+
346
+ it ('returns an error when the length is fewer than the gte option', () => {
347
+ const result = controller.validateIsString('f', {length: {gte: 2}});
348
+ expect(result).toEqual('must be greater than or equal to 2 characters');
349
+ });
350
+
351
+ it ('returns undefined when the length is greater than the gte option', () => {
352
+ const result = controller.validateIsString('foo', {length: {gte: 2}});
353
+ expect(result).toEqual(undefined);
354
+ });
355
+
356
+ it ('returns undefined when the length is equal to the gte option', () => {
357
+ const result = controller.validateIsString('fo', {length: {gte: 2}});
358
+ expect(result).toEqual(undefined);
359
+ });
360
+
361
+ it ('returns an error when the length is greater than the lte option', () => {
362
+ const result = controller.validateIsString('foo', {length: {lte: 2}});
363
+ expect(result).toEqual('must be fewer than or equal to 2 characters');
364
+ });
365
+
366
+ it ('returns undefined when the length is fewer than the lte option', () => {
367
+ const result = controller.validateIsString('f', {length: {lte: 2}});
368
+ expect(result).toEqual(undefined);
369
+ });
370
+
371
+ it ('returns undefined when the length is equal to the lte option', () => {
372
+ const result = controller.validateIsString('fo', {length: {lte: 2}});
373
+ expect(result).toEqual(undefined);
374
+ });
375
+
376
+ it ('supports both the lte and gte options', () => {
377
+ let result = controller.validateIsString('fo', {length: {lte: 3, gte: 1}});
378
+ expect(result).toEqual(undefined);
379
+
380
+ result = controller.validateIsString('', {length: {lte: 3, gte: 1}});
381
+ expect(result).toEqual('must be greater than or equal to 1 characters');
382
+
383
+ result = controller.validateIsString('foobar', {length: {lte: 3, gte: 1}});
384
+ expect(result).toEqual('must be fewer than or equal to 3 characters');
385
+ });
386
+
387
+ it ('returns undefined when the value matches the pattern', () => {
388
+ const result = controller.validateIsString('foo', {regex: /oo/})
389
+ expect(result).toBe(undefined);
390
+ });
391
+
392
+ it ('returns an error when the value does not match the pattern', () => {
393
+ const result = controller.validateIsString('bar', {regex: /oo/})
394
+ expect(result).toBe(`must match /oo/`);
395
+ });
396
+ });
397
+
398
+
399
+ describe('.validateIsDateTime', () => {
251
400
  const controller = new FooController({}, {});
252
401
  it ('returns undefined when passed a string of format YYYY-MM-DD', () => {
253
402
  const result = controller.validateIsDateTime('2025-12-17');
@@ -286,7 +435,7 @@ describe('VidaServerController', () => {
286
435
  });
287
436
 
288
437
 
289
- describe('VidaServerController.validateIsEnum', () => {
438
+ describe('.validateIsEnum', () => {
290
439
  const controller = new FooController({}, {});
291
440
  const enums = [Math.random(), Math.random(), Math.random()];
292
441
  const error = TestHelpers.Faker.Text.randomString();
@@ -303,7 +452,7 @@ describe('VidaServerController', () => {
303
452
  });
304
453
 
305
454
 
306
- describe('VidaServerController.validateFunction', () => {
455
+ describe('.validateFunction', () => {
307
456
  const controller = new FooController({}, {});
308
457
  const correctValue = Math.random();
309
458
  const error = TestHelpers.Faker.Text.randomString();
@@ -321,37 +470,7 @@ describe('VidaServerController', () => {
321
470
  });
322
471
 
323
472
 
324
- describe('VidaServerController.validateRegex', () => {
325
- const controller = new FooController({}, {});
326
-
327
- it ('returns undefined when the value matches the pattern', () => {
328
- const result = controller.validateRegex('foo', /oo/)
329
- expect(result).toBe(undefined);
330
- });
331
-
332
- it ('returns an error when the value does not match the pattern', () => {
333
- const result = controller.validateRegex('bar', /oo/)
334
- expect(result).toBe(`must match the pattern /oo/`);
335
- });
336
-
337
- it ('returns an error when the value is null', () => {
338
- const result = controller.validateRegex(null, /oo/)
339
- expect(result).toBe(`must match the pattern /oo/`);
340
- });
341
-
342
- it ('returns an error when the value is undefined', () => {
343
- const result = controller.validateRegex(undefined, /oo/)
344
- expect(result).toBe(`must match the pattern /oo/`);
345
- });
346
-
347
- it ('returns an error when the value is an object', () => {
348
- const result = controller.validateRegex({}, /oo/)
349
- expect(result).toBe(`must match the pattern /oo/`);
350
- });
351
- });
352
-
353
-
354
- describe('VidaServerController#performRequest', () => {
473
+ describe('#performRequest', () => {
355
474
  const errorHandlers = [
356
475
  ['renderUnauthorizedResponse', 'AuthorizationError'],
357
476
  ['renderForbiddenResponse', 'ForbiddenError'],
@@ -371,7 +490,7 @@ describe('VidaServerController', () => {
371
490
 
372
491
  expect(controller[handlerName]).toHaveBeenCalledTimes(1);
373
492
  if (handlerName == 'renderErrors') {
374
- expect(controller[handlerName]).toHaveBeenCalledWith(message, error.errors);
493
+ expect(controller[handlerName]).toHaveBeenCalledWith(message, error.fields);
375
494
  } else {
376
495
  expect(controller[handlerName]).toHaveBeenCalledWith(message);
377
496
  }
@@ -386,7 +505,7 @@ describe('VidaServerController', () => {
386
505
  await controller.performRequest('testAction');
387
506
 
388
507
  expect(controller.statusCode).toEqual(500);
389
- expect(controller.render).toHaveBeenCalledWith({error: message});
508
+ expect(controller.render).toHaveBeenCalledWith({errors: { message }});
390
509
  });
391
510
  });
392
511
 
@@ -401,7 +520,7 @@ describe('VidaServerController', () => {
401
520
  });
402
521
 
403
522
 
404
- describe('VidaServerController#renderErrors', () => {
523
+ describe('#renderErrors', () => {
405
524
  it ('returns a 400 response', async () => {
406
525
  await controller.renderErrors();
407
526
  expect(response.statusCode).toBe(400);
@@ -458,7 +577,7 @@ describe('VidaServerController', () => {
458
577
  });
459
578
 
460
579
 
461
- describe('VidaServerController#renderUnauthorizedResponse', () => {
580
+ describe('#renderUnauthorizedResponse', () => {
462
581
  it ('returns a 401 response', async () => {
463
582
  await controller.renderUnauthorizedResponse();
464
583
  expect(response.statusCode).toBe(401);
@@ -467,19 +586,19 @@ describe('VidaServerController', () => {
467
586
  it ('includes a blank message by default', async () => {
468
587
  await controller.renderUnauthorizedResponse();
469
588
  expect(controller.render).toHaveBeenCalledTimes(1);
470
- expect(controller.render).toHaveBeenCalledWith({message: null});
589
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null}});
471
590
  })
472
591
 
473
592
  it ('includes a provided message', async () => {
474
593
  const msg = TestHelpers.Faker.Text.randomString();
475
594
  await controller.renderUnauthorizedResponse(msg);
476
595
  expect(controller.render).toHaveBeenCalledTimes(1);
477
- expect(controller.render).toHaveBeenCalledWith({message: msg});
596
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: msg}});
478
597
  });
479
598
  });
480
599
 
481
600
 
482
- describe('VidaServerController#renderForbiddenResponse', () => {
601
+ describe('#renderForbiddenResponse', () => {
483
602
  it ('returns a 403 response', async () => {
484
603
  await controller.renderForbiddenResponse();
485
604
  expect(response.statusCode).toBe(403);
@@ -488,19 +607,19 @@ describe('VidaServerController', () => {
488
607
  it ('includes a blank message by default', async () => {
489
608
  await controller.renderForbiddenResponse();
490
609
  expect(controller.render).toHaveBeenCalledTimes(1);
491
- expect(controller.render).toHaveBeenCalledWith({message: null});
610
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null}});
492
611
  })
493
612
 
494
613
  it ('includes a provided message', async () => {
495
614
  const msg = TestHelpers.Faker.Text.randomString();
496
615
  await controller.renderForbiddenResponse(msg);
497
616
  expect(controller.render).toHaveBeenCalledTimes(1);
498
- expect(controller.render).toHaveBeenCalledWith({message: msg});
617
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: msg}});
499
618
  });
500
619
  });
501
620
 
502
621
 
503
- describe('VidaServerController#renderNotFoundResponse', () => {
622
+ describe('#renderNotFoundResponse', () => {
504
623
  it ('returns a 404 response', async () => {
505
624
  await controller.renderNotFoundResponse();
506
625
  expect(response.statusCode).toBe(404);
@@ -509,14 +628,14 @@ describe('VidaServerController', () => {
509
628
  it ('includes a blank message by default', async () => {
510
629
  await controller.renderNotFoundResponse();
511
630
  expect(controller.render).toHaveBeenCalledTimes(1);
512
- expect(controller.render).toHaveBeenCalledWith({message: null});
631
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null}});
513
632
  })
514
633
 
515
634
  it ('includes a provided message', async () => {
516
635
  const msg = TestHelpers.Faker.Text.randomString();
517
636
  await controller.renderNotFoundResponse(msg);
518
637
  expect(controller.render).toHaveBeenCalledTimes(1);
519
- expect(controller.render).toHaveBeenCalledWith({message: msg});
638
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: msg}});
520
639
  });
521
640
  });
522
641
  });
@@ -534,7 +653,7 @@ describe('VidaServerController', () => {
534
653
  controller = new FooController(request, response);
535
654
  });
536
655
 
537
- describe('VidaServerController#requestHeaders', () => {
656
+ describe('#requestHeaders', () => {
538
657
  it ('returns a copy of the request headers', () => {
539
658
  expect(controller.requestHeaders).not.toBe(request.headers);
540
659
  expect(JSON.stringify(controller.requestHeaders)).toEqual(JSON.stringify(request.headers));
@@ -542,28 +661,28 @@ describe('VidaServerController', () => {
542
661
  });
543
662
 
544
663
 
545
- describe('VidaServerController#responseHeaders', () => {
664
+ describe('#responseHeaders', () => {
546
665
  it ('returns the request headers', () => {
547
666
  expect(controller.responseHeaders).toBe(response.headers);
548
667
  });
549
668
  });
550
669
 
551
670
 
552
- describe('VidaServerController#contentType', () => {
671
+ describe('#contentType', () => {
553
672
  it ('returns the content-type request header', () => {
554
673
  expect(controller.contentType).toEqual(request.headers['content-type']);
555
674
  });
556
675
  });
557
676
 
558
677
 
559
- describe('VidaServerController#logger', () => {
678
+ describe('#logger', () => {
560
679
  it ('uses the standard logger', () => {
561
680
  expect(controller.logger).toBe(logger);
562
681
  });
563
682
  });
564
683
 
565
684
 
566
- describe('VidaServerController#rendered', () => {
685
+ describe('#rendered', () => {
567
686
  it ('returns false if nothing has rendered', () => {
568
687
  expect(controller.rendered).toBeFalsy();
569
688
  });
@@ -582,7 +701,7 @@ describe('VidaServerController', () => {
582
701
  });
583
702
 
584
703
 
585
- describe('VidaServerController#statusCode', () => {
704
+ describe('#statusCode', () => {
586
705
  it ('returns the response status code', () => {
587
706
  expect(controller.statusCode).toEqual(response.statusCode);
588
707
  });
@@ -594,4 +713,21 @@ describe('VidaServerController', () => {
594
713
  });
595
714
  });
596
715
  });
716
+
717
+
718
+ describe('#setupCallbacks', () => {
719
+ it ('is only called once', () => {
720
+ class CallbacksTestController extends VidaServerController {}
721
+ CallbacksTestController.prototype.setupCallbacks = jest.fn();
722
+ const controller = new CallbacksTestController({}, {});
723
+
724
+ expect(CallbacksTestController.prototype.setupCallbacks).toHaveBeenCalledTimes(1);
725
+ expect(controller.setupCallbacks).toBe(undefined);
726
+
727
+ });
728
+ });
729
+
730
+
731
+ describe('Request Properties', () => {
732
+ });
597
733
  });