@vida-global/core 1.2.4 → 1.3.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.
Files changed (46) hide show
  1. package/.github/workflows/npm-test.yml +24 -0
  2. package/index.js +1 -1
  3. package/lib/{active_record → activeRecord}/README.md +3 -3
  4. package/lib/{active_record → activeRecord}/baseRecord.js +11 -2
  5. package/lib/http/README.md +2 -2
  6. package/lib/server/README.md +181 -20
  7. package/lib/server/errors.js +28 -0
  8. package/lib/server/index.js +3 -3
  9. package/lib/server/server.js +7 -52
  10. package/lib/server/serverController.js +169 -23
  11. package/package.json +1 -1
  12. package/scripts/{active_record → activeRecord}/migrate.js +1 -1
  13. package/test/{active_record → activeRecord}/baseRecord.test.js +46 -90
  14. package/test/activeRecord/db/connection.test.js +149 -0
  15. package/test/activeRecord/db/connectionConfiguration.test.js +128 -0
  16. package/test/activeRecord/db/migrator.test.js +144 -0
  17. package/test/activeRecord/db/queryInterface.test.js +48 -0
  18. package/test/activeRecord/helpers/baseRecord.js +32 -0
  19. package/test/activeRecord/helpers/baseRecordMocks.js +59 -0
  20. package/test/activeRecord/helpers/connection.js +28 -0
  21. package/test/activeRecord/helpers/connectionConfiguration.js +32 -0
  22. package/test/activeRecord/helpers/fixtures.js +39 -0
  23. package/test/activeRecord/helpers/migrator.js +78 -0
  24. package/test/activeRecord/helpers/queryInterface.js +29 -0
  25. package/test/http/client.test.js +61 -239
  26. package/test/http/error.test.js +23 -47
  27. package/test/http/helpers/client.js +80 -0
  28. package/test/http/helpers/error.js +31 -0
  29. package/test/server/helpers/autoload/TmpWithHelpersController.js +17 -0
  30. package/test/server/helpers/serverController.js +13 -0
  31. package/test/server/serverController.test.js +357 -11
  32. package/test/active_record/db/connection.test.js +0 -221
  33. package/test/active_record/db/connectionConfiguration.test.js +0 -184
  34. package/test/active_record/db/migrator.test.js +0 -266
  35. package/test/active_record/db/queryInterface.test.js +0 -66
  36. /package/lib/{active_record → activeRecord}/db/connection.js +0 -0
  37. /package/lib/{active_record → activeRecord}/db/connectionConfiguration.js +0 -0
  38. /package/lib/{active_record → activeRecord}/db/importSchema.js +0 -0
  39. /package/lib/{active_record → activeRecord}/db/migration.js +0 -0
  40. /package/lib/{active_record → activeRecord}/db/migrationTemplate.js +0 -0
  41. /package/lib/{active_record → activeRecord}/db/migrationVersion.js +0 -0
  42. /package/lib/{active_record → activeRecord}/db/migrator.js +0 -0
  43. /package/lib/{active_record → activeRecord}/db/queryInterface.js +0 -0
  44. /package/lib/{active_record → activeRecord}/db/schema.js +0 -0
  45. /package/lib/{active_record → activeRecord}/index.js +0 -0
  46. /package/lib/{active_record → activeRecord}/utils.js +0 -0
@@ -1,10 +1,11 @@
1
- const { ValidationError,
2
- VidaServerController } = require('../../lib/server');
3
1
  const { BarController } = require('./helpers/controllers/barController');
4
2
  const { FooController } = require('./helpers/controllers/fooController');
5
3
  const { camelize } = require('inflection');
4
+ const Errors = require('../../lib/server/errors');
5
+ const { logger } = require('../../lib/logger');
6
+ const { randomPayload } = require('./helpers/serverController');
6
7
  const TestHelpers = require('@vida-global/test-helpers');
7
-
8
+ const { VidaServerController } = require('../../lib/server');
8
9
 
