3 var Code = require('code');
4 var Boom = require('../lib');
5 var Lab = require('lab');
15 var lab = exports.lab = Lab.script();
16 var describe = lab.describe;
18 var expect = Code.expect;
21 it('returns the same object when already boom', function (done) {
23 var error = Boom.badRequest();
24 var wrapped = Boom.wrap(error);
25 expect(error).to.equal(wrapped);
29 it('returns an error with info when constructed using another error', function (done) {
31 var error = new Error('ka-boom');
33 var err = Boom.wrap(error);
34 expect(err.xyz).to.equal(123);
35 expect(err.message).to.equal('ka-boom');
36 expect(err.output).to.deep.equal({
40 error: 'Internal Server Error',
41 message: 'An internal server error occurred'
45 expect(err.data).to.equal(null);
49 it('does not override data when constructed using another error', function (done) {
51 var error = new Error('ka-boom');
52 error.data = { useful: 'data' };
53 var err = Boom.wrap(error);
54 expect(err.data).to.equal(error.data);
58 it('sets new message when none exists', function (done) {
60 var error = new Error();
61 var wrapped = Boom.wrap(error, 400, 'something bad');
62 expect(wrapped.message).to.equal('something bad');
66 it('throws when statusCode is not a number', function (done) {
71 }).to.throw('First argument must be a number (400+): x');
75 it('will cast a number-string to an integer', function (done) {
78 { input: '404', result: 404 },
79 { input: '404.1', result: 404 },
80 { input: 400, result: 400 },
81 { input: 400.123, result: 400 }];
82 for (var i = 0, il = codes.length; i < il; ++i) {
84 var err = Boom.create(code.input);
85 expect(err.output.statusCode).to.equal(code.result);
91 it('throws when statusCode is not finite', function (done) {
96 }).to.throw('First argument must be a number (400+): null');
100 it('sets error code to unknown', function (done) {
102 var err = Boom.create(999);
103 expect(err.output.payload.error).to.equal('Unknown');
107 describe('create()', function () {
109 it('does not sets null message', function (done) {
111 var error = Boom.unauthorized(null);
112 expect(error.output.payload.message).to.not.exist();
113 expect(error.isServer).to.be.false();
117 it('sets message and data', function (done) {
119 var error = Boom.badRequest('Missing data', { type: 'user' });
120 expect(error.data.type).to.equal('user');
121 expect(error.output.payload.message).to.equal('Missing data');
126 describe('isBoom()', function () {
128 it('returns true for Boom object', function (done) {
130 expect(Boom.badRequest().isBoom).to.equal(true);
134 it('returns false for Error object', function (done) {
136 expect((new Error()).isBoom).to.not.exist();
141 describe('badRequest()', function () {
143 it('returns a 400 error statusCode', function (done) {
145 var error = Boom.badRequest();
147 expect(error.output.statusCode).to.equal(400);
148 expect(error.isServer).to.be.false();
152 it('sets the message with the passed in message', function (done) {
154 expect(Boom.badRequest('my message').message).to.equal('my message');
158 it('sets the message to HTTP status if none provided', function (done) {
160 expect(Boom.badRequest().message).to.equal('Bad Request');
165 describe('unauthorized()', function () {
167 it('returns a 401 error statusCode', function (done) {
169 var err = Boom.unauthorized();
170 expect(err.output.statusCode).to.equal(401);
171 expect(err.output.headers).to.deep.equal({});
175 it('sets the message with the passed in message', function (done) {
177 expect(Boom.unauthorized('my message').message).to.equal('my message');
181 it('returns a WWW-Authenticate header when passed a scheme', function (done) {
183 var err = Boom.unauthorized('boom', 'Test');
184 expect(err.output.statusCode).to.equal(401);
185 expect(err.output.headers['WWW-Authenticate']).to.equal('Test error="boom"');
189 it('returns a WWW-Authenticate header set to the schema array value', function (done) {
191 var err = Boom.unauthorized(null, ['Test','one','two']);
192 expect(err.output.statusCode).to.equal(401);
193 expect(err.output.headers['WWW-Authenticate']).to.equal('Test, one, two');
197 it('returns a WWW-Authenticate header when passed a scheme and attributes', function (done) {
199 var err = Boom.unauthorized('boom', 'Test', { a: 1, b: 'something', c: null, d: 0 });
200 expect(err.output.statusCode).to.equal(401);
201 expect(err.output.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0", error="boom"');
202 expect(err.output.payload.attributes).to.deep.equal({ a: 1, b: 'something', c: '', d: 0, error: 'boom' });
206 it('returns a WWW-Authenticate header when passed attributes, missing error', function (done) {
208 var err = Boom.unauthorized(null, 'Test', { a: 1, b: 'something', c: null, d: 0 });
209 expect(err.output.statusCode).to.equal(401);
210 expect(err.output.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0"');
211 expect(err.isMissing).to.equal(true);
215 it('sets the isMissing flag when error message is empty', function (done) {
217 var err = Boom.unauthorized('', 'Basic');
218 expect(err.isMissing).to.equal(true);
222 it('does not set the isMissing flag when error message is not empty', function (done) {
224 var err = Boom.unauthorized('message', 'Basic');
225 expect(err.isMissing).to.equal(undefined);
229 it('sets a WWW-Authenticate when passed as an array', function (done) {
231 var err = Boom.unauthorized('message', ['Basic', 'Example e="1"', 'Another x="3", y="4"']);
232 expect(err.output.headers['WWW-Authenticate']).to.equal('Basic, Example e="1", Another x="3", y="4"');
238 describe('methodNotAllowed()', function () {
240 it('returns a 405 error statusCode', function (done) {
242 expect(Boom.methodNotAllowed().output.statusCode).to.equal(405);
246 it('sets the message with the passed in message', function (done) {
248 expect(Boom.methodNotAllowed('my message').message).to.equal('my message');
254 describe('notAcceptable()', function () {
256 it('returns a 406 error statusCode', function (done) {
258 expect(Boom.notAcceptable().output.statusCode).to.equal(406);
262 it('sets the message with the passed in message', function (done) {
264 expect(Boom.notAcceptable('my message').message).to.equal('my message');
270 describe('proxyAuthRequired()', function () {
272 it('returns a 407 error statusCode', function (done) {
274 expect(Boom.proxyAuthRequired().output.statusCode).to.equal(407);
278 it('sets the message with the passed in message', function (done) {
280 expect(Boom.proxyAuthRequired('my message').message).to.equal('my message');
286 describe('clientTimeout()', function () {
288 it('returns a 408 error statusCode', function (done) {
290 expect(Boom.clientTimeout().output.statusCode).to.equal(408);
294 it('sets the message with the passed in message', function (done) {
296 expect(Boom.clientTimeout('my message').message).to.equal('my message');
302 describe('conflict()', function () {
304 it('returns a 409 error statusCode', function (done) {
306 expect(Boom.conflict().output.statusCode).to.equal(409);
310 it('sets the message with the passed in message', function (done) {
312 expect(Boom.conflict('my message').message).to.equal('my message');
318 describe('resourceGone()', function () {
320 it('returns a 410 error statusCode', function (done) {
322 expect(Boom.resourceGone().output.statusCode).to.equal(410);
326 it('sets the message with the passed in message', function (done) {
328 expect(Boom.resourceGone('my message').message).to.equal('my message');
334 describe('lengthRequired()', function () {
336 it('returns a 411 error statusCode', function (done) {
338 expect(Boom.lengthRequired().output.statusCode).to.equal(411);
342 it('sets the message with the passed in message', function (done) {
344 expect(Boom.lengthRequired('my message').message).to.equal('my message');
350 describe('preconditionFailed()', function () {
352 it('returns a 412 error statusCode', function (done) {
354 expect(Boom.preconditionFailed().output.statusCode).to.equal(412);
358 it('sets the message with the passed in message', function (done) {
360 expect(Boom.preconditionFailed('my message').message).to.equal('my message');
366 describe('entityTooLarge()', function () {
368 it('returns a 413 error statusCode', function (done) {
370 expect(Boom.entityTooLarge().output.statusCode).to.equal(413);
374 it('sets the message with the passed in message', function (done) {
376 expect(Boom.entityTooLarge('my message').message).to.equal('my message');
382 describe('uriTooLong()', function () {
384 it('returns a 414 error statusCode', function (done) {
386 expect(Boom.uriTooLong().output.statusCode).to.equal(414);
390 it('sets the message with the passed in message', function (done) {
392 expect(Boom.uriTooLong('my message').message).to.equal('my message');
398 describe('unsupportedMediaType()', function () {
400 it('returns a 415 error statusCode', function (done) {
402 expect(Boom.unsupportedMediaType().output.statusCode).to.equal(415);
406 it('sets the message with the passed in message', function (done) {
408 expect(Boom.unsupportedMediaType('my message').message).to.equal('my message');
414 describe('rangeNotSatisfiable()', function () {
416 it('returns a 416 error statusCode', function (done) {
418 expect(Boom.rangeNotSatisfiable().output.statusCode).to.equal(416);
422 it('sets the message with the passed in message', function (done) {
424 expect(Boom.rangeNotSatisfiable('my message').message).to.equal('my message');
430 describe('expectationFailed()', function () {
432 it('returns a 417 error statusCode', function (done) {
434 expect(Boom.expectationFailed().output.statusCode).to.equal(417);
438 it('sets the message with the passed in message', function (done) {
440 expect(Boom.expectationFailed('my message').message).to.equal('my message');
446 describe('badData()', function () {
448 it('returns a 422 error statusCode', function (done) {
450 expect(Boom.badData().output.statusCode).to.equal(422);
454 it('sets the message with the passed in message', function (done) {
456 expect(Boom.badData('my message').message).to.equal('my message');
462 describe('preconditionRequired()', function () {
464 it('returns a 428 error statusCode', function (done) {
466 expect(Boom.preconditionRequired().output.statusCode).to.equal(428);
470 it('sets the message with the passed in message', function (done) {
472 expect(Boom.preconditionRequired('my message').message).to.equal('my message');
478 describe('tooManyRequests()', function () {
480 it('returns a 429 error statusCode', function (done) {
482 expect(Boom.tooManyRequests().output.statusCode).to.equal(429);
486 it('sets the message with the passed-in message', function (done) {
488 expect(Boom.tooManyRequests('my message').message).to.equal('my message');
493 describe('serverTimeout()', function () {
495 it('returns a 503 error statusCode', function (done) {
497 expect(Boom.serverTimeout().output.statusCode).to.equal(503);
501 it('sets the message with the passed in message', function (done) {
503 expect(Boom.serverTimeout('my message').message).to.equal('my message');
508 describe('forbidden()', function () {
510 it('returns a 403 error statusCode', function (done) {
512 expect(Boom.forbidden().output.statusCode).to.equal(403);
516 it('sets the message with the passed in message', function (done) {
518 expect(Boom.forbidden('my message').message).to.equal('my message');
523 describe('notFound()', function () {
525 it('returns a 404 error statusCode', function (done) {
527 expect(Boom.notFound().output.statusCode).to.equal(404);
531 it('sets the message with the passed in message', function (done) {
533 expect(Boom.notFound('my message').message).to.equal('my message');
538 describe('internal()', function () {
540 it('returns a 500 error statusCode', function (done) {
542 expect(Boom.internal().output.statusCode).to.equal(500);
546 it('sets the message with the passed in message', function (done) {
548 var err = Boom.internal('my message');
549 expect(err.message).to.equal('my message');
550 expect(err.isServer).to.true();
551 expect(err.output.payload.message).to.equal('An internal server error occurred');
555 it('passes data on the callback if its passed in', function (done) {
557 expect(Boom.internal('my message', { my: 'data' }).data.my).to.equal('data');
561 it('returns an error with composite message', function (done) {
567 var boom = Boom.internal('Someting bad', err);
568 expect(boom.message).to.equal('Someting bad: Unexpected end of input');
569 expect(boom.isServer).to.be.true();
575 describe('notImplemented()', function () {
577 it('returns a 501 error statusCode', function (done) {
579 expect(Boom.notImplemented().output.statusCode).to.equal(501);
583 it('sets the message with the passed in message', function (done) {
585 expect(Boom.notImplemented('my message').message).to.equal('my message');
591 describe('badGateway()', function () {
593 it('returns a 502 error statusCode', function (done) {
595 expect(Boom.badGateway().output.statusCode).to.equal(502);
599 it('sets the message with the passed in message', function (done) {
601 expect(Boom.badGateway('my message').message).to.equal('my message');
606 describe('gatewayTimeout()', function () {
608 it('returns a 504 error statusCode', function (done) {
610 expect(Boom.gatewayTimeout().output.statusCode).to.equal(504);
614 it('sets the message with the passed in message', function (done) {
616 expect(Boom.gatewayTimeout('my message').message).to.equal('my message');
621 describe('badImplementation()', function () {
623 it('returns a 500 error statusCode', function (done) {
625 var err = Boom.badImplementation();
626 expect(err.output.statusCode).to.equal(500);
627 expect(err.isDeveloperError).to.equal(true);
628 expect(err.isServer).to.be.true();
633 describe('stack trace', function () {
635 it('should omit lib', function (done) {
637 ['badRequest', 'unauthorized', 'forbidden', 'notFound', 'methodNotAllowed',
638 'notAcceptable', 'proxyAuthRequired', 'clientTimeout', 'conflict',
639 'resourceGone', 'lengthRequired', 'preconditionFailed', 'entityTooLarge',
640 'uriTooLong', 'unsupportedMediaType', 'rangeNotSatisfiable', 'expectationFailed',
641 'badData', 'preconditionRequired', 'tooManyRequests',
644 'internal', 'notImplemented', 'badGateway', 'serverTimeout', 'gatewayTimeout',
646 ].forEach(function (name) {
648 var err = Boom[name]();
649 expect(err.stack).to.not.match(/\/lib\/index\.js/);