@vida-global/core 1.2.5 → 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.
- package/.github/workflows/npm-test.yml +24 -0
- package/index.js +1 -1
- package/lib/{active_record → activeRecord}/README.md +3 -3
- package/lib/{active_record → activeRecord}/baseRecord.js +11 -2
- package/lib/http/README.md +2 -2
- package/lib/server/README.md +181 -20
- package/lib/server/errors.js +28 -0
- package/lib/server/index.js +3 -3
- package/lib/server/server.js +7 -53
- package/lib/server/serverController.js +147 -20
- package/package.json +1 -1
- package/scripts/{active_record → activeRecord}/migrate.js +1 -1
- package/test/{active_record → activeRecord}/baseRecord.test.js +46 -90
- package/test/activeRecord/db/connection.test.js +149 -0
- package/test/activeRecord/db/connectionConfiguration.test.js +128 -0
- package/test/activeRecord/db/migrator.test.js +144 -0
- package/test/activeRecord/db/queryInterface.test.js +48 -0
- package/test/activeRecord/helpers/baseRecord.js +32 -0
- package/test/activeRecord/helpers/baseRecordMocks.js +59 -0
- package/test/activeRecord/helpers/connection.js +28 -0
- package/test/activeRecord/helpers/connectionConfiguration.js +32 -0
- package/test/activeRecord/helpers/fixtures.js +39 -0
- package/test/activeRecord/helpers/migrator.js +78 -0
- package/test/activeRecord/helpers/queryInterface.js +29 -0
- package/test/http/client.test.js +61 -239
- package/test/http/error.test.js +23 -47
- package/test/http/helpers/client.js +80 -0
- package/test/http/helpers/error.js +31 -0
- package/test/server/helpers/autoload/TmpWithHelpersController.js +17 -0
- package/test/server/helpers/serverController.js +13 -0
- package/test/server/serverController.test.js +319 -6
- package/test/active_record/db/connection.test.js +0 -221
- package/test/active_record/db/connectionConfiguration.test.js +0 -184
- package/test/active_record/db/migrator.test.js +0 -266
- package/test/active_record/db/queryInterface.test.js +0 -66
- /package/lib/{active_record → activeRecord}/db/connection.js +0 -0
- /package/lib/{active_record → activeRecord}/db/connectionConfiguration.js +0 -0
- /package/lib/{active_record → activeRecord}/db/importSchema.js +0 -0
- /package/lib/{active_record → activeRecord}/db/migration.js +0 -0
- /package/lib/{active_record → activeRecord}/db/migrationTemplate.js +0 -0
- /package/lib/{active_record → activeRecord}/db/migrationVersion.js +0 -0
- /package/lib/{active_record → activeRecord}/db/migrator.js +0 -0
- /package/lib/{active_record → activeRecord}/db/queryInterface.js +0 -0
- /package/lib/{active_record → activeRecord}/db/schema.js +0 -0
- /package/lib/{active_record → activeRecord}/index.js +0 -0
- /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,6 +23,43 @@ 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', () => {
|
|
26
64
|
class UsersController extends VidaServerController {
|
|
27
65
|
static get routes() {
|
|
@@ -131,7 +169,7 @@ describe('VidaServerController', () => {
|
|
|
131
169
|
validator1.mockImplementation(() => error1);
|
|
132
170
|
await expect(async () => {
|
|
133
171
|
await controller.validateParameters(validations);
|
|
134
|
-
}).rejects.toThrow(ValidationError);
|
|
172
|
+
}).rejects.toThrow(Errors.ValidationError);
|
|
135
173
|
});
|
|
136
174
|
|
|
137
175
|
it ('throws a `ValidationError` when there are multiple errors', async () => {
|
|
@@ -140,7 +178,7 @@ describe('VidaServerController', () => {
|
|
|
140
178
|
|
|
141
179
|
await expect(async () => {
|
|
142
180
|
await controller.validateParameters(validations);
|
|
143
|
-
}).rejects.toThrow(ValidationError);
|
|
181
|
+
}).rejects.toThrow(Errors.ValidationError);
|
|
144
182
|
});
|
|
145
183
|
|
|
146
184
|
it ('sets nothing when there is no error', () => {
|
|
@@ -276,9 +314,284 @@ describe('VidaServerController', () => {
|
|
|
276
314
|
expect(result).toBe(undefined);
|
|
277
315
|
});
|
|
278
316
|
|
|
279
|
-
it ('returns
|
|
317
|
+
it ('returns an error when the function returns an error', () => {
|
|
280
318
|
const result = controller.validateFunction(Math.random(), validator);
|
|
281
319
|
expect(result).toBe(error);
|
|
282
320
|
});
|
|
283
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
|
+
});
|
|
284
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
|
-
});
|