9
10
  describe('VidaServerController', () => {
10
11
  describe('VidaServerController.actionNames', () => {
@@ -22,23 +23,93 @@ describe('VidaServerController', () => {
22
23
  });
23
24
 
24
25
 
26
+ describe('VidaServerController.autoLoadHelpers', () => {
27
+ class AutoLoadTestController extends VidaServerController {
28
+ static get autoLoadHelperPath() {
29
+ return `${process.cwd()}/test/server/helpers/autoload/${this.name}.js`;
30
+ }
31
+ }
32
+
33
+ it ('does nothing if there is no helper', () => {
34
+ class TmpController extends AutoLoadTestController {}
35
+ TmpController.autoLoadHelpers();
36
+ expect(TmpController.anInstanceMethod).toBe(undefined);
37
+ expect(TmpController.aProperty).toBe(undefined);
38
+ });
39
+
40
+ it ('loads instance methods and accessors from the helper', () => {
41
+ class TmpWithHelpersController extends AutoLoadTestController {}
42
+ TmpWithHelpersController.autoLoadHelpers();
43
+
44
+ const { InstanceMethods, Accessors } = require('./helpers/autoload/TmpWithHelpersController');
45
+
46
+ expect(InstanceMethods.anInstanceMethod).not.toHaveBeenCalled();
47
+ expect(Accessors.aProperty.get).not.toHaveBeenCalled();
48
+ expect(Accessors.aProperty.set).not.toHaveBeenCalled();
49
+
50
+ const controller = new TmpWithHelpersController({}, {});
51
+ controller.anInstanceMethod();
52
+ expect(InstanceMethods.anInstanceMethod).toHaveBeenCalledTimes(1);
53
+
54
+ controller.aProperty;
55
+ expect(Accessors.aProperty.get).toHaveBeenCalledTimes(1);
56
+
57
+ controller.aProperty = 'foo';
58
+ expect(Accessors.aProperty.set).toHaveBeenCalledTimes(1);
59
+ });
60
+ });
61
+
62
+
25
63
  describe('VidaServerController._constructAction', () => {
64
+ class UsersController extends VidaServerController {
65
+ static get routes() {
66
+ return {getBazBan: '/baz/:id/ban'};
67
+ }
68
+ };
69
+
26
70
  it ('returns an object with path, method, and action', () => {
27
71
  const expected = {
28
72
  method: 'GET',
29
- path: '/foo/fooBar',
73
+ path: '/users/fooBar',
30
74
  action: 'getFooBar'
31
75
  }
32
- expect(FooController._constructAction('getFooBar', '')).toEqual(expected);
76
+ expect(UsersController._constructAction('getFooBar', '')).toEqual(expected);
33
77
  });
34
78
 
35
79
  it ('uses a blank path for index actions', () => {
36
80
  const expected = {
37
81
  method: 'POST',
38
- path: '/foo',
82
+ path: '/users',
39
83
  action: 'postIndex'
40
84
  }
41
- expect(FooController._constructAction('postIndex', '')).toEqual(expected);
85
+ expect(UsersController._constructAction('postIndex', '')).toEqual(expected);
86
+ });
87
+
88
+ it ('creates a single resource route for Record', () => {
89
+ const expected = {
90
+ method: 'GET',
91
+ path: '/user/:id',
92
+ action: 'getRecord'
93
+ }
94
+ expect(UsersController._constructAction('getRecord', '')).toEqual(expected);
95
+ });
96
+
97
+ it ('only uses Record when checking for single resource routes', () => {
98
+ const expected = {
99
+ method: 'GET',
100
+ path: '/users/recording',
101
+ action: 'getRecording'
102
+ }
103
+ expect(UsersController._constructAction('getRecording', '')).toEqual(expected);
104
+ });
105
+
106
+ it ('creates a single sub resource route for RecordFoo', () => {
107
+ const expected = {
108
+ method: 'GET',
109
+ path: '/user/:id/foo',
110
+ action: 'getRecordFoo'
111
+ }
112
+ expect(UsersController._constructAction('getRecordFoo', '')).toEqual(expected);
42
113
  });
43
114
 
44
115
  it ('uses a custom path when defined', () => {
@@ -47,7 +118,7 @@ describe('VidaServerController', () => {
47
118
  path: '/baz/:id/ban',
48
119
  action: 'getBazBan'
49
120
  }
50
- expect(FooController._constructAction('getBazBan', '')).toEqual(expected);
121
+ expect(UsersController._constructAction('getBazBan', '')).toEqual(expected);
51
122
  });
52
123
  });
53
124
 
@@ -98,7 +169,7 @@ describe('VidaServerController', () => {
98
169
  validator1.mockImplementation(() => error1);
99
170
  await expect(async () => {
100
171
  await controller.validateParameters(validations);
101
- }).rejects.toThrow(ValidationError);
172
+ }).rejects.toThrow(Errors.ValidationError);
102
173
  });
103
174
 
104
175
  it ('throws a `ValidationError` when there are multiple errors', async () => {
@@ -107,7 +178,7 @@ describe('VidaServerController', () => {
107
178
 
108
179
  await expect(async () => {
109
180
  await controller.validateParameters(validations);
110
- }).rejects.toThrow(ValidationError);
181
+ }).rejects.toThrow(Errors.ValidationError);
111
182
  });
112
183
 
113
184
  it ('sets nothing when there is no error', () => {
@@ -243,9 +314,284 @@ describe('VidaServerController', () => {
243
314
  expect(result).toBe(undefined);
244
315
  });
245
316
 
246
- it ('returns undefiend when passed a valid value', () => {
317
+ it ('returns an error when the function returns an error', () => {
247
318
  const result = controller.validateFunction(Math.random(), validator);
248
319
  expect(result).toBe(error);
249
320
  });
250
321
  });
322
+
323
+
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', () => {
355
+ const errorHandlers = [
356
+ ['renderUnauthorizedResponse', 'AuthorizationError'],
357
+ ['renderForbiddenResponse', 'ForbiddenError'],
358
+ ['renderNotFoundResponse', 'NotFoundError'],
359
+ ['renderErrors', 'ValidationError'],
360
+ ]
361
+
362
+ it.each(errorHandlers)('calls %s when %s is thrown', async (handlerName, errorClsName) => {
363
+ const controller = new FooController({}, {});
364
+ const message = TestHelpers.Faker.Text.randomString();
365
+ const error = new Errors[errorClsName](message);
366
+ if (handlerName == 'renderErrors') error.errors = randomPayload();
367
+
368
+ controller[handlerName] = jest.fn();
369
+ controller.testAction = () => { throw error };
370
+ await controller.performRequest('testAction');
371
+
372
+ expect(controller[handlerName]).toHaveBeenCalledTimes(1);
373
+ if (handlerName == 'renderErrors') {
374
+ expect(controller[handlerName]).toHaveBeenCalledWith(message, error.errors);
375
+ } else {
376
+ expect(controller[handlerName]).toHaveBeenCalledWith(message);
377
+ }
378
+ });
379
+
380
+ it ('throws a 500 if there is a non standard error thrown', async () => {
381
+ const controller = new FooController({}, {});
382
+ const message = TestHelpers.Faker.Text.randomString();
383
+
384
+ controller.testAction = () => { throw new Error(message) };
385
+ controller.render = jest.fn();
386
+ await controller.performRequest('testAction');
387
+
388
+ expect(controller.statusCode).toEqual(500);
389
+ expect(controller.render).toHaveBeenCalledWith({error: message});
390
+ });
391
+ });
392
+
393
+
394
+ describe('Rendering', () => {
395
+ let controller;
396
+ let response;
397
+ beforeEach(() => {
398
+ response = {json: jest.fn(), statusCode: 200};
399
+ controller = new FooController({}, response);
400
+ controller.render = jest.fn();
401
+ });
402
+
403
+
404
+ describe('VidaServerController#renderErrors', () => {
405
+ it ('returns a 400 response', async () => {
406
+ await controller.renderErrors();
407
+ expect(response.statusCode).toBe(400);
408
+ })
409
+
410
+ it ('includes a blank message and blank fields by default', async () => {
411
+ await controller.renderErrors();
412
+ expect(controller.render).toHaveBeenCalledTimes(1);
413
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null, fields: {}}});
414
+ })
415
+
416
+ it ('includes a provided message', async () => {
417
+ const msg = TestHelpers.Faker.Text.randomString();
418
+ await controller.renderErrors(msg);
419
+ expect(controller.render).toHaveBeenCalledTimes(1);
420
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: msg, fields: {}}});
421
+ });
422
+
423
+ it ('includes provided field data', async () => {
424
+ const field1 = TestHelpers.Faker.Text.randomString();
425
+ const msg1 = TestHelpers.Faker.Text.randomString();
426
+ const msg2 = TestHelpers.Faker.Text.randomString();
427
+ await controller.renderErrors(null, {[field1]: [msg1, msg2]});
428
+ expect(controller.render).toHaveBeenCalledTimes(1);
429
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null, fields: {[field1]: [msg1, msg2]}}});
430
+ });
431
+
432
+ it ('includes provided message field data', async () => {
433
+ const field1 = TestHelpers.Faker.Text.randomString();
434
+ const msg1 = TestHelpers.Faker.Text.randomString();
435
+ const msg2 = TestHelpers.Faker.Text.randomString();
436
+ const msg3 = TestHelpers.Faker.Text.randomString();
437
+ await controller.renderErrors(msg1, {[field1]: [msg2, msg3]});
438
+ expect(controller.render).toHaveBeenCalledTimes(1);
439
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: msg1, fields: {[field1]: [msg2, msg3]}}});
440
+ });
441
+
442
+ it ('uses the first parameter as fields if it is an object', async () => {
443
+ const field1 = TestHelpers.Faker.Text.randomString();
444
+ const msg1 = TestHelpers.Faker.Text.randomString();
445
+ const msg2 = TestHelpers.Faker.Text.randomString();
446
+ await controller.renderErrors({[field1]: [msg1, msg2]});
447
+ expect(controller.render).toHaveBeenCalledTimes(1);
448
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null, fields: {[field1]: [msg1, msg2]}}});
449
+ });
450
+
451
+ it ('converts single field error messages to arrays', async () => {
452
+ const field1 = TestHelpers.Faker.Text.randomString();
453
+ const msg1 = TestHelpers.Faker.Text.randomString();
454
+ await controller.renderErrors({[field1]: msg1});
455
+ expect(controller.render).toHaveBeenCalledTimes(1);
456
+ expect(controller.render).toHaveBeenCalledWith({errors: {message: null, fields: {[field1]: [msg1]}}});
457
+ });
458
+ });
459
+
460
+
461
+ describe('VidaServerController#renderUnauthorizedResponse', () => {
462
+ it ('returns a 401 response', async () => {
463
+ await controller.renderUnauthorizedResponse();
464
+ expect(response.statusCode).toBe(401);
465
+ })
466
+
467
+ it ('includes a blank message by default', async () => {
468
+ await controller.renderUnauthorizedResponse();
469
+ expect(controller.render).toHaveBeenCalledTimes(1);
470
+ expect(controller.render).toHaveBeenCalledWith({message: null});
471
+ })
472
+
473
+ it ('includes a provided message', async () => {
474
+ const msg = TestHelpers.Faker.Text.randomString();
475
+ await controller.renderUnauthorizedResponse(msg);
476
+ expect(controller.render).toHaveBeenCalledTimes(1);
477
+ expect(controller.render).toHaveBeenCalledWith({message: msg});
478
+ });
479
+ });
480
+
481
+
482
+ describe('VidaServerController#renderForbiddenResponse', () => {
483
+ it ('returns a 403 response', async () => {
484
+ await controller.renderForbiddenResponse();
485
+ expect(response.statusCode).toBe(403);
486
+ })
487
+
488
+ it ('includes a blank message by default', async () => {
489
+ await controller.renderForbiddenResponse();
490
+ expect(controller.render).toHaveBeenCalledTimes(1);
491
+ expect(controller.render).toHaveBeenCalledWith({message: null});
492
+ })
493
+
494
+ it ('includes a provided message', async () => {
495
+ const msg = TestHelpers.Faker.Text.randomString();
496
+ await controller.renderForbiddenResponse(msg);
497
+ expect(controller.render).toHaveBeenCalledTimes(1);
498
+ expect(controller.render).toHaveBeenCalledWith({message: msg});
499
+ });
500
+ });
501
+
502
+
503
+ describe('VidaServerController#renderNotFoundResponse', () => {
504
+ it ('returns a 404 response', async () => {
505
+ await controller.renderNotFoundResponse();
506
+ expect(response.statusCode).toBe(404);
507
+ })
508
+
509
+ it ('includes a blank message by default', async () => {
510
+ await controller.renderNotFoundResponse();
511
+ expect(controller.render).toHaveBeenCalledTimes(1);
512
+ expect(controller.render).toHaveBeenCalledWith({message: null});
513
+ })
514
+
515
+ it ('includes a provided message', async () => {
516
+ const msg = TestHelpers.Faker.Text.randomString();
517
+ await controller.renderNotFoundResponse(msg);
518
+ expect(controller.render).toHaveBeenCalledTimes(1);
519
+ expect(controller.render).toHaveBeenCalledWith({message: msg});
520
+ });
521
+ });
522
+ });
523
+
524
+
525
+ describe('Request Properties', () => {
526
+ let request;
527
+ let response;
528
+ let controller;
529
+
530
+ beforeEach(() => {
531
+ request = {headers: randomPayload()};
532
+ response = {headers: randomPayload(), statusCode: TestHelpers.Faker.Math.randomNumber(), json: jest.fn()};
533
+ request.headers['content-type'] = TestHelpers.Faker.Text.randomString();
534
+ controller = new FooController(request, response);
535
+ });
536
+
537
+ describe('VidaServerController#requestHeaders', () => {
538
+ it ('returns a copy of the request headers', () => {
539
+ expect(controller.requestHeaders).not.toBe(request.headers);
540
+ expect(JSON.stringify(controller.requestHeaders)).toEqual(JSON.stringify(request.headers));
541
+ });
542
+ });
543
+
544
+
545
+ describe('VidaServerController#responseHeaders', () => {
546
+ it ('returns the request headers', () => {
547
+ expect(controller.responseHeaders).toBe(response.headers);
548
+ });
549
+ });
550
+
551
+
552
+ describe('VidaServerController#contentType', () => {
553
+ it ('returns the content-type request header', () => {
554
+ expect(controller.contentType).toEqual(request.headers['content-type']);
555
+ });
556
+ });
557
+
558
+
559
+ describe('VidaServerController#logger', () => {
560
+ it ('uses the standard logger', () => {
561
+ expect(controller.logger).toBe(logger);
562
+ });
563
+ });
564
+
565
+
566
+ describe('VidaServerController#rendered', () => {
567
+ it ('returns false if nothing has rendered', () => {
568
+ expect(controller.rendered).toBeFalsy();
569
+ });
570
+
571
+ it ('returns true if something has rendered', async () => {
572
+ expect(controller.rendered).toBeFalsy();
573
+ await controller.render({});
574
+ expect(controller.rendered).toBeTruthy();
575
+ });
576
+
577
+ it ('returns true if markRendered has been called', () => {
578
+ expect(controller.rendered).toBeFalsy();
579
+ controller.markRendered();
580
+ expect(controller.rendered).toBeTruthy();
581
+ });
582
+ });
583
+
584
+
585
+ describe('VidaServerController#statusCode', () => {
586
+ it ('returns the response status code', () => {
587
+ expect(controller.statusCode).toEqual(response.statusCode);
588
+ });
589
+
590
+ it ('sets the response status code', () => {
591
+ const code = TestHelpers.Faker.Math.randomNumber();
592
+ controller.statusCode = code;
593
+ expect(response.statusCode).toEqual(code);
594
+ });
595
+ });
596
+ });
251
597
  });
