@vida-global/core 1.4.1 → 1.4.3
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/index.js +13 -1
- package/lib/server/errors.js +65 -12
- package/lib/server/index.js +3 -2
- package/lib/server/serverController.js +64 -72
- package/package.json +1 -1
- package/test/server/errors.test.js +54 -0
- package/test/server/serverController.test.js +46 -8
package/index.js
CHANGED
|
@@ -5,10 +5,22 @@ const ActiveRecord = require('./lib/activeRecord');
|
|
|
5
5
|
const redisLibs = require('./lib/redis');
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
const {
|
|
9
|
+
AbstractServerError,
|
|
10
|
+
ApiDocsGenerator,
|
|
11
|
+
VidaServer,
|
|
12
|
+
VidaServerController,
|
|
13
|
+
} = serverLibs;
|
|
14
|
+
const serverErrorsToExport = Object.values(serverLibs).filter(obj => obj.prototype instanceof AbstractServerError);
|
|
15
|
+
|
|
16
|
+
|
|
8
17
|
module.exports = {
|
|
9
18
|
ActiveRecord,
|
|
10
19
|
...httpLibs,
|
|
11
20
|
logger,
|
|
12
21
|
...redisLibs,
|
|
13
|
-
...
|
|
22
|
+
...serverErrorsToExport,
|
|
23
|
+
ApiDocsGenerator,
|
|
24
|
+
VidaServer,
|
|
25
|
+
VidaServerController,
|
|
14
26
|
};
|
package/lib/server/errors.js
CHANGED
|
@@ -1,16 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
const Statuses = {
|
|
2
|
+
BadRequest: 400,
|
|
3
|
+
Unauthorized: 401,
|
|
4
|
+
PaymentRequired: 402,
|
|
5
|
+
Forbidden: 403,
|
|
6
|
+
NotFound: 404,
|
|
7
|
+
MethodNotAllowed: 405,
|
|
8
|
+
RequestTimeout: 408,
|
|
9
|
+
Conflict: 409,
|
|
10
|
+
Gone: 410,
|
|
11
|
+
ContentTooLarge: 413,
|
|
12
|
+
UnsupportedMediaType: 415,
|
|
13
|
+
UnprocessableContent: 422,
|
|
14
|
+
Locked: 423,
|
|
15
|
+
TooManyRequests: 429,
|
|
16
|
+
Server: 500,
|
|
17
|
+
NotImplemented: 501,
|
|
18
|
+
BadGateway: 502,
|
|
19
|
+
ServiceUnavailable: 503,
|
|
20
|
+
GatewayTimeout: 504,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
const classNameForErrorType = (type) => `${type}Error`;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AbstractServerError extends Error {
|
|
2
29
|
#message;
|
|
3
|
-
|
|
30
|
+
#body;
|
|
31
|
+
constructor(message, body) {
|
|
4
32
|
super();
|
|
5
33
|
this.#message = message;
|
|
34
|
+
this.#body = body || null;
|
|
6
35
|
}
|
|
7
36
|
get message() { return this.#message; };
|
|
37
|
+
get body() { return this.#body; };
|
|
38
|
+
get type() {
|
|
39
|
+
const clsName = this.constructor.name;
|
|
40
|
+
return clsName == 'ServerError' ? 'ServerError' : clsName.replace('Error', '')
|
|
41
|
+
}
|
|
8
42
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
const ErrorClasses = {};
|
|
46
|
+
for (const [type, statusCode] of Object.entries(Statuses)) {
|
|
47
|
+
const clsName = classNameForErrorType(type);
|
|
48
|
+
const cls = class extends AbstractServerError {};
|
|
49
|
+
ErrorClasses[clsName] = cls
|
|
50
|
+
Object.defineProperty(cls, 'name', { value: clsName });
|
|
51
|
+
Object.defineProperty(cls, 'statusCode', { value: statusCode });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class ValidationError extends AbstractServerError {
|
|
14
56
|
#fields;
|
|
15
57
|
constructor(message, fields) {
|
|
16
58
|
super(message);
|
|
@@ -20,11 +62,22 @@ class ValidationError extends ServerError {
|
|
|
20
62
|
}
|
|
21
63
|
|
|
22
64
|
|
|
65
|
+
function errorForStatusCode(code) {
|
|
66
|
+
for (const [type, aCode] of Object.entries(Statuses)) {
|
|
67
|
+
if (code == aCode) {
|
|
68
|
+
return ErrorClasses[classNameForErrorType(type)];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
23
76
|
module.exports = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
77
|
+
...ErrorClasses,
|
|
78
|
+
AuthorizationError: ErrorClasses.UnauthorizedError, // Deprecated
|
|
79
|
+
errorForStatusCode,
|
|
80
|
+
AbstractServerError,
|
|
81
|
+
Statuses,
|
|
29
82
|
ValidationError
|
|
30
83
|
}
|
package/lib/server/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
const { VidaServer } = require('./server');
|
|
2
2
|
const { VidaServerController } = require('./serverController');
|
|
3
|
-
const
|
|
3
|
+
const Errors = require('./errors');
|
|
4
4
|
const { ApiDocsGenerator } = require('./apiDocsGenerator');
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
module.exports = {
|
|
7
8
|
ApiDocsGenerator,
|
|
8
|
-
...
|
|
9
|
+
...Errors,
|
|
9
10
|
VidaServer,
|
|
10
11
|
VidaServerController,
|
|
11
12
|
}
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
const { logger } = require('../logger');
|
|
2
2
|
const { camelize, singularize } = require('inflection');
|
|
3
|
-
const
|
|
4
|
-
ConflictError,
|
|
5
|
-
ForbiddenError,
|
|
6
|
-
NotFoundError,
|
|
7
|
-
ServerError,
|
|
8
|
-
ValidationError } = require('./errors');
|
|
3
|
+
const Errors = require('./errors');
|
|
9
4
|
|
|
10
5
|
|
|
11
6
|
const AUTH_CALLBACK_NAME = 'authenticateRequest';
|
|
12
7
|
|
|
13
8
|
|
|
14
9
|
class VidaServerController {
|
|
15
|
-
#afterCallbacks
|
|
16
|
-
#
|
|
17
|
-
#
|
|
10
|
+
#afterCallbacks = [];
|
|
11
|
+
#afterCallbacksToSkip = [];
|
|
12
|
+
#beforeCallbacks = [];
|
|
13
|
+
#beforeCallbacksToSkip = [];
|
|
14
|
+
#callbacksSetUp = false;
|
|
18
15
|
#params;
|
|
19
|
-
#rendered
|
|
16
|
+
#rendered = false;
|
|
20
17
|
#request;
|
|
21
18
|
#response;
|
|
22
19
|
|
|
@@ -122,25 +119,22 @@ class VidaServerController {
|
|
|
122
119
|
|
|
123
120
|
|
|
124
121
|
async #handleError(err) {
|
|
125
|
-
if (err instanceof AuthorizationError) {
|
|
126
|
-
await this.renderUnauthorized(err.message);
|
|
122
|
+
if (err instanceof Errors.AuthorizationError) {
|
|
123
|
+
await this.renderUnauthorized(err.message, err.body);
|
|
127
124
|
|
|
128
|
-
} else if (err instanceof
|
|
129
|
-
await this.renderConflict(err.message);
|
|
130
|
-
|
|
131
|
-
} else if (err instanceof ForbiddenError) {
|
|
132
|
-
await this.renderForbidden(err.message);
|
|
133
|
-
|
|
134
|
-
} else if (err instanceof NotFoundError) {
|
|
135
|
-
await this.renderNotFound(err.message);
|
|
136
|
-
|
|
137
|
-
} else if (err instanceof ValidationError) {
|
|
125
|
+
} else if (err instanceof Errors.ValidationError) {
|
|
138
126
|
await this.renderErrors(err.message, err.fields);
|
|
139
127
|
|
|
128
|
+
} else if (err instanceof Errors.AbstractServerError) {
|
|
129
|
+
const renderer = `render${err.type}`;
|
|
130
|
+
await this[renderer](err.message, err.body);
|
|
131
|
+
|
|
140
132
|
} else {
|
|
141
133
|
this._response.error = err;
|
|
142
|
-
let message;
|
|
143
|
-
if (
|
|
134
|
+
let message = null;
|
|
135
|
+
if (process.env.NODE_ENV != 'development') {
|
|
136
|
+
// don't show error details outside of development
|
|
137
|
+
} else if (typeof err == 'string') {
|
|
144
138
|
message = err;
|
|
145
139
|
} else {
|
|
146
140
|
message = err.message;
|
|
@@ -170,8 +164,6 @@ class VidaServerController {
|
|
|
170
164
|
|
|
171
165
|
|
|
172
166
|
async renderErrors(message, fields) {
|
|
173
|
-
this.statusCode = 400;
|
|
174
|
-
|
|
175
167
|
const errors = {message: null, fields: {}};
|
|
176
168
|
|
|
177
169
|
if (message && !fields && typeof message == 'object') {
|
|
@@ -179,7 +171,6 @@ class VidaServerController {
|
|
|
179
171
|
message = null;
|
|
180
172
|
}
|
|
181
173
|
|
|
182
|
-
if (message) errors.message = message;
|
|
183
174
|
if (fields) {
|
|
184
175
|
for (const [field, values] of Object.entries(fields)) {
|
|
185
176
|
if (!Array.isArray(values)) fields[field] = [values];
|
|
@@ -187,15 +178,7 @@ class VidaServerController {
|
|
|
187
178
|
errors.fields = fields;
|
|
188
179
|
}
|
|
189
180
|
|
|
190
|
-
await this.
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
async renderServerError(message=null) {
|
|
195
|
-
if (process.env.NODE_ENV != 'development') {
|
|
196
|
-
message = null;
|
|
197
|
-
}
|
|
198
|
-
return await this.#renderError(500, message);
|
|
181
|
+
await this.renderBadRequest(message, { errors });
|
|
199
182
|
}
|
|
200
183
|
|
|
201
184
|
|
|
@@ -213,6 +196,8 @@ class VidaServerController {
|
|
|
213
196
|
if (body === undefined) return null;
|
|
214
197
|
if (!body || typeof body != 'object') return body;
|
|
215
198
|
|
|
199
|
+
body = structuredClone(body);
|
|
200
|
+
|
|
216
201
|
if (body.toApiResponse) {
|
|
217
202
|
const formattedBody = await body.toApiResponse(options);
|
|
218
203
|
return await this.processJSONBody(formattedBody, options);
|
|
@@ -285,27 +270,19 @@ class VidaServerController {
|
|
|
285
270
|
return 'too many requests';
|
|
286
271
|
case 500:
|
|
287
272
|
return 'server error';
|
|
273
|
+
case 501:
|
|
274
|
+
return 'not implemented';
|
|
275
|
+
case 502:
|
|
276
|
+
return 'bad gateway';
|
|
277
|
+
case 503:
|
|
278
|
+
return 'service unavailable';
|
|
279
|
+
case 504:
|
|
280
|
+
return 'gateway timeout';
|
|
288
281
|
}
|
|
289
282
|
}
|
|
290
283
|
|
|
291
284
|
|
|
292
285
|
#setupStatusRenderers() {
|
|
293
|
-
const errorStatuses = {
|
|
294
|
-
Unauthorized: 401,
|
|
295
|
-
PaymentRequired: 402,
|
|
296
|
-
Forbidden: 403,
|
|
297
|
-
NotFound: 404,
|
|
298
|
-
MethodNotAllowed: 405,
|
|
299
|
-
RequestTimeout: 408,
|
|
300
|
-
Conflict: 409,
|
|
301
|
-
Gone: 410,
|
|
302
|
-
ContentTooLarge: 413,
|
|
303
|
-
UnsupportedMediaType: 415,
|
|
304
|
-
UnprocessableContent: 422,
|
|
305
|
-
Locked: 423,
|
|
306
|
-
TooManyRequests: 429,
|
|
307
|
-
}
|
|
308
|
-
|
|
309
286
|
const successStatuses = {
|
|
310
287
|
CreationSuccessful: 201,
|
|
311
288
|
Accepted: 202,
|
|
@@ -317,23 +294,26 @@ class VidaServerController {
|
|
|
317
294
|
PermanentRedirect: 308,
|
|
318
295
|
}
|
|
319
296
|
|
|
320
|
-
for (
|
|
321
|
-
|
|
322
|
-
|
|
297
|
+
for (let [type, statusCode] of Object.entries(Errors.Statuses)) {
|
|
298
|
+
if (type == 'Server') type = 'ServerError';
|
|
299
|
+
this[`render${type}`] = async function(message=null, body=null) {
|
|
300
|
+
return await this.#renderError(statusCode, message, body);
|
|
323
301
|
}
|
|
324
302
|
}
|
|
325
303
|
|
|
326
|
-
for (
|
|
327
|
-
this[`render${
|
|
328
|
-
return await this.#renderSuccess(statusCode,
|
|
304
|
+
for (let [type, statusCode] of Object.entries(successStatuses)) {
|
|
305
|
+
this[`render${type}`] = async function(body=null) {
|
|
306
|
+
return await this.#renderSuccess(statusCode, body);
|
|
329
307
|
}
|
|
330
308
|
}
|
|
331
309
|
}
|
|
332
310
|
|
|
333
311
|
|
|
334
|
-
async #renderError(statusCode, message) {
|
|
312
|
+
async #renderError(statusCode, message, body) {
|
|
335
313
|
this.statusCode = statusCode;
|
|
336
|
-
|
|
314
|
+
body = structuredClone(body || {});
|
|
315
|
+
body.errors = body.errors || {};
|
|
316
|
+
body.errors.message = message || null;
|
|
337
317
|
return await this.render(body);
|
|
338
318
|
}
|
|
339
319
|
|
|
@@ -413,24 +393,40 @@ class VidaServerController {
|
|
|
413
393
|
}
|
|
414
394
|
|
|
415
395
|
|
|
396
|
+
skipBeforeCallback(callback, options={}) {
|
|
397
|
+
this.#addCallback(callback, options, this.#beforeCallbacksToSkip);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
skipAfterCallback(callback, options={}) {
|
|
402
|
+
this.#addCallback(callback, options, this.#afterCallbacksToSkip);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
|
|
416
406
|
#addCallback(callback, options, callbacksList) {
|
|
417
407
|
callbacksList.push({ callback, options });
|
|
418
408
|
}
|
|
419
409
|
|
|
420
410
|
|
|
421
411
|
async runBeforeCallbacks(actionName) {
|
|
422
|
-
return await this.#runCallbacks(this.#beforeCallbacks, actionName);
|
|
412
|
+
return await this.#runCallbacks(this.#beforeCallbacks, this.#beforeCallbacksToSkip, actionName);
|
|
423
413
|
}
|
|
424
414
|
|
|
425
415
|
|
|
426
416
|
async runAfterCallbacks(actionName) {
|
|
427
|
-
return await this.#runCallbacks(this.#afterCallbacks, actionName);
|
|
417
|
+
return await this.#runCallbacks(this.#afterCallbacks, this.#afterCallbacksToSkip, actionName);
|
|
428
418
|
}
|
|
429
419
|
|
|
430
420
|
|
|
431
|
-
async #runCallbacks(callbacksList, actionName) {
|
|
421
|
+
async #runCallbacks(callbacksList, callbacksToSkipList, actionName) {
|
|
422
|
+
let toSkip = callbacksToSkipList.filter(({ callback, options }) => {
|
|
423
|
+
return this.#shouldRunCallback(actionName, options);
|
|
424
|
+
});
|
|
425
|
+
toSkip = toSkip.map(({ callback }) => callback);
|
|
426
|
+
|
|
432
427
|
for (const { callback, options } of callbacksList) {
|
|
433
428
|
if (!this.#shouldRunCallback(actionName, options)) continue;
|
|
429
|
+
if (toSkip.includes(callback)) continue;
|
|
434
430
|
const result = await this.#runCallback(callback)
|
|
435
431
|
if (result === false) return false;
|
|
436
432
|
}
|
|
@@ -470,7 +466,7 @@ class VidaServerController {
|
|
|
470
466
|
if (parameterErrors.length) errors[parameterName] = parameterErrors;
|
|
471
467
|
}
|
|
472
468
|
|
|
473
|
-
if (Object.keys(errors).length) throw new ValidationError('', errors);
|
|
469
|
+
if (Object.keys(errors).length) throw new Errors.ValidationError('', errors);
|
|
474
470
|
}
|
|
475
471
|
|
|
476
472
|
|
|
@@ -677,14 +673,10 @@ class VidaServerController {
|
|
|
677
673
|
}
|
|
678
674
|
|
|
679
675
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
NotFound: NotFoundError,
|
|
685
|
-
Server: ServerError,
|
|
686
|
-
Validation: ValidationError
|
|
687
|
-
}
|
|
676
|
+
const errorClasses = Object.values(Errors).filter(cls => cls == Errors.ServerError || cls.prototype instanceof Errors.AbstractServerError);
|
|
677
|
+
VidaServerController.prototype.Errors = Object.fromEntries(errorClasses.map(cls => {
|
|
678
|
+
return [cls.name.replace('Error', ''), cls]
|
|
679
|
+
}));
|
|
688
680
|
|
|
689
681
|
|
|
690
682
|
module.exports = {
|
package/package.json
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const Errors = require('../../lib/server/errors');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const Statuses = [
|
|
5
|
+
['BadRequest', 400],
|
|
6
|
+
['Unauthorized', 401],
|
|
7
|
+
['PaymentRequired', 402],
|
|
8
|
+
['Forbidden', 403],
|
|
9
|
+
['NotFound', 404],
|
|
10
|
+
['MethodNotAllowed', 405],
|
|
11
|
+
['RequestTimeout', 408],
|
|
12
|
+
['Conflict', 409],
|
|
13
|
+
['Gone', 410],
|
|
14
|
+
['ContentTooLarge', 413],
|
|
15
|
+
['UnsupportedMediaType', 415],
|
|
16
|
+
['UnprocessableContent', 422],
|
|
17
|
+
['Locked', 423],
|
|
18
|
+
['TooManyRequests', 429],
|
|
19
|
+
['Server', 500],
|
|
20
|
+
['NotImplemented', 501],
|
|
21
|
+
['BadGateway', 502],
|
|
22
|
+
['ServiceUnavailable', 503],
|
|
23
|
+
['GatewayTimeout', 504],
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
describe.each(Statuses)('describe %s', (type, statusCode) => {
|
|
28
|
+
const cls = Errors.errorForStatusCode(statusCode);
|
|
29
|
+
|
|
30
|
+
describe('statusCode', () => {
|
|
31
|
+
it (`equals ${statusCode}`, () => {
|
|
32
|
+
expect(cls.statusCode).toEqual(statusCode);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
describe('type', () => {
|
|
38
|
+
const typeStr = type == 'Server' ? 'ServerError' : type;
|
|
39
|
+
it (`equals ${typeStr}`, () => {
|
|
40
|
+
expect(new cls().type).toEqual(typeStr);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
describe('errorForStatusCode', () => {
|
|
48
|
+
it.each(Statuses)('returns a %sError for %s', (type, statusCode) => {
|
|
49
|
+
const clsName = `${type}Error`;
|
|
50
|
+
const cls = Errors[clsName];
|
|
51
|
+
expect(Errors.errorForStatusCode(statusCode)).toEqual(cls);
|
|
52
|
+
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -464,17 +464,39 @@ describe('VidaServerController', () => {
|
|
|
464
464
|
|
|
465
465
|
describe('#performRequest', () => {
|
|
466
466
|
const errorHandlers = [
|
|
467
|
-
['renderUnauthorized',
|
|
468
|
-
['
|
|
469
|
-
['
|
|
470
|
-
['
|
|
471
|
-
['
|
|
472
|
-
|
|
467
|
+
['renderUnauthorized', 'AuthorizationError'],
|
|
468
|
+
['renderErrors', 'ValidationError'],
|
|
469
|
+
['renderBadRequest', 'BadRequestError'],
|
|
470
|
+
['renderUnauthorized', 'UnauthorizedError'],
|
|
471
|
+
['renderPaymentRequired', 'PaymentRequiredError'],
|
|
472
|
+
['renderForbidden', 'ForbiddenError'],
|
|
473
|
+
['renderNotFound', 'NotFoundError'],
|
|
474
|
+
['renderMethodNotAllowed', 'MethodNotAllowedError'],
|
|
475
|
+
['renderRequestTimeout', 'RequestTimeoutError'],
|
|
476
|
+
['renderConflict', 'ConflictError'],
|
|
477
|
+
['renderGone', 'GoneError'],
|
|
478
|
+
['renderContentTooLarge', 'ContentTooLargeError'],
|
|
479
|
+
['renderUnsupportedMediaType', 'UnsupportedMediaTypeError'],
|
|
480
|
+
['renderUnprocessableContent', 'UnprocessableContentError'],
|
|
481
|
+
['renderLocked', 'LockedError'],
|
|
482
|
+
['renderTooManyRequests', 'TooManyRequestsError'],
|
|
483
|
+
['renderServerError', 'ServerError'],
|
|
484
|
+
['renderNotImplemented', 'NotImplementedError'],
|
|
485
|
+
['renderBadGateway', 'BadGatewayError'],
|
|
486
|
+
['renderServiceUnavailable', 'ServiceUnavailableError'],
|
|
487
|
+
['renderGatewayTimeout', 'GatewayTimeoutError'],
|
|
488
|
+
];
|
|
473
489
|
|
|
474
490
|
it.each(errorHandlers)('calls %s when %s is thrown', async (handlerName, errorClsName) => {
|
|
475
491
|
const controller = new FooController({}, {});
|
|
492
|
+
const key = TestHelpers.Faker.Text.randomString();
|
|
493
|
+
const value = TestHelpers.Faker.Text.randomString();
|
|
494
|
+
const body = {[key]: value};
|
|
476
495
|
const message = TestHelpers.Faker.Text.randomString();
|
|
477
|
-
|
|
496
|
+
|
|
497
|
+
if (!Errors[errorClsName]) console.log(errorClsName);
|
|
498
|
+
|
|
499
|
+
const error = new Errors[errorClsName](message, body);
|
|
478
500
|
if (handlerName == 'renderErrors') error.errors = randomPayload();
|
|
479
501
|
|
|
480
502
|
controller[handlerName] = jest.fn();
|
|
@@ -485,7 +507,7 @@ describe('VidaServerController', () => {
|
|
|
485
507
|
if (handlerName == 'renderErrors') {
|
|
486
508
|
expect(controller[handlerName]).toHaveBeenCalledWith(message, error.fields);
|
|
487
509
|
} else {
|
|
488
|
-
expect(controller[handlerName]).toHaveBeenCalledWith(message);
|
|
510
|
+
expect(controller[handlerName]).toHaveBeenCalledWith(message, body);
|
|
489
511
|
}
|
|
490
512
|
});
|
|
491
513
|
|
|
@@ -611,6 +633,11 @@ describe('VidaServerController', () => {
|
|
|
611
633
|
['renderUnprocessableContent', 422],
|
|
612
634
|
['renderLocked', 423],
|
|
613
635
|
['renderTooManyRequests', 429],
|
|
636
|
+
['renderServerError', 500],
|
|
637
|
+
['renderNotImplemented', 501],
|
|
638
|
+
['renderBadGateway', 502],
|
|
639
|
+
['renderServiceUnavailable', 503],
|
|
640
|
+
['renderGatewayTimeout', 504],
|
|
614
641
|
]
|
|
615
642
|
|
|
616
643
|
describe.each(errorHandlers)('#%s', (handlerName, statusCode) => {
|
|
@@ -631,6 +658,17 @@ describe('VidaServerController', () => {
|
|
|
631
658
|
expect(controller.render).toHaveBeenCalledTimes(1);
|
|
632
659
|
expect(controller.render).toHaveBeenCalledWith({errors: {message: msg}});
|
|
633
660
|
});
|
|
661
|
+
|
|
662
|
+
it ('includes a provided body and message', async () => {
|
|
663
|
+
const key = TestHelpers.Faker.Text.randomString();
|
|
664
|
+
const val = TestHelpers.Faker.Text.randomString();
|
|
665
|
+
const body = {[key]: val};
|
|
666
|
+
const msg = TestHelpers.Faker.Text.randomString();
|
|
667
|
+
const expected = {...body, errors: {message: msg}};
|
|
668
|
+
await controller[handlerName](msg, body);
|
|
669
|
+
expect(controller.render).toHaveBeenCalledTimes(1);
|
|
670
|
+
expect(controller.render).toHaveBeenCalledWith(expected);
|
|
671
|
+
});
|
|
634
672
|
});
|
|
635
673
|
});
|
|
636
674
|
|