@vida-global/core 1.4.6 → 2.0.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 (50) hide show
  1. package/README.md +1 -0
  2. package/config/newrelic-config.js +118 -0
  3. package/index.js +9 -5
  4. package/lib/activeRecord/baseRecord.js +49 -3
  5. package/lib/apm/agent.js +22 -0
  6. package/lib/apm/index.js +54 -0
  7. package/lib/apm/utils.js +43 -0
  8. package/lib/http/client.js +16 -2
  9. package/lib/jobQueue/README.md +63 -0
  10. package/lib/jobQueue/abstractJob.js +103 -0
  11. package/lib/jobQueue/abstractJobComponent.js +37 -0
  12. package/lib/jobQueue/index.js +10 -0
  13. package/lib/jobQueue/jobImporter.js +19 -0
  14. package/lib/jobQueue/queue.js +161 -0
  15. package/lib/jobQueue/worker.js +273 -0
  16. package/lib/logger/README.md +1 -1
  17. package/lib/logger/index.js +33 -15
  18. package/lib/logger/serverMiddleware.js +14 -12
  19. package/lib/redis/redisClient.js +32 -24
  20. package/lib/server/controllerImporter.js +9 -47
  21. package/lib/server/server.js +30 -13
  22. package/lib/server/serverController.js +93 -23
  23. package/lib/utils/abstractAutoImporter.js +64 -0
  24. package/package.json +4 -2
  25. package/test/activeRecord/baseRecord.test.js +129 -0
  26. package/test/activeRecord/db/connection.test.js +4 -1
  27. package/test/activeRecord/db/connectionConfiguration.test.js +9 -3
  28. package/test/activeRecord/helpers/baseRecordMocks.js +6 -4
  29. package/test/activeRecord/helpers/connection.js +0 -3
  30. package/test/activeRecord/helpers/connectionConfiguration.js +0 -8
  31. package/test/apm/agent.test.js +56 -0
  32. package/test/apm/utils.test.js +121 -0
  33. package/test/helpers/env.js +33 -0
  34. package/test/http/client.test.js +3 -3
  35. package/test/jobQueue/abstractJob.test.js +307 -0
  36. package/test/jobQueue/abstractJobComponent.test.js +110 -0
  37. package/test/jobQueue/helpers/abstractJob.js +26 -0
  38. package/test/jobQueue/helpers/apmMock.js +20 -0
  39. package/test/jobQueue/helpers/bullmqMock.js +67 -0
  40. package/test/jobQueue/helpers/env.js +29 -0
  41. package/test/jobQueue/helpers/fixtureJobs/notAJob.js +8 -0
  42. package/test/jobQueue/helpers/fixtureJobs/testJobA.js +14 -0
  43. package/test/jobQueue/helpers/fixtureJobs/testJobB.js +14 -0
  44. package/test/jobQueue/helpers/loggerMock.js +43 -0
  45. package/test/jobQueue/helpers/worker.js +38 -0
  46. package/test/jobQueue/queue.test.js +320 -0
  47. package/test/jobQueue/worker.test.js +526 -0
  48. package/test/logger/index.test.js +61 -0
  49. package/test/logger/serverMiddleware.test.js +6 -7
  50. package/test/server/serverController.test.js +180 -10
@@ -127,6 +127,178 @@ describe('VidaServerController', () => {
127
127
  });
128
128
 
129
129
 
