@adaptivestone/framework 4.7.0 → 4.8.1

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 (96) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/Cli.js +1 -0
  3. package/commands/SyncIndexes.js +1 -1
  4. package/commands/migration/Create.js +4 -3
  5. package/controllers/Auth.js +3 -5
  6. package/controllers/index.js +0 -2
  7. package/coverage/base.css +224 -0
  8. package/coverage/block-navigation.js +87 -0
  9. package/coverage/clover.xml +3573 -0
  10. package/coverage/coverage-final.json +44 -0
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/framework/config/auth.js.html +100 -0
  13. package/coverage/framework/config/http.js.html +112 -0
  14. package/coverage/framework/config/i18n.js.html +121 -0
  15. package/coverage/framework/config/index.html +236 -0
  16. package/coverage/framework/config/log.js.html +151 -0
  17. package/coverage/framework/config/mail.js.html +172 -0
  18. package/coverage/framework/config/mongo.js.html +94 -0
  19. package/coverage/framework/config/rateLimiter.js.html +133 -0
  20. package/coverage/framework/config/redis.js.html +97 -0
  21. package/coverage/framework/config/validate.js.html +94 -0
  22. package/coverage/framework/controllers/Auth.js.html +715 -0
  23. package/coverage/framework/controllers/Home.js.html +169 -0
  24. package/coverage/framework/controllers/index.html +146 -0
  25. package/coverage/framework/controllers/index.js.html +259 -0
  26. package/coverage/framework/controllers/test/SomeController.js.html +571 -0
  27. package/coverage/framework/controllers/test/index.html +116 -0
  28. package/coverage/framework/helpers/files.js.html +310 -0
  29. package/coverage/framework/helpers/index.html +131 -0
  30. package/coverage/framework/helpers/logger.js.html +142 -0
  31. package/coverage/framework/helpers/redis/clearNamespace.js.html +127 -0
  32. package/coverage/framework/helpers/redis/index.html +116 -0
  33. package/coverage/framework/index.html +116 -0
  34. package/coverage/framework/models/Migration.js.html +130 -0
  35. package/coverage/framework/models/Sequence.js.html +151 -0
  36. package/coverage/framework/models/User.js.html +859 -0
  37. package/coverage/framework/models/index.html +146 -0
  38. package/coverage/framework/modules/AbstractController.js.html +1309 -0
  39. package/coverage/framework/modules/AbstractModel.js.html +268 -0
  40. package/coverage/framework/modules/Base.js.html +244 -0
  41. package/coverage/framework/modules/index.html +146 -0
  42. package/coverage/framework/server.js.html +1279 -0
  43. package/coverage/framework/services/cache/Cache.js.html +445 -0
  44. package/coverage/framework/services/cache/index.html +116 -0
  45. package/coverage/framework/services/documentation/DocumentationGenerator.js.html +592 -0
  46. package/coverage/framework/services/documentation/index.html +116 -0
  47. package/coverage/framework/services/http/HttpServer.js.html +373 -0
  48. package/coverage/framework/services/http/index.html +116 -0
  49. package/coverage/framework/services/http/middleware/AbstractMiddleware.js.html +238 -0
  50. package/coverage/framework/services/http/middleware/Auth.js.html +145 -0
  51. package/coverage/framework/services/http/middleware/GetUserByToken.js.html +223 -0
  52. package/coverage/framework/services/http/middleware/I18n.js.html +442 -0
  53. package/coverage/framework/services/http/middleware/Pagination.js.html +253 -0
  54. package/coverage/framework/services/http/middleware/PrepareAppInfo.js.html +139 -0
  55. package/coverage/framework/services/http/middleware/RateLimiter.js.html +472 -0
  56. package/coverage/framework/services/http/middleware/RequestLogger.js.html +151 -0
  57. package/coverage/framework/services/http/middleware/RequestParser.js.html +199 -0
  58. package/coverage/framework/services/http/middleware/Role.js.html +172 -0
  59. package/coverage/framework/services/http/middleware/index.html +251 -0
  60. package/coverage/framework/services/http/middleware/test/CheckFlag.js.html +139 -0
  61. package/coverage/framework/services/http/middleware/test/index.html +116 -0
  62. package/coverage/framework/services/messaging/email/index.html +116 -0
  63. package/coverage/framework/services/messaging/email/index.js.html +739 -0
  64. package/coverage/framework/services/messaging/index.html +116 -0
  65. package/coverage/framework/services/messaging/index.js.html +100 -0
  66. package/coverage/framework/services/validate/ValidateService.js.html +556 -0
  67. package/coverage/framework/services/validate/drivers/AbstractValidator.js.html +196 -0
  68. package/coverage/framework/services/validate/drivers/CustomValidator.js.html +241 -0
  69. package/coverage/framework/services/validate/drivers/YupValidator.js.html +394 -0
  70. package/coverage/framework/services/validate/drivers/index.html +146 -0
  71. package/coverage/framework/services/validate/index.html +116 -0
  72. package/coverage/index.html +356 -0
  73. package/coverage/prettify.css +1 -0
  74. package/coverage/prettify.js +2 -0
  75. package/coverage/sort-arrow-sprite.png +0 -0
  76. package/coverage/sorter.js +196 -0
  77. package/helpers/files.js +75 -0
  78. package/helpers/logger.js +19 -0
  79. package/models/Migration.test.js +19 -0
  80. package/models/User.test.js +3 -3
  81. package/modules/AbstractController.js +1 -3
  82. package/modules/Base.js +6 -56
  83. package/modules/BaseCli.js +0 -3
  84. package/package.json +3 -2
  85. package/server.d.ts +14 -0
  86. package/server.js +165 -86
  87. package/services/cache/Cache.js +10 -5
  88. package/services/cache/Cache.test.js +81 -0
  89. package/services/http/middleware/Auth.test.js +57 -0
  90. package/services/http/middleware/I18n.test.js +16 -4
  91. package/services/http/middleware/PrepareAppInfo.test.js +1 -1
  92. package/services/http/middleware/RateLimiter.test.js +7 -7
  93. package/services/http/middleware/Role.test.js +93 -0
  94. package/services/validate/ValidateService.test.js +3 -3
  95. package/tests/setup.js +3 -0
  96. package/tests/setupVitest.js +3 -4
