Initial commit
[yaffs-website] / node_modules / boom / test / index.js
1 // Load modules
2
3 var Code = require('code');
4 var Boom = require('../lib');
5 var Lab = require('lab');
6
7
8 // Declare internals
9
10 var internals = {};
11
12
13 // Test shortcuts
14
15 var lab = exports.lab = Lab.script();
16 var describe = lab.describe;
17 var it = lab.it;
18 var expect = Code.expect;
19
20
21 it('returns the same object when already boom', function (done) {
22
23     var error = Boom.badRequest();
24     var wrapped = Boom.wrap(error);
25     expect(error).to.equal(wrapped);
26     done();
27 });
28
29 it('returns an error with info when constructed using another error', function (done) {
30
31     var error = new Error('ka-boom');
32     error.xyz = 123;
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({
37         statusCode: 500,
38         payload: {
39             statusCode: 500,
40             error: 'Internal Server Error',
41             message: 'An internal server error occurred'
42         },
43         headers: {}
44     });
45     expect(err.data).to.equal(null);
46     done();
47 });
48
49 it('does not override data when constructed using another error', function (done) {
50
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);
55     done();
56 });
57
58 it('sets new message when none exists', function (done) {
59
60     var error = new Error();
61     var wrapped = Boom.wrap(error, 400, 'something bad');
62     expect(wrapped.message).to.equal('something bad');
63     done();
64 });
65
66 it('throws when statusCode is not a number', function (done) {
67
68     expect(function () {
69
70         Boom.create('x');
71     }).to.throw('First argument must be a number (400+): x');
72     done();
73 });
74
75 it('will cast a number-string to an integer', function (done) {
76
77     var codes = [
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) {
83         var code = codes[i];
84         var err = Boom.create(code.input);
85         expect(err.output.statusCode).to.equal(code.result);
86     }
87
88     done();
89 });
90
91 it('throws when statusCode is not finite', function (done) {
92
93     expect(function () {
94
95         Boom.create(1 / 0);
96     }).to.throw('First argument must be a number (400+): null');
97     done();
98 });
99
100 it('sets error code to unknown', function (done) {
101
102     var err = Boom.create(999);
103     expect(err.output.payload.error).to.equal('Unknown');
104     done();
105 });
106
107 describe('create()', function () {
108
109     it('does not sets null message', function (done) {
110
111         var error = Boom.unauthorized(null);
112         expect(error.output.payload.message).to.not.exist();
113         expect(error.isServer).to.be.false();
114         done();
115     });
116
117     it('sets message and data', function (done) {
118
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');
122         done();
123     });
124 });
125
126 describe('isBoom()', function () {
127
128     it('returns true for Boom object', function (done) {
129
130         expect(Boom.badRequest().isBoom).to.equal(true);
131         done();
132     });
133
134     it('returns false for Error object', function (done) {
135
136         expect((new Error()).isBoom).to.not.exist();
137         done();
138     });
139 });
140
141 describe('badRequest()', function () {
142
143     it('returns a 400 error statusCode', function (done) {
144
145         var error = Boom.badRequest();
146
147         expect(error.output.statusCode).to.equal(400);
148         expect(error.isServer).to.be.false();
149         done();
150     });
151
152     it('sets the message with the passed in message', function (done) {
153
154         expect(Boom.badRequest('my message').message).to.equal('my message');
155         done();
156     });
157
158     it('sets the message to HTTP status if none provided', function (done) {
159
160         expect(Boom.badRequest().message).to.equal('Bad Request');
161         done();
162     });
163 });
164
165 describe('unauthorized()', function () {
166
167     it('returns a 401 error statusCode', function (done) {
168
169         var err = Boom.unauthorized();
170         expect(err.output.statusCode).to.equal(401);
171         expect(err.output.headers).to.deep.equal({});
172         done();
173     });
174
175     it('sets the message with the passed in message', function (done) {
176
177         expect(Boom.unauthorized('my message').message).to.equal('my message');
178         done();
179     });
180
181     it('returns a WWW-Authenticate header when passed a scheme', function (done) {
182
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"');
186         done();
187     });
188
189     it('returns a WWW-Authenticate header set to the schema array value', function (done) {
190
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');
194         done();
195     });
196
197     it('returns a WWW-Authenticate header when passed a scheme and attributes', function (done) {
198
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' });
203         done();
204     });
205
206     it('returns a WWW-Authenticate header when passed attributes, missing error', function (done) {
207
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);
212         done();
213     });
214
215     it('sets the isMissing flag when error message is empty', function (done) {
216
217         var err = Boom.unauthorized('', 'Basic');
218         expect(err.isMissing).to.equal(true);
219         done();
220     });
221
222     it('does not set the isMissing flag when error message is not empty', function (done) {
223
224         var err = Boom.unauthorized('message', 'Basic');
225         expect(err.isMissing).to.equal(undefined);
226         done();
227     });
228
229     it('sets a WWW-Authenticate when passed as an array', function (done) {
230
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"');
233         done();
234     });
235 });
236
237
238 describe('methodNotAllowed()', function () {
239
240     it('returns a 405 error statusCode', function (done) {
241
242         expect(Boom.methodNotAllowed().output.statusCode).to.equal(405);
243         done();
244     });
245
246     it('sets the message with the passed in message', function (done) {
247
248         expect(Boom.methodNotAllowed('my message').message).to.equal('my message');
249         done();
250     });
251 });
252
253
254 describe('notAcceptable()', function () {
255
256     it('returns a 406 error statusCode', function (done) {
257
258         expect(Boom.notAcceptable().output.statusCode).to.equal(406);
259         done();
260     });
261
262     it('sets the message with the passed in message', function (done) {
263
264         expect(Boom.notAcceptable('my message').message).to.equal('my message');
265         done();
266     });
267 });
268
269
270 describe('proxyAuthRequired()', function () {
271
272     it('returns a 407 error statusCode', function (done) {
273
274         expect(Boom.proxyAuthRequired().output.statusCode).to.equal(407);
275         done();
276     });
277
278     it('sets the message with the passed in message', function (done) {
279
280         expect(Boom.proxyAuthRequired('my message').message).to.equal('my message');
281         done();
282     });
283 });
284
285
286 describe('clientTimeout()', function () {
287
288     it('returns a 408 error statusCode', function (done) {
289
290         expect(Boom.clientTimeout().output.statusCode).to.equal(408);
291         done();
292     });
293
294     it('sets the message with the passed in message', function (done) {
295
296         expect(Boom.clientTimeout('my message').message).to.equal('my message');
297         done();
298     });
299 });
300
301
302 describe('conflict()', function () {
303
304     it('returns a 409 error statusCode', function (done) {
305
306         expect(Boom.conflict().output.statusCode).to.equal(409);
307         done();
308     });
309
310     it('sets the message with the passed in message', function (done) {
311
312         expect(Boom.conflict('my message').message).to.equal('my message');
313         done();
314     });
315 });
316
317
318 describe('resourceGone()', function () {
319
320     it('returns a 410 error statusCode', function (done) {
321
322         expect(Boom.resourceGone().output.statusCode).to.equal(410);
323         done();
324     });
325
326     it('sets the message with the passed in message', function (done) {
327
328         expect(Boom.resourceGone('my message').message).to.equal('my message');
329         done();
330     });
331 });
332
333
334 describe('lengthRequired()', function () {
335
336     it('returns a 411 error statusCode', function (done) {
337
338         expect(Boom.lengthRequired().output.statusCode).to.equal(411);
339         done();
340     });
341
342     it('sets the message with the passed in message', function (done) {
343
344         expect(Boom.lengthRequired('my message').message).to.equal('my message');
345         done();
346     });
347 });
348
349
350 describe('preconditionFailed()', function () {
351
352     it('returns a 412 error statusCode', function (done) {
353
354         expect(Boom.preconditionFailed().output.statusCode).to.equal(412);
355         done();
356     });
357
358     it('sets the message with the passed in message', function (done) {
359
360         expect(Boom.preconditionFailed('my message').message).to.equal('my message');
361         done();
362     });
363 });
364
365
366 describe('entityTooLarge()', function () {
367
368     it('returns a 413 error statusCode', function (done) {
369
370         expect(Boom.entityTooLarge().output.statusCode).to.equal(413);
371         done();
372     });
373
374     it('sets the message with the passed in message', function (done) {
375
376         expect(Boom.entityTooLarge('my message').message).to.equal('my message');
377         done();
378     });
379 });
380
381
382 describe('uriTooLong()', function () {
383
384     it('returns a 414 error statusCode', function (done) {
385
386         expect(Boom.uriTooLong().output.statusCode).to.equal(414);
387         done();
388     });
389
390     it('sets the message with the passed in message', function (done) {
391
392         expect(Boom.uriTooLong('my message').message).to.equal('my message');
393         done();
394     });
395 });
396
397
398 describe('unsupportedMediaType()', function () {
399
400     it('returns a 415 error statusCode', function (done) {
401
402         expect(Boom.unsupportedMediaType().output.statusCode).to.equal(415);
403         done();
404     });
405
406     it('sets the message with the passed in message', function (done) {
407
408         expect(Boom.unsupportedMediaType('my message').message).to.equal('my message');
409         done();
410     });
411 });
412
413
414 describe('rangeNotSatisfiable()', function () {
415
416     it('returns a 416 error statusCode', function (done) {
417
418         expect(Boom.rangeNotSatisfiable().output.statusCode).to.equal(416);
419         done();
420     });
421
422     it('sets the message with the passed in message', function (done) {
423
424         expect(Boom.rangeNotSatisfiable('my message').message).to.equal('my message');
425         done();
426     });
427 });
428
429
430 describe('expectationFailed()', function () {
431
432     it('returns a 417 error statusCode', function (done) {
433
434         expect(Boom.expectationFailed().output.statusCode).to.equal(417);
435         done();
436     });
437
438     it('sets the message with the passed in message', function (done) {
439
440         expect(Boom.expectationFailed('my message').message).to.equal('my message');
441         done();
442     });
443 });
444
445
446 describe('badData()', function () {
447
448     it('returns a 422 error statusCode', function (done) {
449
450         expect(Boom.badData().output.statusCode).to.equal(422);
451         done();
452     });
453
454     it('sets the message with the passed in message', function (done) {
455
456         expect(Boom.badData('my message').message).to.equal('my message');
457         done();
458     });
459 });
460
461
462 describe('preconditionRequired()', function () {
463
464     it('returns a 428 error statusCode', function (done) {
465
466         expect(Boom.preconditionRequired().output.statusCode).to.equal(428);
467         done();
468     });
469
470     it('sets the message with the passed in message', function (done) {
471
472         expect(Boom.preconditionRequired('my message').message).to.equal('my message');
473         done();
474     });
475 });
476
477
478 describe('tooManyRequests()', function () {
479
480     it('returns a 429 error statusCode', function (done) {
481
482         expect(Boom.tooManyRequests().output.statusCode).to.equal(429);
483         done();
484     });
485
486     it('sets the message with the passed-in message', function (done) {
487
488         expect(Boom.tooManyRequests('my message').message).to.equal('my message');
489         done();
490     });
491 });
492
493 describe('serverTimeout()', function () {
494
495     it('returns a 503 error statusCode', function (done) {
496
497         expect(Boom.serverTimeout().output.statusCode).to.equal(503);
498         done();
499     });
500
501     it('sets the message with the passed in message', function (done) {
502
503         expect(Boom.serverTimeout('my message').message).to.equal('my message');
504         done();
505     });
506 });
507
508 describe('forbidden()', function () {
509
510     it('returns a 403 error statusCode', function (done) {
511
512         expect(Boom.forbidden().output.statusCode).to.equal(403);
513         done();
514     });
515
516     it('sets the message with the passed in message', function (done) {
517
518         expect(Boom.forbidden('my message').message).to.equal('my message');
519         done();
520     });
521 });
522
523 describe('notFound()', function () {
524
525     it('returns a 404 error statusCode', function (done) {
526
527         expect(Boom.notFound().output.statusCode).to.equal(404);
528         done();
529     });
530
531     it('sets the message with the passed in message', function (done) {
532
533         expect(Boom.notFound('my message').message).to.equal('my message');
534         done();
535     });
536 });
537
538 describe('internal()', function () {
539
540     it('returns a 500 error statusCode', function (done) {
541
542         expect(Boom.internal().output.statusCode).to.equal(500);
543         done();
544     });
545
546     it('sets the message with the passed in message', function (done) {
547
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');
552         done();
553     });
554
555     it('passes data on the callback if its passed in', function (done) {
556
557         expect(Boom.internal('my message', { my: 'data' }).data.my).to.equal('data');
558         done();
559     });
560
561     it('returns an error with composite message', function (done) {
562
563         try {
564             JSON.parse('{');
565         }
566         catch (err) {
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();
570             done();
571         }
572     });
573 });
574
575 describe('notImplemented()', function () {
576
577     it('returns a 501 error statusCode', function (done) {
578
579         expect(Boom.notImplemented().output.statusCode).to.equal(501);
580         done();
581     });
582
583     it('sets the message with the passed in message', function (done) {
584
585         expect(Boom.notImplemented('my message').message).to.equal('my message');
586         done();
587     });
588 });
589
590
591 describe('badGateway()', function () {
592
593     it('returns a 502 error statusCode', function (done) {
594
595         expect(Boom.badGateway().output.statusCode).to.equal(502);
596         done();
597     });
598
599     it('sets the message with the passed in message', function (done) {
600
601         expect(Boom.badGateway('my message').message).to.equal('my message');
602         done();
603     });
604 });
605
606 describe('gatewayTimeout()', function () {
607
608     it('returns a 504 error statusCode', function (done) {
609
610         expect(Boom.gatewayTimeout().output.statusCode).to.equal(504);
611         done();
612     });
613
614     it('sets the message with the passed in message', function (done) {
615
616         expect(Boom.gatewayTimeout('my message').message).to.equal('my message');
617         done();
618     });
619 });
620
621 describe('badImplementation()', function () {
622
623     it('returns a 500 error statusCode', function (done) {
624
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();
629         done();
630     });
631 });
632
633 describe('stack trace', function () {
634
635     it('should omit lib', function (done) {
636
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',
642
643             // 500s
644             'internal', 'notImplemented', 'badGateway', 'serverTimeout', 'gatewayTimeout',
645             'badImplementation'
646         ].forEach(function (name) {
647
648             var err = Boom[name]();
649             expect(err.stack).to.not.match(/\/lib\/index\.js/);
650         });
651
652         done();
653     });
654 });