130
+ describe('#hasParam', () => {
131
+ let controller;
132
+ beforeEach(() => {
133
+ const params = {foo: 'bar', empty: '', falsy: false, nully: null};
134
+ controller = new FooController({params}, {});
135
+ });
136
+
137
+ it ('returns true when the named key exists in params', () => {
138
+ expect(controller.hasParam('foo')).toBe(true);
139
+ });
140
+
141
+ it ('returns true when the value is an empty string', () => {
142
+ expect(controller.hasParam('empty')).toBe(true);
143
+ });
144
+
145
+ it ('returns true when the value is null', () => {
146
+ expect(controller.hasParam('nully')).toBe(true);
147
+ });
148
+
149
+ it ('returns true when the value is false', () => {
150
+ expect(controller.hasParam('falsy')).toBe(true);
151
+ });
152
+
153
+ it ('returns false when the named key is not in params', () => {
154
+ expect(controller.hasParam('nope')).toBe(false);
155
+ });
156
+ });
157
+
158
+
159
+ describe('#coerceBoolean', () => {
160
+ const controller = new FooController({}, {});
161
+
162
+ it ('returns true when passed boolean true', () => {
163
+ expect(controller.coerceBoolean(true)).toBe(true);
164
+ });
165
+
166
+ it ('returns false when passed boolean false', () => {
167
+ expect(controller.coerceBoolean(false)).toBe(false);
168
+ });
169
+
170
+ it.each([
171
+ ['true'],
172
+ ['TRUE'],
173
+ ['1'],
174
+ ['yes'],
175
+ ['on'],
176
+ [' ON '],
177
+ ])('coerces "%s" to true', (input) => {
178
+ expect(controller.coerceBoolean(input)).toBe(true);
179
+ });
180
+
181
+ it.each([
182
+ ['false'],
183
+ ['FALSE'],
184
+ ['0'],
185
+ ['no'],
186
+ ['off'],
187
+ [' off '],
188
+ ])('coerces "%s" to false', (input) => {
189
+ expect(controller.coerceBoolean(input)).toBe(false);
190
+ });
191
+
192
+ it ('returns the fallback for an unrecognized string', () => {
193
+ const fallback = TestHelpers.Faker.Text.randomString();
194
+ expect(controller.coerceBoolean('maybe', {fallback})).toBe(fallback);
195
+ });
196
+
197
+ it ('returns the fallback for an empty/whitespace string', () => {
198
+ const fallback = TestHelpers.Faker.Text.randomString();
199
+ expect(controller.coerceBoolean(' ', {fallback})).toBe(fallback);
200
+ });
201
+
202
+ it.each([
203
+ [null],
204
+ [undefined],
205
+ [123],
206
+ [{}],
207
+ [[]],
208
+ ])('returns the fallback for non-string, non-boolean input (%p)', (input) => {
209
+ const fallback = TestHelpers.Faker.Text.randomString();
210
+ expect(controller.coerceBoolean(input, {fallback})).toBe(fallback);
211
+ });
212
+
213
+ it ('defaults the fallback to undefined when no options are given', () => {
214
+ expect(controller.coerceBoolean('maybe')).toBe(undefined);
215
+ });
216
+ });
217
+
218
+
219
+ describe('#coerceInteger', () => {
220
+ const controller = new FooController({}, {});
221
+
222
+ it ('returns the fallback for null', () => {
223
+ const fallback = TestHelpers.Faker.Text.randomString();
224
+ expect(controller.coerceInteger(null, {fallback})).toBe(fallback);
225
+ });
226
+
227
+ it ('returns the fallback for undefined', () => {
228
+ const fallback = TestHelpers.Faker.Text.randomString();
229
+ expect(controller.coerceInteger(undefined, {fallback})).toBe(fallback);
230
+ });
231
+
232
+ it.each([
233
+ [''],
234
+ [' '],
235
+ ])('returns the fallback for empty/whitespace string (%p)', (input) => {
236
+ const fallback = TestHelpers.Faker.Text.randomString();
237
+ expect(controller.coerceInteger(input, {fallback})).toBe(fallback);
238
+ });
239
+
240
+ it ('returns the fallback for a non-numeric string', () => {
241
+ const fallback = TestHelpers.Faker.Text.randomString();
242
+ expect(controller.coerceInteger('abc', {fallback})).toBe(fallback);
243
+ });
244
+
245
+ it ('parses an integer string to an integer', () => {
246
+ expect(controller.coerceInteger('42')).toBe(42);
247
+ });
248
+
249
+ it ('floors a decimal string value', () => {
250
+ expect(controller.coerceInteger('3.7')).toBe(3);
251
+ });
252
+
253
+ it ('accepts an integer value directly', () => {
254
+ expect(controller.coerceInteger(42)).toBe(42);
255
+ });
256
+
257
+ it ('floors a decimal numeric value', () => {
258
+ expect(controller.coerceInteger(3.7)).toBe(3);
259
+ });
260
+
261
+ it ('clamps to min when the value is below min', () => {
262
+ expect(controller.coerceInteger(1, {min: 5})).toBe(5);
263
+ });
264
+
265
+ it ('clamps to max when the value is above max', () => {
266
+ expect(controller.coerceInteger(100, {max: 50})).toBe(50);
267
+ });
268
+
269
+ it ('returns the fallback when nonNegative is set and the value is negative', () => {
270
+ const fallback = TestHelpers.Faker.Text.randomString();
271
+ expect(controller.coerceInteger(-3, {nonNegative: true, fallback})).toBe(fallback);
272
+ });
273
+ });
274
+
275
+
276
+ describe('#coerceObject', () => {
277
+ const controller = new FooController({}, {});
278
+
279
+ it ('returns a plain object unchanged', () => {
280
+ const input = {foo: TestHelpers.Faker.Text.randomString()};
281
+ expect(controller.coerceObject(input)).toBe(input);
282
+ });
283
+
284
+ it.each([
285
+ [null],
286
+ [undefined],
287
+ [[1, 2]],
288
+ ['string'],
289
+ [42],
290
+ [true],
291
+ ])('returns the fallback for non-plain-object input (%p)', (input) => {
292
+ const fallback = {foo: TestHelpers.Faker.Text.randomString()};
293
+ expect(controller.coerceObject(input, {fallback})).toBe(fallback);
294
+ });
295
+
296
+ it ('defaults the fallback to an empty object', () => {
297
+ expect(controller.coerceObject(null)).toEqual({});
298
+ });
299
+ });
300
+
301
+
130
302
  describe('.validateParameters', () => {
131
303
  const paramName1 = TestHelpers.Faker.Text.randomString();
132
304
  const paramName2 = TestHelpers.Faker.Text.randomString();
@@ -739,17 +911,15 @@ describe('VidaServerController', () => {
739
911
 
740
912
 
741
913
  describe('#logger', () => {
742
- it ('uses the a logger with http scope', () => {
743
- expect(controller.logger.scope).toBe('http');
744
- });
914
+ it ('returns a child of the passed logger, scoped to the request id', () => {
915
+ const childLogger = {};
916
+ const passedLogger = { child: jest.fn(() => childLogger) };
917
+ request.id = TestHelpers.Faker.Text.randomString();
918
+
919
+ const c = new FooController(request, response, passedLogger);
745
920
 
746
- it ('uses the request id', () => {
747
- const id1 = TestHelpers.Faker.Text.randomString();
748
- const id2 = TestHelpers.Faker.Text.randomString();
749
- const controller1 = new FooController({ id: id1 }, response);
750
- const controller2 = new FooController({ id: id2 }, response);
751
- expect(controller1.logger.id).toBe(id1);
752
- expect(controller2.logger.id).toBe(id2);
921
+ expect(passedLogger.child).toHaveBeenCalledWith(request.id);
922
+ expect(c.logger).toBe(childLogger);
753
923
  });
754
924
  });
755
925