@@ -1,221 +0,0 @@
1
- const { Connection } = require('../../../lib/active_record/db/connection');
2
- const { ConnectionConfiguration } = require('../../../lib/active_record/db/connectionConfiguration');
3
- const TestHelpers = require('@vida-global/test-helpers');
4
-
5
-
6
- jest.mock('sequelize', () => {
7
- class MockSequelize {
8
- constructor(_1, _2, _3, options) {
9
- this.options = options;
10
- }
11
-
12
- transaction = jest.fn(callback => callback())
13
- close = jest.fn();
14
- }
15
- return {Sequelize: MockSequelize};
16
- });
17
-
18
-
19
- let spy;
20
- const origEnv = process.env.NODE_ENV;
21
- afterEach(() => {
22
- if (spy) spy.mockRestore();
23
- spy = null;
24
- Connection.clearConnectionsCache();
25
- process.env.NODE_ENV = origEnv;
26
- });
27
-
28
-
29
- const config1 = {
30
- database: TestHelpers.Faker.Text.randomString(),
31
- host: TestHelpers.Faker.Text.randomString(),
32
- password: TestHelpers.Faker.Text.randomString(),
33
- port: Math.random(),
34
- username: TestHelpers.Faker.Text.randomString(),
35
- pool: {
36
- min: Math.random(),
37
- max: Math.random(),
38
- }
39
- }
40
-
41
- const config2 = {
42
- database: TestHelpers.Faker.Text.randomString(),
43
- host: TestHelpers.Faker.Text.randomString(),
44
- password: TestHelpers.Faker.Text.randomString(),
45
- port: Math.random(),
46
- username: TestHelpers.Faker.Text.randomString()
47
- }
48
-
49
- const config3 = {
50
- database: TestHelpers.Faker.Text.randomString(),
51
- host: TestHelpers.Faker.Text.randomString(),
52
- password: TestHelpers.Faker.Text.randomString(),
53
- port: Math.random(),
54
- ssl: true,
55
- username: TestHelpers.Faker.Text.randomString()
56
- }
57
-
58
- const sqliteConfig = {
59
- dialect: 'sqlite'
60
- };
61
-
62
- const databaseId1 = TestHelpers.Faker.Text.randomString();
63
- const databaseId2 = TestHelpers.Faker.Text.randomString();
64
-
65
-
66
- describe('Connection', () => {
67
- beforeEach(() => {
68
- spy = jest.spyOn(ConnectionConfiguration, '_fetchAllConfigs');
69
- spy.mockImplementation(() => ({
70
- default: {test: config1, development: config1, production: config1},
71
- [databaseId1]: {test: config2, production: {}},
72
- [databaseId2]: {test: config3, production: {}},
73
- sqlite: {test: sqliteConfig}
74
- }));
75
- });
76
-
77
- describe('Connection#_sequelize', () => {
78
- it ('caches the connection to the same database', () => {
79
- const conn1 = new Connection();
80
- const conn2 = new Connection();
81
- expect(conn1._sequelize).toBe(conn2._sequelize);
82
- });
83
-
84
- it ('does not cache connections to different databases', () => {
85
- const conn1 = new Connection();
86
- const conn2 = new Connection(databaseId1);
87
- expect(conn1._sequelize).not.toBe(conn2._sequelize);
88
- });
89
-
90
- describe('settings (postgres)', () => {
91
- it ('sets the connection settings to the correct values', () => {
92
- const conn1 = new Connection();
93
- expect(conn1._sequelize.options.database).toEqual(config1.database);
94
- expect(conn1._sequelize.options.dialect).toEqual('postgres');
95
- expect(conn1._sequelize.options.host).toEqual(config1.host);
96
- expect(conn1._sequelize.options.password).toEqual(config1.password);
97
- expect(conn1._sequelize.options.port).toEqual(config1.port);
98
- expect(conn1._sequelize.options.username).toEqual(config1.username);
99
-
100
- const conn2 = new Connection(databaseId1);
101
- expect(conn2._sequelize.options.database).toEqual(config2.database);
102
- expect(conn2._sequelize.options.dialect).toEqual('postgres');
103
- expect(conn2._sequelize.options.host).toEqual(config2.host);
104
- expect(conn2._sequelize.options.password).toEqual(config2.password);
105
- expect(conn2._sequelize.options.port).toEqual(config2.port);
106
- expect(conn2._sequelize.options.username).toEqual(config2.username);
107
- });
108
-
109
- it ('requires ssl when the configuration says to', () => {
110
- const conn = new Connection(databaseId2);
111
- expect(conn._sequelize.options.dialectOptions).toEqual({ssl: {require: true}});
112
- });
113
-
114
- it ('enables logging in development', () => {
115
- process.env.NODE_ENV = 'development';
116
- const conn = new Connection();
117
- expect(conn._sequelize.options.logging).toBe(undefined); // undefined defaults to true
118
- });
119
-
120
- it ('does not enable logging in production', () => {
121
- process.env.NODE_ENV = 'production';
122
- const conn = new Connection();
123
- expect(conn._sequelize.options.logging).toBeFalsy();
124
- });
125
-
126
- it ('sets the connection pool to the configured values', () => {
127
- const conn1 = new Connection();
128
- expect(conn1._sequelize.options.pool).toEqual(config1.pool);
129
-
130
- const conn2 = new Connection(databaseId1);
131
- expect(conn2._sequelize.options.pool).toEqual({min: 0, max: 5})
132
- });
133
-
134
- it ('configures the connection to use underscores for columns', () => {
135
- const conn = new Connection();
136
- expect(conn._sequelize.options.define.underscored).toBeTruthy();
137
- });
138
-
139
-
140
- describe('replication', () => {
141
- it ('configures a read and writer when replicas are configured', () => {
142
- const config = {
143
- database: TestHelpers.Faker.Text.randomString(),
144
- host: TestHelpers.Faker.Text.randomString(),
145
- password: TestHelpers.Faker.Text.randomString(),
146
- port: Math.random(),
147
- username: TestHelpers.Faker.Text.randomString(),
148
- readers: [
149
- {
150
- database: TestHelpers.Faker.Text.randomString(),
151
- host: TestHelpers.Faker.Text.randomString(),
152
- password: TestHelpers.Faker.Text.randomString(),
153
- port: Math.random(),
154
- username: TestHelpers.Faker.Text.randomString(),
155
- },
156
- {
157
- database: TestHelpers.Faker.Text.randomString(),
158
- host: TestHelpers.Faker.Text.randomString(),
159
- password: TestHelpers.Faker.Text.randomString(),
160
- port: Math.random(),
161
- username: TestHelpers.Faker.Text.randomString(),
162
- },
163
- ]
164
- }
165
- spy.mockImplementation(() => ({default: {test: config }}));
166
- const conn = new Connection();
167
- const options = conn._sequelize.options;
168
- expect(options.database).toBe(undefined);
169
- expect(options.dialect).toBe('postgres');
170
- expect(options.host).toBe(undefined);
171
- expect(options.password).toBe(undefined);
172
- expect(options.port).toBe(undefined);
173
- expect(options.username).toBe(undefined);
174
-
175
- expect(options.replication).toEqual({
176
- write: {
177
- database: config.database,
178
- host: config.host,
179
- password: config.password,
180
- port: config.port,
181
- username: config.username,
182
- },
183
- read: config.readers
184
- });
185
- });
186
- });
187
- });
188
-
189
-
190
- describe('settings (sqlite)', () => {
191
- it ('sets the connection settings to the correct values for sqlite', () => {
192
- const conn = new Connection('sqlite');
193
- expect(conn._sequelize.options.dialect).toEqual('sqlite');
194
- expect(conn._sequelize.options.storage).toEqual(`${process.cwd()}/config/db/database.test.sqlite`);
195
- });
196
- });
197
- });
198
-
199
-
200
- describe('Connection#close', () => {
201
- it ('calls close on the underlying sequelize connection', () => {
202
- const conn = new Connection();
203
- conn._sequelize; // reference it to initiate the connection
204
- conn.close();
205
- expect(conn._sequelize.close).toHaveBeenCalledTimes(1);
206
- });
207
- });
208
-
209
-
210
- describe('Connection.closeAll', () => {
211
- it ('calls close on all cached connections', () => {
212
- const conn1 = new Connection();
213
- const conn2 = new Connection(databaseId1);
214
- conn1._sequelize // reference it to initiate the connection
215
- conn2._sequelize // reference it to initiate the connection
216
- Connection.closeAll();
217
- expect(conn1._sequelize.close).toHaveBeenCalledTimes(1);
218
- expect(conn2._sequelize.close).toHaveBeenCalledTimes(1);
219
- });
220
- });
221
- });