package/server.js CHANGED
@@ -1,9 +1,14 @@
1
1
  /* eslint-disable no-console */
2
2
  const EventEmitter = require('node:events');
3
+ const { hrtime } = require('node:process');
3
4
 
4
5
  require('dotenv').config();
5
6
  const merge = require('deepmerge');
6
7
  const winston = require('winston');
8
+ const { getFilesPathWithInheritance } = require('./helpers/files');
9
+ const { consoleLogger } = require('./helpers/logger');
10
+
11
+ const Cache = require('./services/cache/Cache');
7
12
 
8
13
  /**
9
14
  * Main framework class.
@@ -11,6 +16,8 @@ const winston = require('winston');
11
16
  class Server {
12
17
  #realLogger = null;
13
18
 
19
+ #isInited = false;
20
+
14
21
  /**
15
22
  * Construct new server
16
23
  * @param {Object} config main config object
@@ -46,6 +53,7 @@ class Server {
46
53
  this.cache = {
47
54
  configs: new Map(),
48
55
  models: new Map(),
56
+ modelConstructors: new Map(),
49
57
  };
50
58
 
51
59
  this.cli = false;
@@ -57,13 +65,11 @@ class Server {
57
65
  * @returns {Promise}
58
66
  */
59
67
  async startServer(callbackBefore404 = async () => Promise.resolve()) {
60
- // const HttpServer = require('./services/http/HttpServer');
61
- // const ControllerManager = require('./controllers/index');
62
- // TODO wait until https://github.com/nodejs/node/issues/35889
63
68
  const [{ default: HttpServer }, { default: ControllerManager }] =
64
69
  await Promise.all([
65
70
  import('./services/http/HttpServer.js'), // Speed optimisation
66
71
  import('./controllers/index.js'), // Speed optimisation
72
+ this.init(),
67
73
  ]);
68
74
 
69
75
  this.addErrorHandling();
@@ -78,20 +84,150 @@ class Server {
78
84
  this.app.httpServer.add404Page();
79
85
  }
80
86
 
87
+ /**
88
+ * Do an initialization (config reading, etc)
89
+ * @returns {Promise}
90
+ */
91
+ async init({ isSkipModelInit = false } = {}) {
92
+ if (this.#isInited) {
93
+ return true;
94
+ }
95
+
96
+ console.time('Server init. Done');
97
+ console.time('Loading config and model files. Time');
98
+ await Promise.all([this.#initConfigFiles(), this.#loadModelFiles()]);
99
+ console.timeEnd('Loading config and model files. Time');
100
+
101
+ if (!isSkipModelInit) {
102
+ await this.initAllModels();
103
+ }
104
+
105
+ this.#isInited = true;
106
+
107
+ console.timeEnd('Server init. Done');
108
+
109
+ return true;
110
+ }
111
+
112
+ /**
113
+ * Load model and init them
114
+ * @returns {Promise}
115
+ */
116
+ async initAllModels() {
117
+ console.time('Initing models. Time');
118
+
119
+ if (this.app.getConfig('mongo').connectionString) {
120
+ for (const [modelName, ModelConstructor] of this.cache
121
+ .modelConstructors) {
122
+ try {
123
+ const model = new ModelConstructor(this.app);
124
+ this.cache.models.set(modelName, model.mongooseModel);
125
+ } catch (e) {
126
+ this.app.logger.error(
127
+ `Problem with model ${modelName}, ${e.message}`,
128
+ );
129
+ this.app.logger.error(e);
130
+ }
131
+ }
132
+ } else {
133
+ this.app.logger.info(
134
+ 'Skipping inited models as we have no mongo connection string',
135
+ );
136
+ }
137
+
138
+ console.timeEnd('Initing models. Time');
139
+ }
140
+
141
+ async #initConfigFiles() {
142
+ const files = await getFilesPathWithInheritance({
143
+ internalFolder: `${__dirname}/config`,
144
+ externalFolder: this.app.foldersConfig.config,
145
+ loggerFileType: 'CONFIG',
146
+ logger: (m) => consoleLogger('info', m),
147
+ filter: {
148
+ startWithCapital: false,
149
+ },
150
+ });
151
+
152
+ const configFiles = {};
153
+
154
+ for (const file of files) {
155
+ const config = file.file.split('.');
156
+ if (!configFiles[config[0]]) {
157
+ configFiles[config[0]] = {};
158
+ }
159
+ if (config.length === 2) {
160
+ configFiles[config[0]].default = file.path;
161
+ } else {
162
+ configFiles[config[0]][config[1]] = file.path;
163
+ }
164
+ }
165
+
166
+ const loadConfig = async (configName, values) => {
167
+ const promises = [import(values.default)];
168
+ if (process.env.NODE_ENV && values[process.env.NODE_ENV]) {
169
+ promises.push(import(values[process.env.NODE_ENV]));
170
+ }
171
+ const result = await Promise.all(promises);
172
+ return {
173
+ name: configName,
174
+ finalValue: merge(result[0].default, result[1]?.default || {}, {
175
+ arrayMerge: (destinationArray, sourceArray) => sourceArray,
176
+ }),
177
+ };
178
+ };
179
+
180
+ const loadingPromises = [];
181
+
182
+ for (const [configFile, value] of Object.entries(configFiles)) {
183
+ loadingPromises.push(loadConfig(configFile, value));
184
+ }
185
+
186
+ const configs = await Promise.all(loadingPromises);
187
+
188
+ for (const config of configs) {
189
+ this.cache.configs.set(config.name, config.finalValue);
190
+ }
191
+ return true;
192
+ }
193
+
194
+ async #loadModelFiles() {
195
+ const files = await getFilesPathWithInheritance({
196
+ internalFolder: `${__dirname}/models`,
197
+ externalFolder: this.app.foldersConfig.models,
198
+ loggerFileType: 'MODEL',
199
+ logger: (m) => consoleLogger('info', m),
200
+ });
201
+
202
+ const promises = [];
203
+ for (const file of files) {
204
+ const t = hrtime.bigint();
205
+ promises.push(
206
+ import(file.path).then((f) => ({
207
+ name: file.file.split('.')[0],
208
+ file: f,
209
+ took: hrtime.bigint() - t,
210
+ })),
211
+ );
212
+ }
213
+
214
+ const loadedModels = await Promise.all(promises);
215
+
216
+ for (const model of loadedModels) {
217
+ this.cache.modelConstructors.set(model.name, model.file.default);
218
+ }
219
+ return true;
220
+ }
221
+
81
222
  /**
82
223
  * Add error logging on promise reject
83
224
  */
84
- // eslint-disable-next-line class-methods-use-this
85
225
  addErrorHandling() {
86
- process.on('uncaughtException', console.error);
87
- process.on('unhandledRejection', (reason, p) => {
88
- console.log(
89
- 'Possibly Unhandled Rejection at: Promise ',
90
- p,
91
- ' reason: ',
92
- reason,
93
- );
94
- console.trace('unhandledRejection');
226
+ process.on('uncaughtException', (e) =>
227
+ this.app.logger.error('uncaughtException', e),
228
+ );
229
+ process.on('unhandledRejection', (e) => {
230
+ this.app.logger.error('unhandledRejection', e);
95
231
  });
96
232
  }
97
233
 
@@ -106,24 +242,14 @@ class Server {
106
242
  * @returns {Object} config object. Structure depends of config file
107
243
  */
108
244
  getConfig(configName) {
109
- // const configName = name.charAt(0).toUpperCase() + name.slice(1);
110
245
  if (!this.cache.configs.has(configName)) {
111
- let envConfig = {};
112
- if (process.env.NODE_ENV) {
113
- envConfig =
114
- this.getFileWithExtendingInhirence(
115
- 'config',
116
- `${configName}.${process.env.NODE_ENV}.js`,
117
- ) || envConfig;
246
+ if (!this.#isInited) {
247
+ throw new Error('You should call Server.init() before using getConfig');
118
248
  }
119
- this.cache.configs.set(
120
- configName,
121
- merge(
122
- this.getFileWithExtendingInhirence('config', configName),
123
- envConfig,
124
- { arrayMerge: (destinationArray, sourceArray) => sourceArray },
125
- ),
249
+ this.app.logger.warn(
250
+ `You asked for config ${configName} that not exists. Please check you codebase `,
126
251
  );
252
+ return {};
127
253
  }
128
254
  return this.cache.configs.get(configName);
129
255
  }
@@ -225,24 +351,21 @@ class Server {
225
351
  */
226
352
  getModel(modelName) {
227
353
  if (modelName.endsWith('s')) {
228
- console.warn(
354
+ this.app.logger.warn(
229
355
  `Probably your model name '${modelName}' in plural from. Try to avoid plural form`,
230
356
  );
231
357
  }
358
+ if (!this.#isInited) {
359
+ this.app.logger.error(
360
+ new Error('You should call Server.init() before using getModel'),
361
+ );
362
+ return false;
363
+ }
232
364
  if (!this.cache.models.has(modelName)) {
233
- const Model = this.getFileWithExtendingInhirence('models', modelName);
234
- if (!Model) {
235
- console.error(`Model not found: ${modelName}`);
236
- return false;
237
- }
238
- try {
239
- const model = new Model(this.app);
240
-
241
- this.cache.models.set(modelName, model.mongooseModel);
242
- } catch (e) {
243
- console.error(`Problem with model ${modelName}, ${e.message}`);
244
- console.error(e);
245
- }
365
+ this.app.logger.warn(
366
+ `You asked for model ${modelName} that not exists. Please check you codebase `,
367
+ );
368
+ return {};
246
369
  }
247
370
  return this.cache.models.get(modelName);
248
371
  }
@@ -254,9 +377,7 @@ class Server {
254
377
  */
255
378
  async runCliCommand(commandName, args) {
256
379
  if (!this.cli) {
257
- // TODO wait until https://github.com/nodejs/node/issues/35889
258
380
  const { default: BaseCli } = await import('./modules/BaseCli.js'); // Speed optimisation
259
- // const BaseCli = require('./modules/BaseCli');
260
381
  this.cli = new BaseCli(this);
261
382
  }
262
383
  return this.cli.run(commandName, args);
@@ -268,52 +389,10 @@ class Server {
268
389
  */
269
390
  getCache() {
270
391
  if (!this.cacheService) {
271
- // eslint-disable-next-line global-require
272
- const Cache = require('./services/cache/Cache'); // Speed optimisation
273
392
  this.cacheService = new Cache(this.app);
274
393
  }
275
394
  return this.cacheService;
276
395
  }
277
-
278
- /**
279
- * Get file using Inhirence (ability to overrite models, configs, etc)
280
- * @param {('models'|'config')} fileType type of file to load
281
- * @param {string} fileName name of file to load
282
- */
283
- getFileWithExtendingInhirence(fileType, fileName) {
284
- let file;
285
- try {
286
- // eslint-disable-next-line global-require, import/no-dynamic-require
287
- file = require(`${this.config.folders[fileType]}/${fileName}`);
288
- } catch (e) {
289
- try {
290
- // eslint-disable-next-line global-require, import/no-dynamic-require
291
- file = require(`./${fileType}/${fileName}`);
292
- } catch (e2) {
293
- const levels = [
294
- 'error',
295
- 'warn',
296
- 'info',
297
- 'http',
298
- 'verbose',
299
- 'debug',
300
- 'silly',
301
- ];
302
-
303
- if (
304
- !process.env.LOGGER_CONSOLE_LEVEL ||
305
- levels.indexOf(process.env.LOGGER_CONSOLE_LEVEL) > 0 // as a warn level
306
- ) {
307
- console.warn(
308
- `Config not found '${fileName}'. This can be a normal (in case this an environment config)`,
309
- );
310
- }
311
-
312
- file = false;
313
- }
314
- }
315
- return file;
316
- }
317
396
  }
318
397
 
319
398
  module.exports = Server;
@@ -1,13 +1,17 @@
1
- const redis = require('redis');
2
1
  const Base = require('../../modules/Base');
3
2
 
4
3
  class Cache extends Base {
5
4
  constructor(app) {
5
+ super(app);
6
+ this.whenReady = this.#init();
7
+ }
8
+
9
+ async #init() {
6
10
  // todo for now only redis. refactor for drives support in future
7
11
  // at least memory and redis drivers should be presented
8
12
  // memory drives should works on master process level
9
13
  // we should support multiple cashe same time
10
- super(app);
14
+ const redis = await import('redis');
11
15
  const conf = this.app.getConfig('redis');
12
16
  this.redisClient = redis.createClient({
13
17
  url: conf.url,
@@ -33,6 +37,7 @@ class Cache extends Base {
33
37
  }
34
38
 
35
39
  async getSetValue(keyValue, onNotFound, storeTime = 60 * 5) {
40
+ await this.whenReady;
36
41
  if (!this.redisClient.isOpen) {
37
42
  await this.redisClient.connect();
38
43
  }
@@ -58,9 +63,7 @@ class Cache extends Base {
58
63
  try {
59
64
  result = await onNotFound();
60
65
  } catch (e) {
61
- this.logger.error(
62
- `Cache onNotFound for key '${key}' error: ${e.message}`,
63
- );
66
+ this.logger.error(`Cache onNotFound for key '${key}' error: ${e}`);
64
67
  this.promiseMapping.delete(key);
65
68
  reject(e);
66
69
  return Promise.reject(e);
@@ -100,6 +103,8 @@ class Cache extends Base {
100
103
  }
101
104
 
102
105
  async removeKey(keyValue) {
106
+ await this.whenReady;
107
+
103
108
  if (!this.redisClient.isOpen) {
104
109
  await this.redisClient.connect();
105
110
  }
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { setTimeout } from 'node:timers/promises';
3
+
4
+ describe('cache', () => {
5
+ const time = Date.now();
6
+
7
+ it('can get set values', async () => {
8
+ expect.assertions(2);
9
+
10
+ const { cache } = global.server.app;
11
+
12
+ const res = await cache.getSetValue('TEST_TIME', () => time);
13
+ expect(res).toStrictEqual(time);
14
+
15
+ const res2 = await cache.getSetValue('TEST_TIME', () => '123');
16
+ expect(res2).toStrictEqual(time);
17
+ });
18
+
19
+ it('can delete values', async () => {
20
+ expect.assertions(1);
21
+ const { cache } = global.server.app;
22
+
23
+ await cache.removeKey('TEST_TIME');
24
+
25
+ const res2 = await cache.getSetValue('TEST_TIME', () => '123');
26
+ expect(res2).toBe('123');
27
+ });
28
+
29
+ it('can works with big int', async () => {
30
+ expect.assertions(2);
31
+ const { cache } = global.server.app;
32
+
33
+ const res = await cache.getSetValue('BIN_INT', () => 1n);
34
+ expect(res).toBe(1n);
35
+
36
+ const res2 = await cache.getSetValue('BIN_INT', () => '1111');
37
+ expect(res2).toBe(1n);
38
+ });
39
+
40
+ it('can execute only one request per time', async () => {
41
+ expect.assertions(3);
42
+ const { cache } = global.server.app;
43
+ let counter = 0;
44
+
45
+ const f = async () => {
46
+ await setTimeout(10);
47
+ counter += 1;
48
+ return 1;
49
+ };
50
+
51
+ const [res, res1] = await Promise.all([
52
+ cache.getSetValue('T', f),
53
+ cache.getSetValue('T', f),
54
+ ]);
55
+
56
+ expect(counter).toBe(1);
57
+
58
+ expect(res).toBe(1);
59
+ expect(res1).toBe(1);
60
+ });
61
+
62
+ it('can handle problems on onNotFound', async () => {
63
+ expect.assertions(1);
64
+ const getAsyncThrow = async () => {
65
+ throw new Error('err');
66
+ };
67
+ let err;
68
+
69
+ const { cache } = global.server.app;
70
+
71
+ try {
72
+ await Promise.all([
73
+ cache.getSetValue('THROW', getAsyncThrow),
74
+ cache.getSetValue('THROW', getAsyncThrow),
75
+ ]);
76
+ } catch (e) {
77
+ err = e;
78
+ }
79
+ expect(err.message).toBe('err');
80
+ });
81
+ });
@@ -0,0 +1,57 @@
1
+ import { beforeAll, describe, it, expect } from 'vitest';
2
+ import Auth from './Auth';
3
+
4
+ describe('atuh middleware methods', () => {
5
+ let middleware;
6
+ beforeAll(() => {
7
+ middleware = new Auth(global.server.app);
8
+ });
9
+ it('have description fields', async () => {
10
+ expect.assertions(1);
11
+ expect(middleware.constructor.description).toBeDefined();
12
+ });
13
+
14
+ it('middleware pass when user presented', async () => {
15
+ expect.assertions(1);
16
+ let isCalled = false;
17
+ const nextFunction = () => {
18
+ isCalled = true;
19
+ };
20
+ const req = {
21
+ appInfo: {
22
+ user: true,
23
+ },
24
+ };
25
+ await middleware.middleware(req, {}, nextFunction);
26
+ expect(isCalled).toBeTruthy();
27
+ });
28
+
29
+ it('middleware NOT pass when user NOT presented', async () => {
30
+ expect.assertions(3);
31
+ let isCalled = false;
32
+ let status;
33
+ let isSend;
34
+ const nextFunction = () => {
35
+ isCalled = true;
36
+ };
37
+ const req = {
38
+ appInfo: {}, // no user
39
+ };
40
+ await middleware.middleware(
41
+ req,
42
+ {
43
+ status(statusCode) {
44
+ status = statusCode;
45
+ return this;
46
+ },
47
+ json() {
48
+ isSend = true;
49
+ },
50
+ },
51
+ nextFunction,
52
+ );
53
+ expect(isCalled).toBeFalsy();
54
+ expect(status).toBe(401);
55
+ expect(isSend).toBeTruthy();
56
+ });
57
+ });
@@ -12,7 +12,7 @@ describe('i18n middleware methods', () => {
12
12
  });
13
13
 
14
14
  it('detectors should works correctly', async () => {
15
- expect.assertions(5);
15
+ expect.assertions(6);
16
16
  const request = {
17
17
  get: () => 'en',
18
18
  query: {
@@ -42,10 +42,13 @@ describe('i18n middleware methods', () => {
42
42
  };
43
43
  lang = await middleware.detectLang(request);
44
44
  expect(lang).toBe('en');
45
+
46
+ lang = await middleware.detectLang(request, false);
47
+ expect(lang).toBe('en-GB');
45
48
  });
46
49
 
47
50
  it('middleware that works', async () => {
48
- expect.assertions(4);
51
+ expect.assertions(6);
49
52
  let isCalled = false;
50
53
  const nextFunction = () => {
51
54
  isCalled = true;
@@ -55,10 +58,19 @@ describe('i18n middleware methods', () => {
55
58
  appInfo: {},
56
59
  };
57
60
  await middleware.middleware(req, {}, nextFunction);
58
- expect(isCalled).toBe(true);
61
+ expect(isCalled).toBeTruthy();
59
62
  expect(req.appInfo.i18n).toBeDefined();
63
+ expect(req.appInfo.i18n.language).toBe('en');
60
64
  expect(req.appInfo.i18n.t('aaaaa')).toBe('aaaaa');
61
65
  expect(req.i18n.t('aaaaa')).toBe('aaaaa'); // proxy test
66
+
67
+ const req2 = {
68
+ get: () => 'fakeLang',
69
+ appInfo: {},
70
+ };
71
+
72
+ await middleware.middleware(req2, {}, nextFunction);
73
+ expect(req2.appInfo.i18n.language).toBe('en');
62
74
  });
63
75
 
64
76
  it('middleware disabled', async () => {
@@ -75,7 +87,7 @@ describe('i18n middleware methods', () => {
75
87
  appInfo: {},
76
88
  };
77
89
  await middleware.middleware(req, {}, nextFunction);
78
- expect(isCalled).toBe(true);
90
+ expect(isCalled).toBeTruthy();
79
91
  expect(req.appInfo.i18n).toBeDefined();
80
92
  expect(req.appInfo.i18n.t('aaaaa')).toBe('aaaaa');
81
93
  expect(req.i18n.t('aaaaa')).toBe('aaaaa'); // proxy test
@@ -17,7 +17,7 @@ describe('prepareAppInfo methods', () => {
17
17
  };
18
18
  const req = {};
19
19
  await middleware.middleware(req, {}, nextFunction);
20
- expect(isCalled).toBe(true);
20
+ expect(isCalled).toBeTruthy();
21
21
  expect(req.appInfo).toBeDefined();
22
22
  req.appInfo.test = 5;
23
23
  await middleware.middleware(req, {}, nextFunction);
@@ -113,7 +113,7 @@ describe('rate limiter methods', () => {
113
113
  () => {},
114
114
  );
115
115
  expect(status).toBe(500);
116
- expect(isSend).toBe(true);
116
+ expect(isSend).toBeTruthy();
117
117
  });
118
118
 
119
119
  const makeOneRequest = async ({ rateLimiter, driver, request }) => {
@@ -154,7 +154,7 @@ describe('rate limiter methods', () => {
154
154
  rateLimiter: mongoRateLimiter,
155
155
  request: { ip: '10.10.0.1' },
156
156
  });
157
- expect(isNextCalled).toBe(true);
157
+ expect(isNextCalled).toBeTruthy();
158
158
  });
159
159
 
160
160
  it('middleware should works with a memory drivers', async () => {
@@ -163,7 +163,7 @@ describe('rate limiter methods', () => {
163
163
  driver: 'memory',
164
164
  request: { ip: '10.10.0.1' },
165
165
  });
166
- expect(isNextCalled).toBe(true);
166
+ expect(isNextCalled).toBeTruthy();
167
167
  });
168
168
 
169
169
  it('middleware should works with a redis drivers', async () => {
@@ -172,7 +172,7 @@ describe('rate limiter methods', () => {
172
172
  driver: 'redis',
173
173
  request: { ip: '10.10.0.1' },
174
174
  });
175
- expect(isNextCalled).toBe(true);
175
+ expect(isNextCalled).toBeTruthy();
176
176
  });
177
177
 
178
178
  it('middleware should rate limits for us. mongo driver', async () => {
@@ -188,7 +188,7 @@ describe('rate limiter methods', () => {
188
188
  const isSend = data.find((obj) => obj.isSend);
189
189
 
190
190
  expect(status.status).toBe(429);
191
- expect(isSend.isSend).toBe(true);
191
+ expect(isSend.isSend).toBeTruthy();
192
192
  });
193
193
 
194
194
  it('middleware should rate limits for us. memory driver', async () => {
@@ -208,7 +208,7 @@ describe('rate limiter methods', () => {
208
208
  const isSend = data.find((obj) => obj.isSend);
209
209
 
210
210
  expect(status.status).toBe(429);
211
- expect(isSend.isSend).toBe(true);
211
+ expect(isSend.isSend).toBeTruthy();
212
212
  });
213
213
 
214
214
  it('middleware should rate limits for us. redis driver', async () => {
@@ -228,6 +228,6 @@ describe('rate limiter methods', () => {
228
228
  const isSend = data.find((obj) => obj.isSend);
229
229
 
230
230
  expect(status.status).toBe(429);
231
- expect(isSend.isSend).toBe(true);
231
+ expect(isSend.isSend).toBeTruthy();
232
232
  });
233
233
  });