@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
@@ -0,0 +1,128 @@
1
+ const { ConnectionConfiguration } = require('../../../lib/activeRecord/db/connectionConfiguration');
2
+ const Helpers = require('../helpers/connectionConfiguration');
3
+
4
+
5
+ afterEach(() => {
6
+ Helpers.fetchConfigsSpy.mockReset();
7
+ process.env.DB_POOL_MIN = Helpers.originalEnv.dbPoolMin;
8
+ process.env.DB_POOL_MAX = Helpers.originalEnv.dbPoolMax;
9
+ process.env.NODE_ENV = Helpers.originalEnv.nodeEnv;
10
+ });
11
+
12
+
13
+ describe('ConnectionConfiguration', () => {
14
+ describe('ConnectionConfiguration.constructor', () => {
15
+ it.each([
16
+ ['database id', () => ({ test: Helpers.testConfig })],
17
+ ['environment', () => ({ [Helpers.databaseId1]: { production: Helpers.productionConfig } })],
18
+ ['postgres fields', () => ({ [Helpers.databaseId1]: { test: { port: Math.random() } } })],
19
+ ])('throws when required %s config is missing', (_label, configBuilder) => {
20
+ Helpers.mockConfigs(configBuilder());
21
+ expect(() => new ConnectionConfiguration(Helpers.databaseId1)).toThrow();
22
+ });
23
+
24
+ it ('does not require postgres details for sqlite', () => {
25
+ Helpers.mockConfigs({ [Helpers.databaseId1]: { test: Helpers.sqliteConfig } });
26
+ expect(() => new ConnectionConfiguration(Helpers.databaseId1)).not.toThrow();
27
+ });
28
+ });
29
+
30
+
31
+ describe('resolved properties', () => {
32
+ it ('maps core fields from the environment config', () => {
33
+ Helpers.mockConfigs({
34
+ [Helpers.databaseId1]: { test: Helpers.testConfig, production: Helpers.productionConfig },
35
+ [Helpers.databaseId2]: { test: {}, production: {} },
36
+ });
37
+
38
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
39
+
40
+ expect(config.database).toEqual(Helpers.testConfig.database);
41
+ expect(config.host).toEqual(Helpers.testConfig.host);
42
+ expect(config.password).toEqual(Helpers.testConfig.password);
43
+ expect(config.username).toEqual(Helpers.testConfig.username);
44
+ expect(config.ssl).toBeFalsy();
45
+ });
46
+
47
+ it ('sets ssl when configured', () => {
48
+ Helpers.mockConfigs({ [Helpers.databaseId1]: { test: Helpers.buildPostgresConfig({ ssl: true }) } });
49
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
50
+ expect(config.ssl).toBeTruthy();
51
+ });
52
+ });
53
+
54
+
55
+ describe('ConnectionConfiguration#loggingEnabled', () => {
56
+ it.each([
57
+ ['development', true],
58
+ ['production', false],
59
+ ])('returns %s logging setting', (environment, expected) => {
60
+ process.env.NODE_ENV = environment;
61
+ Helpers.mockConfigs({ [Helpers.databaseId1]: { [environment]: Helpers.testConfig } });
62
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
63
+ expect(config.loggingEnabled).toBe(expected);
64
+ });
65
+ });
66
+
67
+
68
+ describe('ConnectionConfiguration#pool', () => {
69
+ it ('uses default pool values when unset', () => {
70
+ Helpers.mockConfigs({ [Helpers.databaseId1]: { test: Helpers.testConfig } });
71
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
72
+ expect(config.pool).toEqual({ min: 0, max: 5 });
73
+ });
74
+
75
+ it ('uses configured pool values', () => {
76
+ const pool = { min: Math.random(), max: Math.random() };
77
+ process.env.DB_POOL_MIN = String(Math.random());
78
+ process.env.DB_POOL_MAX = String(Math.random());
79
+ Helpers.mockConfigs({ [Helpers.databaseId1]: { test: Helpers.buildPostgresConfig({ pool }) } });
80
+
81
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
82
+
83
+ expect(config.pool).toEqual(pool);
84
+ });
85
+ });
86
+
87
+
88
+ describe('ConnectionConfiguration.configuredDatabaseIds', () => {
89
+ it ('returns all database ids configured for the current environment', () => {
90
+ Helpers.mockConfigs({
91
+ [Helpers.databaseId1]: { production: Helpers.productionConfig, test: Helpers.testConfig },
92
+ [Helpers.databaseId2]: { production: Helpers.productionConfig, test: Helpers.testConfig },
93
+ });
94
+
95
+ expect(ConnectionConfiguration.configuredDatabaseIds()).toEqual([Helpers.databaseId1, Helpers.databaseId2]);
96
+ });
97
+
98
+ it ('filters out ids missing the current environment', () => {
99
+ Helpers.mockConfigs({
100
+ [Helpers.databaseId1]: { production: Helpers.productionConfig },
101
+ [Helpers.databaseId2]: { production: Helpers.productionConfig, test: Helpers.testConfig },
102
+ });
103
+
104
+ expect(ConnectionConfiguration.configuredDatabaseIds()).toEqual([Helpers.databaseId2]);
105
+ });
106
+ });
107
+
108
+
109
+ describe('ConnectionConfiguration#dialect', () => {
110
+ it.each([
111
+ ['postgres', { test: Helpers.testConfig }, 'postgres'],
112
+ ['sqlite', { test: Helpers.sqliteConfig }, 'sqlite'],
113
+ ])('returns %s dialect', (_label, configByEnv, expectedDialect) => {
114
+ Helpers.mockConfigs({ [Helpers.databaseId1]: configByEnv });
115
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
116
+ expect(config.dialect).toEqual(expectedDialect);
117
+ });
118
+ });
119
+
120
+
121
+ describe('ConnectionConfiguration#storage', () => {
122
+ it ('returns sqlite storage path', () => {
123
+ Helpers.mockConfigs({ [Helpers.databaseId1]: { test: Helpers.sqliteConfig } });
124
+ const config = new ConnectionConfiguration(Helpers.databaseId1);
125
+ expect(config.storage).toEqual(`${process.cwd()}/config/db/database.test.sqlite`);
126
+ });
127
+ });
128
+ });
@@ -0,0 +1,144 @@
1
+ const Helpers = require('../helpers/migrator');
2
+
3
+
4
+ afterEach(() => {
5
+ jest.clearAllMocks();
6
+ });
7
+
8
+
9
+ describe('Migrator', () => {
10
+ describe('Migrator#run', () => {
11
+ it ('runs `up` in a transaction', async () => {
12
+ await Helpers.migrator.run();
13
+
14
+ expect(Helpers.transactionSpy).toHaveBeenCalledTimes(1);
15
+ expect(Helpers.migrationModule.up).toHaveBeenCalledTimes(1);
16
+ });
17
+
18
+ it ('throws when `up` is missing', async () => {
19
+ const originalUp = Helpers.migrationModule.up;
20
+ delete Helpers.migrationModule.up;
21
+
22
+ await expect(Helpers.migrator.run()).rejects.toThrow();
23
+
24
+ Helpers.migrationModule.up = originalUp;
25
+ });
26
+ });
27
+
28
+
29
+ describe('Migrator#down', () => {
30
+ it ('runs `down` in a transaction', async () => {
31
+ await Helpers.migrator.rollback();
32
+
33
+ expect(Helpers.transactionSpy).toHaveBeenCalledTimes(1);
34
+ expect(Helpers.migrationModule.down).toHaveBeenCalledTimes(1);
35
+ });
36
+
37
+ it ('does not throw when `down` is missing', async () => {
38
+ const originalDown = Helpers.migrationModule.down;
39
+ delete Helpers.migrationModule.down;
40
+
41
+ await expect(Helpers.migrator.rollback()).resolves.toBe(undefined);
42
+
43
+ Helpers.migrationModule.down = originalDown;
44
+ });
45
+ });
46
+
47
+
48
+ describe('Migrator#createTable', () => {
49
+ const defaultColumns = {
50
+ id: { allowNull: false, autoIncrement: true, primaryKey: true, type: 'INTEGER' },
51
+ created_at: { allowNull: false, type: 'DATE' },
52
+ updated_at: { allowNull: false, type: 'DATE' },
53
+ };
54
+
55
+ it ('creates tables with provided details', async () => {
56
+ const tableName = Helpers.randomString();
57
+ const details = { ...defaultColumns, [Helpers.randomString().toLowerCase()]: Helpers.randomNumber() };
58
+
59
+ await Helpers.migrator.createTable(tableName, details);
60
+
61
+ expect(Helpers.mockQueryInterface.createTable).toHaveBeenCalledWith(tableName, details);
62
+ });
63
+
64
+ it ('snake_cases created table columns', async () => {
65
+ const tableName = Helpers.randomString();
66
+ const details = { ...defaultColumns, myColumn: 1 };
67
+
68
+ await Helpers.migrator.createTable(tableName, details);
69
+
70
+ expect(Helpers.mockQueryInterface.createTable).toHaveBeenCalledWith(tableName, {
71
+ ...defaultColumns,
72
+ my_column: 1,
73
+ });
74
+ });
75
+ });
76
+
77
+
78
+ const tableOperations = [
79
+ ['dropTable', [Helpers.randomString()]],
80
+ ['addColumn', [Helpers.randomString(), Helpers.randomString(), Helpers.randomColumnDetails()]],
81
+ ['removeColumn', [Helpers.randomString(), Helpers.randomString()]],
82
+ ['changeColumn', [Helpers.randomString(), Helpers.randomString(), Helpers.randomColumnDetails()]],
83
+ ];
84
+ describe.each(tableOperations)('Migrator#%s', (methodName, args) => {
85
+ it ('delegates to the query interface', async () => {
86
+ await Helpers.expectQueryInterfaceCall(methodName, args);
87
+ });
88
+ });
89
+
90
+
91
+ describe('Migrator#renameColumn', () => {
92
+ it ('snake_cases renameColumn target', async () => {
93
+ const tableName = Helpers.randomString();
94
+ const oldName = Helpers.randomString();
95
+
96
+ await Helpers.migrator.renameColumn(tableName, oldName, 'myColumn');
97
+
98
+ expect(Helpers.mockQueryInterface.renameColumn).toHaveBeenCalledWith(tableName, oldName, 'my_column');
99
+ });
100
+ });
101
+
102
+
103
+ describe('Migrator#addIndex', () => {
104
+ it.each([
105
+ ['all supported options', { concurrently: true, unique: true, where: {}, name: 'foo' }],
106
+ ['empty options', {}],
107
+ ['falsey options', { concurrently: false, unique: false, where: null, name: null }],
108
+ ])('builds addIndex options for %s', async (_label, options) => {
109
+ const tableName = Helpers.randomString();
110
+ const fields = [Helpers.randomString(), Helpers.randomString()];
111
+ const expectedOptions = { fields };
112
+
113
+ if (options.concurrently) expectedOptions.concurrently = true;
114
+ if (options.unique) expectedOptions.unique = true;
115
+ if (options.where) expectedOptions.where = options.where;
116
+ if (options.name) expectedOptions.name = options.name;
117
+
118
+ await Helpers.migrator.addIndex(tableName, fields, options);
119
+
120
+ expect(Helpers.mockQueryInterface.addIndex).toHaveBeenCalledTimes(1);
121
+ expect(Helpers.mockQueryInterface.addIndex).toHaveBeenCalledWith(tableName, expectedOptions);
122
+ });
123
+ });
124
+
125
+
126
+ describe('Migrator#removeIndex', () => {
127
+ it.each([
128
+ ['default options', false, {}],
129
+ ['concurrently', true, { concurrently: true }],
130
+ ])('passes removeIndex options for %s', async (_label, concurrently, expectedOptions) => {
131
+ const tableName = Helpers.randomString();
132
+ const fields = [Helpers.randomString(), Helpers.randomString()];
133
+
134
+ await Helpers.migrator.removeIndex(tableName, fields, concurrently);
135
+
136
+ expect(Helpers.mockQueryInterface.removeIndex).toHaveBeenCalledTimes(1);
137
+ expect(Helpers.mockQueryInterface.removeIndex).toHaveBeenCalledWith(
138
+ tableName,
139
+ fields,
140
+ expectedOptions,
141
+ );
142
+ });
143
+ });
144
+ });
@@ -0,0 +1,48 @@
1
+ const { ConnectionConfiguration } = require('../../../lib/activeRecord/db/connectionConfiguration');
2
+ const { Connection } = require('../../../lib/activeRecord/db/connection');
3
+ const { QueryInterface } = require('../../../lib/activeRecord/db/queryInterface');
4
+ const { Sequelize } = require('sequelize');
5
+ const Helpers = require('../helpers/queryInterface');
6
+
7
+
8
+ const connection = new Connection();
9
+ const queryInterface = new QueryInterface(connection);
10
+
11
+ jest.mock('sequelize', () => {
12
+ const { MockSequelize } = require('../helpers/fixtures');
13
+ return { Sequelize: MockSequelize };
14
+ });
15
+
16
+ afterEach(() => {
17
+ jest.clearAllMocks();
18
+ });
19
+
20
+
21
+ describe('QueryInterface', () => {
22
+ describe('QueryInterface#allTables', () => {
23
+ it('loads all table details from sequelize query interface', async () => {
24
+ const tables = await queryInterface.allTables();
25
+
26
+ expect(Helpers.mockQueryInterface.showAllTables).toHaveBeenCalledTimes(1);
27
+ expect(Helpers.mockQueryInterface.describeTable).toHaveBeenCalledTimes(2);
28
+ expect(Helpers.mockQueryInterface.describeTable).toHaveBeenCalledWith(Helpers.tableName1);
29
+ expect(Helpers.mockQueryInterface.describeTable).toHaveBeenCalledWith(Helpers.tableName2);
30
+ expect(tables).toEqual({
31
+ [Helpers.tableName1]: { name: Helpers.tableName1 },
32
+ [Helpers.tableName2]: { name: Helpers.tableName2 },
33
+ });
34
+ });
35
+ });
36
+
37
+
38
+ describe('QueryInterface#transaction', () => {
39
+ it('delegates transaction callback to sequelize', async () => {
40
+ const callback = jest.fn();
41
+
42
+ await queryInterface.transaction(callback);
43
+
44
+ expect(connection._sequelize.transaction).toHaveBeenCalledTimes(1);
45
+ expect(connection._sequelize.transaction).toHaveBeenCalledWith(callback);
46
+ });
47
+ });
48
+ });
@@ -0,0 +1,32 @@
1
+ const { Connection} = require('../../../lib/activeRecord/db/connection');
2
+ const { ConnectionConfiguration } = require('../../../lib/activeRecord/db/connectionConfiguration');
3
+ const Mocks = require('./baseRecordMocks');
4
+ const TestHelpers = require('@vida-global/test-helpers');
5
+
6
+
7
+ /***************************************************************************************************
8
+ * VARIABLES / VARIABLE GENERATION
9
+ ***************************************************************************************************/
10
+ const colName = `${TestHelpers.Faker.Text.randomString()}_${TestHelpers.Faker.Text.randomString()}_${TestHelpers.Faker.Text.randomString()}`;
11
+ const schema = {created_at: {type: Mocks.dataTypeValue1},
12
+ updated_at: {type: Mocks.dataTypeValue2},
13
+ [colName]: {type: Mocks.dataTypeValue2}
14
+ };
15
+
16
+
17
+ /***************************************************************************************************
18
+ * MOCKS
19
+ ***************************************************************************************************/
20
+ const connectionConfig = {database: ' ', host: ' ', password: ' ', username: ' '};
21
+ const configSpy = jest.spyOn(ConnectionConfiguration, '_fetchAllConfigs');
22
+ configSpy.mockImplementation(() => ({default: {test: connectionConfig}}));
23
+
24
+ const connectionSpy = jest.spyOn(Connection.prototype, '_sequelize', 'get');
25
+ connectionSpy.mockImplementation(() => new Mocks.MockSequelize());
26
+
27
+
28
+ module.exports = {
29
+ colName,
30
+ ...Mocks,
31
+ schema,
32
+ }
@@ -0,0 +1,59 @@
1
+ const TestHelpers = require('@vida-global/test-helpers');
2
+
3
+
4
+ /***************************************************************************************************
5
+ * VARIABLES / VARIABLE GENERATION
6
+ ***************************************************************************************************/
7
+ const dataTypeKey1 = TestHelpers.Faker.Text.randomString();
8
+ const dataTypeValue1 = TestHelpers.Faker.Text.randomString();
9
+ const dataTypeKey2 = TestHelpers.Faker.Text.randomString();
10
+ const dataTypeValue2 = TestHelpers.Faker.Text.randomString();
11
+
12
+
13
+ /***************************************************************************************************
14
+ * MOCKS
15
+ ***************************************************************************************************/
16
+ class MockModel {
17
+ constructor(data, opts={}) {
18
+ this.dataValues = data || {}
19
+ this.options = opts;
20
+ for (const [k,v] of Object.entries(this.dataValues)) {
21
+ this[k] = v;
22
+ }
23
+ };
24
+ static addHook = jest.fn()
25
+ static init = jest.fn()
26
+ static findByPk = jest.fn();
27
+ static findAll = jest.fn();
28
+ static primaryKeyAttribute = TestHelpers.Faker.Text.randomString();
29
+ toJSON() { return this.dataValues }
30
+ }
31
+ MockModel.findAll.mockImplementation(() => []);
32
+
33
+
34
+ class MockSequelize {
35
+ static DataTypes = {
36
+ [dataTypeKey1]: {types: {postgres: [dataTypeValue1]}, key: dataTypeKey1},
37
+ [dataTypeKey2]: {types: {postgres: [dataTypeValue2]}, key: dataTypeKey2},
38
+ postgres: {}
39
+ }
40
+ }
41
+
42
+
43
+ const redisClient = {
44
+ del: jest.fn(),
45
+ mGet: jest.fn(),
46
+ mSet: jest.fn(),
47
+ }
48
+ const mockRedisClientFactory = () => redisClient;
49
+
50
+
51
+ module.exports = {
52
+ dataTypeKey1,
53
+ dataTypeValue1,
54
+ dataTypeKey2,
55
+ dataTypeValue2,
56
+ MockModel,
57
+ mockRedisClientFactory,
58
+ MockSequelize,
59
+ }
@@ -0,0 +1,28 @@
1
+ const TestHelpers = require('@vida-global/test-helpers');
2
+ const Fixtures = require('./fixtures');
3
+
4
+ const defaultConfig = Fixtures.buildPostgresConfig({ pool: { min: Math.random(), max: Math.random() } });
5
+ const secondaryConfig = Fixtures.buildPostgresConfig();
6
+ const sslConfig = Fixtures.buildPostgresConfig({ ssl: true });
7
+ const sqliteConfig = { dialect: 'sqlite' };
8
+
9
+ const originalNodeEnv = process.env.NODE_ENV;
10
+
11
+
12
+ function buildConfigs() {
13
+ return {
14
+ default: { test: defaultConfig, development: defaultConfig, production: defaultConfig },
15
+ [Fixtures.databaseId1]: { test: secondaryConfig, production: {} },
16
+ [Fixtures.databaseId2]: { test: sslConfig, production: {} },
17
+ sqlite: { test: sqliteConfig },
18
+ };
19
+ }
20
+
21
+
22
+ module.exports = {
23
+ ...Fixtures,
24
+ buildConfigs,
25
+ defaultConfig,
26
+ originalNodeEnv,
27
+ secondaryConfig,
28
+ };
@@ -0,0 +1,32 @@
1
+ const { ConnectionConfiguration } = require('../../../lib/activeRecord/db/connectionConfiguration');
2
+ const Fixtures = require('./fixtures');
3
+
4
+
5
+ const testConfig = Fixtures.buildPostgresConfig();
6
+ const productionConfig = Fixtures.buildPostgresConfig();
7
+ const sqliteConfig = { dialect: 'sqlite' };
8
+
9
+
10
+ const originalEnv = {
11
+ dbPoolMin: process.env.DB_POOL_MIN,
12
+ dbPoolMax: process.env.DB_POOL_MAX,
13
+ nodeEnv: process.env.NODE_ENV,
14
+ };
15
+
16
+
17
+ const fetchConfigsSpy = jest.spyOn(ConnectionConfiguration, '_fetchAllConfigs');
18
+ function mockConfigs(configs) {
19
+ fetchConfigsSpy.mockImplementation(() => configs);
20
+ }
21
+
22
+
23
+ module.exports = {
24
+ fetchConfigsSpy,
25
+ ...Fixtures,
26
+ mockConfigs,
27
+ originalEnv,
28
+ productionConfig,
29
+ sqliteConfig,
30
+ testConfig,
31
+ }
32
+
@@ -0,0 +1,39 @@
1
+ const TestHelpers = require('@vida-global/test-helpers');
2
+
3
+ /***************************************************************************************************
4
+ * VARIABLES / VARIABLE GENERATION
5
+ ***************************************************************************************************/
6
+ function buildPostgresConfig(overrides = {}) {
7
+ return {
8
+ database: TestHelpers.Faker.Text.randomString(),
9
+ host: TestHelpers.Faker.Text.randomString(),
10
+ password: TestHelpers.Faker.Text.randomString(),
11
+ port: TestHelpers.Faker.Math.randomNumber(),
12
+ username: TestHelpers.Faker.Text.randomString(),
13
+ ...overrides,
14
+ };
15
+ }
16
+
17
+ const databaseId1 = TestHelpers.Faker.Text.randomString();
18
+ const databaseId2 = TestHelpers.Faker.Text.randomString();
19
+
20
+
21
+ /***************************************************************************************************
22
+ * MOCKS
23
+ ***************************************************************************************************/
24
+ class MockSequelize {
25
+ constructor(_db, _user, _pass, options) {
26
+ this.options = options;
27
+ }
28
+
29
+ transaction = jest.fn(callback => callback());
30
+ close = jest.fn();
31
+ }
32
+
33
+
34
+ module.exports = {
35
+ buildPostgresConfig,
36
+ databaseId1,
37
+ databaseId2,
38
+ MockSequelize,
39
+ };
@@ -0,0 +1,78 @@
1
+ const { Migrator } = require('../../../lib/activeRecord/db/migrator');
2
+ const { ConnectionConfiguration } = require('../../../lib/activeRecord/db/connectionConfiguration');
3
+ const Fixtures = require('./fixtures');
4
+ const { QueryInterface } = require('../../../lib/activeRecord/db/queryInterface');
5
+ const { Sequelize } = require('sequelize');
6
+ const TestHelpers = require('@vida-global/test-helpers');
7
+
8
+
9
+ /***************************************************************************************************
10
+ * VARIABLES / VARIABLE GENERATION
11
+ ***************************************************************************************************/
12
+ const connectionConfig = { database: ' ', host: ' ', password: ' ', username: ' ' };
13
+ const migrationModule = { up: jest.fn(), down: jest.fn() };
14
+ const randomNumber = TestHelpers.Faker.Math.randomNumber
15
+ const randomString = TestHelpers.Faker.Text.randomString;
16
+ const mockQueryInterface = {
17
+ createTable: jest.fn(),
18
+ dropTable: jest.fn(),
19
+ addColumn: jest.fn(),
20
+ removeColumn: jest.fn(),
21
+ addIndex: jest.fn(),
22
+ removeIndex: jest.fn(),
23
+ renameColumn: jest.fn(),
24
+ changeColumn: jest.fn(),
25
+ };
26
+
27
+
28
+ function randomColumnDetails() {
29
+ return { [randomString()]: randomNumber() };
30
+ }
31
+
32
+
33
+ /***************************************************************************************************
34
+ * MOCKS
35
+ ***************************************************************************************************/
36
+ jest.mock('sequelize', () => {
37
+ class MockSequelize {
38
+ static DataTypes = { INTEGER: 'INTEGER', DATE: 'DATE' };
39
+ }
40
+ return { Sequelize: MockSequelize };
41
+ });
42
+ Sequelize.prototype.getQueryInterface = () => mockQueryInterface;
43
+
44
+
45
+ jest.spyOn(ConnectionConfiguration, '_fetchAllConfigs').mockImplementation(() => ({
46
+ default: { test: connectionConfig },
47
+ }));
48
+
49
+
50
+ const migrator = new Migrator();
51
+ jest.spyOn(migrator, 'migrationModule', 'get').mockImplementation(() => migrationModule);
52
+
53
+
54
+ const transactionSpy = jest.spyOn(QueryInterface.prototype, 'transaction');
55
+ transactionSpy.mockImplementation(callback => callback());
56
+
57
+
58
+ /***************************************************************************************************
59
+ * ASSERTIONS
60
+ ***************************************************************************************************/
61
+ async function expectQueryInterfaceCall(methodName, args) {
62
+ await migrator[methodName](...args);
63
+ expect(mockQueryInterface[methodName]).toHaveBeenCalledTimes(1);
64
+ expect(mockQueryInterface[methodName]).toHaveBeenCalledWith(...args);
65
+ }
66
+
67
+
68
+ module.exports = {
69
+ expectQueryInterfaceCall,
70
+ ...Fixtures,
71
+ migrationModule,
72
+ migrator,
73
+ mockQueryInterface,
74
+ randomColumnDetails,
75
+ randomNumber,
76
+ randomString,
77
+ transactionSpy,
78
+ };
@@ -0,0 +1,29 @@
1
+ const { Connection } = require('../../../lib/activeRecord/db/connection');
2
+ const { ConnectionConfiguration } = require('../../../lib/activeRecord/db/connectionConfiguration');
3
+ const Fixtures = require('../helpers/fixtures');
4
+ const { QueryInterface } = require('../../../lib/activeRecord/db/queryInterface');
5
+ const { Sequelize } = require('sequelize');
6
+ const TestHelpers = require('@vida-global/test-helpers');
7
+
8
+
9
+ const tableName1 = TestHelpers.Faker.Text.randomString();
10
+ const tableName2 = TestHelpers.Faker.Text.randomString();
11
+ const mockQueryInterface = {
12
+ showAllTables: jest.fn(() => [tableName1, tableName2]),
13
+ describeTable: jest.fn(tableName => ({ name: tableName })),
14
+ };
15
+
16
+
17
+ const connectionConfig = { database: ' ', host: ' ', password: ' ', username: ' ' };
18
+ const configSpy = jest.spyOn(ConnectionConfiguration, '_fetchAllConfigs');
19
+ configSpy.mockImplementation(() => ({ default: { test: connectionConfig } }));
20
+
21
+ Sequelize.prototype.getQueryInterface = () => mockQueryInterface;
22
+
23
+
24
+ module.exports = {
25
+ ...Fixtures,
26
+ mockQueryInterface,
27
+ tableName1,
28
+ tableName2,
29
+ }