UNPKG

63 kBJavaScriptView Raw
1'use strict'
2
3const t = require('tap')
4const test = t.test
5const semver = require('semver')
6const sget = require('simple-get').concat
7const stream = require('stream')
8const Fastify = require('..')
9const fp = require('fastify-plugin')
10const fs = require('fs')
11const split = require('split2')
12const symbols = require('../lib/symbols.js')
13
14const payload = { hello: 'world' }
15
16test('hooks', t => {
17 t.plan(37)
18 const fastify = Fastify()
19
20 try {
21 fastify.addHook('preHandler', function (request, reply, next) {
22 t.is(request.test, 'the request is coming')
23 t.is(reply.test, 'the reply has come')
24 if (request.raw.method === 'HEAD') {
25 next(new Error('some error'))
26 } else {
27 next()
28 }
29 })
30 t.pass()
31 } catch (e) {
32 t.fail()
33 }
34
35 try {
36 fastify.addHook('preParsing', function (request, reply, next) {
37 request.preParsing = true
38 t.is(request.test, 'the request is coming')
39 t.is(reply.test, 'the reply has come')
40 next()
41 })
42 t.pass()
43 } catch (e) {
44 t.fail()
45 }
46
47 try {
48 fastify.addHook('preValidation', function (request, reply, next) {
49 t.is(request.preParsing, true)
50 t.is(request.test, 'the request is coming')
51 t.is(reply.test, 'the reply has come')
52 next()
53 })
54 t.pass()
55 } catch (e) {
56 t.fail()
57 }
58
59 try {
60 fastify.addHook('preSerialization', function (request, reply, payload, next) {
61 t.ok('preSerialization called')
62 next()
63 })
64 t.pass()
65 } catch (e) {
66 t.fail()
67 }
68
69 try {
70 fastify.addHook('onRequest', function (request, reply, next) {
71 request.test = 'the request is coming'
72 reply.test = 'the reply has come'
73 if (request.raw.method === 'DELETE') {
74 next(new Error('some error'))
75 } else {
76 next()
77 }
78 })
79 t.pass()
80 } catch (e) {
81 t.fail()
82 }
83
84 fastify.addHook('onResponse', function (request, reply, next) {
85 t.ok('onResponse called')
86 next()
87 })
88
89 fastify.addHook('onSend', function (req, reply, thePayload, next) {
90 t.ok('onSend called')
91 next()
92 })
93
94 fastify.route({
95 method: 'GET',
96 url: '/',
97 handler: function (req, reply) {
98 t.is(req.test, 'the request is coming')
99 t.is(reply.test, 'the reply has come')
100 reply.code(200).send(payload)
101 },
102 response: {
103 200: {
104 type: 'object'
105 }
106 }
107 })
108
109 fastify.head('/', function (req, reply) {
110 reply.code(200).send(payload)
111 })
112
113 fastify.delete('/', function (req, reply) {
114 reply.code(200).send(payload)
115 })
116
117 fastify.listen(0, err => {
118 t.error(err)
119 fastify.server.unref()
120
121 sget({
122 method: 'GET',
123 url: 'http://localhost:' + fastify.server.address().port
124 }, (err, response, body) => {
125 t.error(err)
126 t.strictEqual(response.statusCode, 200)
127 t.strictEqual(response.headers['content-length'], '' + body.length)
128 t.deepEqual(JSON.parse(body), { hello: 'world' })
129 })
130
131 sget({
132 method: 'HEAD',
133 url: 'http://localhost:' + fastify.server.address().port
134 }, (err, response, body) => {
135 t.error(err)
136 t.strictEqual(response.statusCode, 500)
137 })
138
139 sget({
140 method: 'DELETE',
141 url: 'http://localhost:' + fastify.server.address().port
142 }, (err, response, body) => {
143 t.error(err)
144 t.strictEqual(response.statusCode, 500)
145 })
146 })
147})
148
149test('onRequest hook should support encapsulation / 1', t => {
150 t.plan(5)
151 const fastify = Fastify()
152
153 fastify.register((instance, opts, next) => {
154 instance.addHook('onRequest', (req, reply, next) => {
155 t.strictEqual(req.raw.url, '/plugin')
156 next()
157 })
158
159 instance.get('/plugin', (request, reply) => {
160 reply.send()
161 })
162
163 next()
164 })
165
166 fastify.get('/root', (request, reply) => {
167 reply.send()
168 })
169
170 fastify.inject('/root', (err, res) => {
171 t.error(err)
172 t.strictEqual(res.statusCode, 200)
173 })
174
175 fastify.inject('/plugin', (err, res) => {
176 t.error(err)
177 t.strictEqual(res.statusCode, 200)
178 })
179})
180
181test('onRequest hook should support encapsulation / 2', t => {
182 t.plan(3)
183 const fastify = Fastify()
184 var pluginInstance
185
186 fastify.addHook('onRequest', () => {})
187
188 fastify.register((instance, opts, next) => {
189 instance.addHook('onRequest', () => {})
190 pluginInstance = instance
191 next()
192 })
193
194 fastify.ready(err => {
195 t.error(err)
196 t.is(fastify[symbols.kHooks].onRequest.length, 1)
197 t.is(pluginInstance[symbols.kHooks].onRequest.length, 2)
198 })
199})
200
201test('onRequest hook should support encapsulation / 3', t => {
202 t.plan(20)
203 const fastify = Fastify()
204 fastify.decorate('hello', 'world')
205
206 fastify.addHook('onRequest', function (req, reply, next) {
207 t.ok(this.hello)
208 t.ok(this.hello2)
209 req.first = true
210 next()
211 })
212
213 fastify.decorate('hello2', 'world')
214
215 fastify.get('/first', (req, reply) => {
216 t.ok(req.first)
217 t.notOk(req.second)
218 reply.send({ hello: 'world' })
219 })
220
221 fastify.register((instance, opts, next) => {
222 instance.decorate('hello3', 'world')
223 instance.addHook('onRequest', function (req, reply, next) {
224 t.ok(this.hello)
225 t.ok(this.hello2)
226 t.ok(this.hello3)
227 req.second = true
228 next()
229 })
230
231 instance.get('/second', (req, reply) => {
232 t.ok(req.first)
233 t.ok(req.second)
234 reply.send({ hello: 'world' })
235 })
236
237 next()
238 })
239
240 fastify.listen(0, err => {
241 t.error(err)
242 fastify.server.unref()
243
244 sget({
245 method: 'GET',
246 url: 'http://localhost:' + fastify.server.address().port + '/first'
247 }, (err, response, body) => {
248 t.error(err)
249 t.strictEqual(response.statusCode, 200)
250 t.strictEqual(response.headers['content-length'], '' + body.length)
251 t.deepEqual(JSON.parse(body), { hello: 'world' })
252 })
253
254 sget({
255 method: 'GET',
256 url: 'http://localhost:' + fastify.server.address().port + '/second'
257 }, (err, response, body) => {
258 t.error(err)
259 t.strictEqual(response.statusCode, 200)
260 t.strictEqual(response.headers['content-length'], '' + body.length)
261 t.deepEqual(JSON.parse(body), { hello: 'world' })
262 })
263 })
264})
265
266test('preHandler hook should support encapsulation / 5', t => {
267 t.plan(17)
268 const fastify = Fastify()
269 fastify.decorate('hello', 'world')
270
271 fastify.addHook('preHandler', function (req, res, next) {
272 t.ok(this.hello)
273 req.first = true
274 next()
275 })
276
277 fastify.get('/first', (req, reply) => {
278 t.ok(req.first)
279 t.notOk(req.second)
280 reply.send({ hello: 'world' })
281 })
282
283 fastify.register((instance, opts, next) => {
284 instance.decorate('hello2', 'world')
285 instance.addHook('preHandler', function (req, res, next) {
286 t.ok(this.hello)
287 t.ok(this.hello2)
288 req.second = true
289 next()
290 })
291
292 instance.get('/second', (req, reply) => {
293 t.ok(req.first)
294 t.ok(req.second)
295 reply.send({ hello: 'world' })
296 })
297
298 next()
299 })
300
301 fastify.listen(0, err => {
302 t.error(err)
303 fastify.server.unref()
304
305 sget({
306 method: 'GET',
307 url: 'http://localhost:' + fastify.server.address().port + '/first'
308 }, (err, response, body) => {
309 t.error(err)
310 t.strictEqual(response.statusCode, 200)
311 t.strictEqual(response.headers['content-length'], '' + body.length)
312 t.deepEqual(JSON.parse(body), { hello: 'world' })
313 })
314
315 sget({
316 method: 'GET',
317 url: 'http://localhost:' + fastify.server.address().port + '/second'
318 }, (err, response, body) => {
319 t.error(err)
320 t.strictEqual(response.statusCode, 200)
321 t.strictEqual(response.headers['content-length'], '' + body.length)
322 t.deepEqual(JSON.parse(body), { hello: 'world' })
323 })
324 })
325})
326
327test('onRoute hook should be called / 1', t => {
328 t.plan(2)
329 const fastify = Fastify()
330
331 fastify.register((instance, opts, next) => {
332 instance.addHook('onRoute', () => {
333 t.pass()
334 })
335 instance.get('/', opts, function (req, reply) {
336 reply.send()
337 })
338 next()
339 })
340
341 fastify.ready(err => {
342 t.error(err)
343 })
344})
345
346test('onRoute hook should be called / 2', t => {
347 t.plan(5)
348 let firstHandler = 0
349 let secondHandler = 0
350 const fastify = Fastify()
351 fastify.addHook('onRoute', (route) => {
352 t.pass()
353 firstHandler++
354 })
355
356 fastify.register((instance, opts, next) => {
357 instance.addHook('onRoute', (route) => {
358 t.pass()
359 secondHandler++
360 })
361 instance.get('/', opts, function (req, reply) {
362 reply.send()
363 })
364 next()
365 })
366 .after(() => {
367 t.strictEqual(firstHandler, 1)
368 t.strictEqual(secondHandler, 1)
369 })
370
371 fastify.ready(err => {
372 t.error(err)
373 })
374})
375
376test('onRoute hook should be called / 3', t => {
377 t.plan(6)
378 const fastify = Fastify()
379
380 function handler (req, reply) {
381 reply.send()
382 }
383
384 fastify.addHook('onRoute', (route) => {
385 t.pass()
386 })
387
388 fastify.register((instance, opts, next) => {
389 instance.addHook('onRoute', (route) => {
390 t.pass()
391 })
392 instance.get('/a', handler)
393 next()
394 })
395 .after((err, done) => {
396 t.error(err)
397 setTimeout(() => {
398 fastify.get('/b', handler)
399 done()
400 }, 10)
401 })
402
403 fastify.ready(err => {
404 t.error(err)
405 })
406})
407
408test('onRoute should keep the context', t => {
409 t.plan(4)
410 const fastify = Fastify()
411 fastify.register((instance, opts, next) => {
412 instance.decorate('test', true)
413 instance.addHook('onRoute', onRoute)
414 t.ok(instance.prototype === fastify.prototype)
415
416 function onRoute (route) {
417 t.ok(this.test)
418 t.strictEqual(this, instance)
419 }
420
421 instance.get('/', opts, function (req, reply) {
422 reply.send()
423 })
424
425 next()
426 })
427
428 fastify.close((err) => {
429 t.error(err)
430 })
431})
432
433test('onRoute hook should pass correct route', t => {
434 t.plan(7)
435 const fastify = Fastify()
436 fastify.addHook('onRoute', (route) => {
437 t.strictEqual(route.method, 'GET')
438 t.strictEqual(route.url, '/')
439 t.strictEqual(route.path, '/')
440 })
441
442 fastify.register((instance, opts, next) => {
443 instance.addHook('onRoute', (route) => {
444 t.strictEqual(route.method, 'GET')
445 t.strictEqual(route.url, '/')
446 t.strictEqual(route.path, '/')
447 })
448 instance.get('/', opts, function (req, reply) {
449 reply.send()
450 })
451 next()
452 })
453
454 fastify.ready(err => {
455 t.error(err)
456 })
457})
458
459test('onRoute hook should pass correct route with custom prefix', t => {
460 t.plan(9)
461 const fastify = Fastify()
462 fastify.addHook('onRoute', function (route) {
463 t.strictEqual(route.method, 'GET')
464 t.strictEqual(route.url, '/v1/foo')
465 t.strictEqual(route.path, '/v1/foo')
466 t.strictEqual(route.prefix, '/v1')
467 })
468
469 fastify.register((instance, opts, next) => {
470 instance.addHook('onRoute', function (route) {
471 t.strictEqual(route.method, 'GET')
472 t.strictEqual(route.url, '/v1/foo')
473 t.strictEqual(route.path, '/v1/foo')
474 t.strictEqual(route.prefix, '/v1')
475 })
476 instance.get('/foo', opts, function (req, reply) {
477 reply.send()
478 })
479 next()
480 }, { prefix: '/v1' })
481
482 fastify.ready(err => {
483 t.error(err)
484 })
485})
486
487test('onRoute hook should pass correct route with custom options', t => {
488 t.plan(5)
489 const fastify = Fastify()
490 fastify.register((instance, opts, next) => {
491 instance.addHook('onRoute', function (route) {
492 t.strictEqual(route.method, 'GET')
493 t.strictEqual(route.url, '/foo')
494 t.strictEqual(route.logLevel, 'info')
495 t.strictEqual(route.bodyLimit, 100)
496 })
497 instance.get('/foo', { logLevel: 'info', bodyLimit: 100 }, function (req, reply) {
498 reply.send()
499 })
500 next()
501 })
502
503 fastify.ready(err => {
504 t.error(err)
505 })
506})
507
508test('onRoute hook should receive any route option', t => {
509 t.plan(4)
510 const fastify = Fastify()
511 fastify.register((instance, opts, next) => {
512 instance.addHook('onRoute', function (route) {
513 t.strictEqual(route.method, 'GET')
514 t.strictEqual(route.url, '/foo')
515 t.strictEqual(route.auth, 'basic')
516 })
517 instance.get('/foo', { auth: 'basic' }, function (req, reply) {
518 reply.send()
519 })
520 next()
521 })
522
523 fastify.ready(err => {
524 t.error(err)
525 })
526})
527
528test('onRoute hook should preserve system route configuration', t => {
529 t.plan(4)
530 const fastify = Fastify()
531 fastify.register((instance, opts, next) => {
532 instance.addHook('onRoute', function (route) {
533 t.strictEqual(route.method, 'GET')
534 t.strictEqual(route.url, '/foo')
535 t.strictEqual(route.handler.length, 2)
536 })
537 instance.get('/foo', { url: '/bar', method: 'POST' }, function (req, reply) {
538 reply.send()
539 })
540 next()
541 })
542
543 fastify.ready(err => {
544 t.error(err)
545 })
546})
547
548test('onRoute hook should preserve handler function in options of shorthand route system configuration', t => {
549 t.plan(2)
550
551 const handler = (req, reply) => {}
552
553 const fastify = Fastify()
554 fastify.register((instance, opts, next) => {
555 instance.addHook('onRoute', function (route) {
556 t.strictEqual(route.handler, handler)
557 })
558 instance.get('/foo', { handler })
559 next()
560 })
561
562 fastify.ready(err => {
563 t.error(err)
564 })
565})
566
567test('onRoute hook that throws should be caught ', t => {
568 t.plan(1)
569 const fastify = Fastify()
570
571 fastify.register((instance, opts, next) => {
572 instance.addHook('onRoute', () => {
573 throw new Error('snap')
574 })
575 instance.get('/', opts, function (req, reply) {
576 reply.send()
577 })
578 next()
579 })
580
581 fastify.ready(err => {
582 t.ok(err)
583 })
584})
585
586test('onResponse hook should log request error', t => {
587 t.plan(4)
588
589 let fastify = null
590 const logStream = split(JSON.parse)
591 try {
592 fastify = Fastify({
593 logger: {
594 stream: logStream,
595 level: 'error'
596 }
597 })
598 } catch (e) {
599 t.fail()
600 }
601
602 logStream.once('data', line => {
603 t.equal(line.msg, 'request errored')
604 t.equal(line.level, 50)
605 })
606
607 fastify.addHook('onResponse', (request, reply, next) => {
608 next(new Error('kaboom'))
609 })
610
611 fastify.get('/root', (request, reply) => {
612 reply.send()
613 })
614
615 fastify.inject('/root', (err, res) => {
616 t.error(err)
617 t.strictEqual(res.statusCode, 200)
618 })
619})
620
621test('onResponse hook should support encapsulation / 1', t => {
622 t.plan(5)
623 const fastify = Fastify()
624
625 fastify.register((instance, opts, next) => {
626 instance.addHook('onResponse', (request, reply, next) => {
627 t.strictEqual(reply.plugin, true)
628 next()
629 })
630
631 instance.get('/plugin', (request, reply) => {
632 reply.plugin = true
633 reply.send()
634 })
635
636 next()
637 })
638
639 fastify.get('/root', (request, reply) => {
640 reply.send()
641 })
642
643 fastify.inject('/root', (err, res) => {
644 t.error(err)
645 t.strictEqual(res.statusCode, 200)
646 })
647
648 fastify.inject('/plugin', (err, res) => {
649 t.error(err)
650 t.strictEqual(res.statusCode, 200)
651 })
652})
653
654test('onResponse hook should support encapsulation / 2', t => {
655 t.plan(3)
656 const fastify = Fastify()
657 var pluginInstance
658
659 fastify.addHook('onResponse', () => {})
660
661 fastify.register((instance, opts, next) => {
662 instance.addHook('onResponse', () => {})
663 pluginInstance = instance
664 next()
665 })
666
667 fastify.ready(err => {
668 t.error(err)
669 t.is(fastify[symbols.kHooks].onResponse.length, 1)
670 t.is(pluginInstance[symbols.kHooks].onResponse.length, 2)
671 })
672})
673
674test('onResponse hook should support encapsulation / 3', t => {
675 t.plan(16)
676 const fastify = Fastify()
677 fastify.decorate('hello', 'world')
678
679 fastify.addHook('onResponse', function (request, reply, next) {
680 t.ok(this.hello)
681 t.ok('onResponse called')
682 next()
683 })
684
685 fastify.get('/first', (req, reply) => {
686 reply.send({ hello: 'world' })
687 })
688
689 fastify.register((instance, opts, next) => {
690 instance.decorate('hello2', 'world')
691 instance.addHook('onResponse', function (request, reply, next) {
692 t.ok(this.hello)
693 t.ok(this.hello2)
694 t.ok('onResponse called')
695 next()
696 })
697
698 instance.get('/second', (req, reply) => {
699 reply.send({ hello: 'world' })
700 })
701
702 next()
703 })
704
705 fastify.listen(0, err => {
706 t.error(err)
707 fastify.server.unref()
708
709 sget({
710 method: 'GET',
711 url: 'http://localhost:' + fastify.server.address().port + '/first'
712 }, (err, response, body) => {
713 t.error(err)
714 t.strictEqual(response.statusCode, 200)
715 t.strictEqual(response.headers['content-length'], '' + body.length)
716 t.deepEqual(JSON.parse(body), { hello: 'world' })
717 })
718
719 sget({
720 method: 'GET',
721 url: 'http://localhost:' + fastify.server.address().port + '/second'
722 }, (err, response, body) => {
723 t.error(err)
724 t.strictEqual(response.statusCode, 200)
725 t.strictEqual(response.headers['content-length'], '' + body.length)
726 t.deepEqual(JSON.parse(body), { hello: 'world' })
727 })
728 })
729})
730
731test('onSend hook should support encapsulation / 1', t => {
732 t.plan(3)
733 const fastify = Fastify()
734 var pluginInstance
735
736 fastify.addHook('onSend', () => {})
737
738 fastify.register((instance, opts, next) => {
739 instance.addHook('onSend', () => {})
740 pluginInstance = instance
741 next()
742 })
743
744 fastify.ready(err => {
745 t.error(err)
746 t.is(fastify[symbols.kHooks].onSend.length, 1)
747 t.is(pluginInstance[symbols.kHooks].onSend.length, 2)
748 })
749})
750
751test('onSend hook should support encapsulation / 2', t => {
752 t.plan(16)
753 const fastify = Fastify()
754 fastify.decorate('hello', 'world')
755
756 fastify.addHook('onSend', function (request, reply, thePayload, next) {
757 t.ok(this.hello)
758 t.ok('onSend called')
759 next()
760 })
761
762 fastify.get('/first', (req, reply) => {
763 reply.send({ hello: 'world' })
764 })
765
766 fastify.register((instance, opts, next) => {
767 instance.decorate('hello2', 'world')
768 instance.addHook('onSend', function (request, reply, thePayload, next) {
769 t.ok(this.hello)
770 t.ok(this.hello2)
771 t.ok('onSend called')
772 next()
773 })
774
775 instance.get('/second', (req, reply) => {
776 reply.send({ hello: 'world' })
777 })
778
779 next()
780 })
781
782 fastify.listen(0, err => {
783 t.error(err)
784 fastify.server.unref()
785
786 sget({
787 method: 'GET',
788 url: 'http://localhost:' + fastify.server.address().port + '/first'
789 }, (err, response, body) => {
790 t.error(err)
791 t.strictEqual(response.statusCode, 200)
792 t.strictEqual(response.headers['content-length'], '' + body.length)
793 t.deepEqual(JSON.parse(body), { hello: 'world' })
794 })
795
796 sget({
797 method: 'GET',
798 url: 'http://localhost:' + fastify.server.address().port + '/second'
799 }, (err, response, body) => {
800 t.error(err)
801 t.strictEqual(response.statusCode, 200)
802 t.strictEqual(response.headers['content-length'], '' + body.length)
803 t.deepEqual(JSON.parse(body), { hello: 'world' })
804 })
805 })
806})
807
808test('onSend hook is called after payload is serialized and headers are set', t => {
809 t.plan(30)
810 const fastify = Fastify()
811
812 fastify.register((instance, opts, next) => {
813 const thePayload = { hello: 'world' }
814
815 instance.addHook('onSend', function (request, reply, payload, next) {
816 t.deepEqual(JSON.parse(payload), thePayload)
817 t.strictEqual(reply[symbols.kReplyHeaders]['content-type'], 'application/json; charset=utf-8')
818 next()
819 })
820
821 instance.get('/json', (request, reply) => {
822 reply.send(thePayload)
823 })
824
825 next()
826 })
827
828 fastify.register((instance, opts, next) => {
829 instance.addHook('onSend', function (request, reply, payload, next) {
830 t.strictEqual(payload, 'some text')
831 t.strictEqual(reply[symbols.kReplyHeaders]['content-type'], 'text/plain; charset=utf-8')
832 next()
833 })
834
835 instance.get('/text', (request, reply) => {
836 reply.send('some text')
837 })
838
839 next()
840 })
841
842 fastify.register((instance, opts, next) => {
843 const thePayload = Buffer.from('buffer payload')
844
845 instance.addHook('onSend', function (request, reply, payload, next) {
846 t.strictEqual(payload, thePayload)
847 t.strictEqual(reply[symbols.kReplyHeaders]['content-type'], 'application/octet-stream')
848 next()
849 })
850
851 instance.get('/buffer', (request, reply) => {
852 reply.send(thePayload)
853 })
854
855 next()
856 })
857
858 fastify.register((instance, opts, next) => {
859 var chunk = 'stream payload'
860 const thePayload = new stream.Readable({
861 read () {
862 this.push(chunk)
863 chunk = null
864 }
865 })
866
867 instance.addHook('onSend', function (request, reply, payload, next) {
868 t.strictEqual(payload, thePayload)
869 t.strictEqual(reply[symbols.kReplyHeaders]['content-type'], 'application/octet-stream')
870 next()
871 })
872
873 instance.get('/stream', (request, reply) => {
874 reply.send(thePayload)
875 })
876
877 next()
878 })
879
880 fastify.register((instance, opts, next) => {
881 const serializedPayload = 'serialized'
882
883 instance.addHook('onSend', function (request, reply, payload, next) {
884 t.strictEqual(payload, serializedPayload)
885 t.strictEqual(reply[symbols.kReplyHeaders]['content-type'], 'text/custom')
886 next()
887 })
888
889 instance.get('/custom-serializer', (request, reply) => {
890 reply
891 .serializer(() => serializedPayload)
892 .type('text/custom')
893 .send('needs to be serialized')
894 })
895
896 next()
897 })
898
899 fastify.inject({
900 method: 'GET',
901 url: '/json'
902 }, (err, res) => {
903 t.error(err)
904 t.strictEqual(res.statusCode, 200)
905 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
906 t.strictEqual(res.headers['content-length'], '17')
907 })
908
909 fastify.inject({
910 method: 'GET',
911 url: '/text'
912 }, (err, res) => {
913 t.error(err)
914 t.strictEqual(res.statusCode, 200)
915 t.deepEqual(res.payload, 'some text')
916 t.strictEqual(res.headers['content-length'], '9')
917 })
918
919 fastify.inject({
920 method: 'GET',
921 url: '/buffer'
922 }, (err, res) => {
923 t.error(err)
924 t.strictEqual(res.statusCode, 200)
925 t.deepEqual(res.payload, 'buffer payload')
926 t.strictEqual(res.headers['content-length'], '14')
927 })
928
929 fastify.inject({
930 method: 'GET',
931 url: '/stream'
932 }, (err, res) => {
933 t.error(err)
934 t.strictEqual(res.statusCode, 200)
935 t.deepEqual(res.payload, 'stream payload')
936 t.strictEqual(res.headers['transfer-encoding'], 'chunked')
937 })
938
939 fastify.inject({
940 method: 'GET',
941 url: '/custom-serializer'
942 }, (err, res) => {
943 t.error(err)
944 t.strictEqual(res.statusCode, 200)
945 t.deepEqual(res.payload, 'serialized')
946 t.strictEqual(res.headers['content-type'], 'text/custom')
947 })
948})
949
950test('modify payload', t => {
951 t.plan(10)
952 const fastify = Fastify()
953 const payload = { hello: 'world' }
954 const modifiedPayload = { hello: 'modified' }
955 const anotherPayload = '"winter is coming"'
956
957 fastify.addHook('onSend', function (request, reply, thePayload, next) {
958 t.ok('onSend called')
959 t.deepEqual(JSON.parse(thePayload), payload)
960 thePayload = thePayload.replace('world', 'modified')
961 next(null, thePayload)
962 })
963
964 fastify.addHook('onSend', function (request, reply, thePayload, next) {
965 t.ok('onSend called')
966 t.deepEqual(JSON.parse(thePayload), modifiedPayload)
967 next(null, anotherPayload)
968 })
969
970 fastify.addHook('onSend', function (request, reply, thePayload, next) {
971 t.ok('onSend called')
972 t.strictEqual(thePayload, anotherPayload)
973 next()
974 })
975
976 fastify.get('/', (req, reply) => {
977 reply.send(payload)
978 })
979
980 fastify.inject({
981 method: 'GET',
982 url: '/'
983 }, (err, res) => {
984 t.error(err)
985 t.strictEqual(res.payload, anotherPayload)
986 t.strictEqual(res.statusCode, 200)
987 t.strictEqual(res.headers['content-length'], '18')
988 })
989})
990
991test('clear payload', t => {
992 t.plan(6)
993 const fastify = Fastify()
994
995 fastify.addHook('onSend', function (request, reply, payload, next) {
996 t.ok('onSend called')
997 reply.code(304)
998 next(null, null)
999 })
1000
1001 fastify.get('/', (req, reply) => {
1002 reply.send({ hello: 'world' })
1003 })
1004
1005 fastify.inject({
1006 method: 'GET',
1007 url: '/'
1008 }, (err, res) => {
1009 t.error(err)
1010 t.strictEqual(res.statusCode, 304)
1011 t.strictEqual(res.payload, '')
1012 t.strictEqual(res.headers['content-length'], undefined)
1013 t.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8')
1014 })
1015})
1016
1017test('onSend hook throws', t => {
1018 t.plan(7)
1019 const fastify = Fastify()
1020 fastify.addHook('onSend', function (request, reply, payload, next) {
1021 if (request.raw.method === 'DELETE') {
1022 next(new Error('some error'))
1023 return
1024 }
1025 next()
1026 })
1027
1028 fastify.get('/', (req, reply) => {
1029 reply.send({ hello: 'world' })
1030 })
1031
1032 fastify.delete('/', (req, reply) => {
1033 reply.send({ hello: 'world' })
1034 })
1035
1036 fastify.listen(0, err => {
1037 t.error(err)
1038 fastify.server.unref()
1039 sget({
1040 method: 'GET',
1041 url: 'http://localhost:' + fastify.server.address().port
1042 }, (err, response, body) => {
1043 t.error(err)
1044 t.strictEqual(response.statusCode, 200)
1045 t.strictEqual(response.headers['content-length'], '' + body.length)
1046 t.deepEqual(JSON.parse(body), { hello: 'world' })
1047 })
1048 sget({
1049 method: 'DELETE',
1050 url: 'http://localhost:' + fastify.server.address().port
1051 }, (err, response, body) => {
1052 t.error(err)
1053 t.strictEqual(response.statusCode, 500)
1054 })
1055 })
1056})
1057
1058test('onSend hook should receive valid request and reply objects if onRequest hook fails', t => {
1059 t.plan(4)
1060 const fastify = Fastify()
1061
1062 fastify.decorateRequest('testDecorator', 'testDecoratorVal')
1063 fastify.decorateReply('testDecorator', 'testDecoratorVal')
1064
1065 fastify.addHook('onRequest', function (req, reply, next) {
1066 next(new Error('onRequest hook failed'))
1067 })
1068
1069 fastify.addHook('onSend', function (request, reply, payload, next) {
1070 t.strictEqual(request.testDecorator, 'testDecoratorVal')
1071 t.strictEqual(reply.testDecorator, 'testDecoratorVal')
1072 next()
1073 })
1074
1075 fastify.get('/', (req, reply) => {
1076 reply.send('hello')
1077 })
1078
1079 fastify.inject({
1080 method: 'GET',
1081 url: '/'
1082 }, (err, res) => {
1083 t.error(err)
1084 t.strictEqual(res.statusCode, 500)
1085 })
1086})
1087
1088test('onSend hook should receive valid request and reply objects if middleware fails', t => {
1089 t.plan(4)
1090 const fastify = Fastify()
1091
1092 fastify.decorateRequest('testDecorator', 'testDecoratorVal')
1093 fastify.decorateReply('testDecorator', 'testDecoratorVal')
1094
1095 fastify.use(function (req, res, next) {
1096 next(new Error('middlware failed'))
1097 })
1098
1099 fastify.addHook('onSend', function (request, reply, payload, next) {
1100 t.strictEqual(request.testDecorator, 'testDecoratorVal')
1101 t.strictEqual(reply.testDecorator, 'testDecoratorVal')
1102 next()
1103 })
1104
1105 fastify.get('/', (req, reply) => {
1106 reply.send('hello')
1107 })
1108
1109 fastify.inject({
1110 method: 'GET',
1111 url: '/'
1112 }, (err, res) => {
1113 t.error(err)
1114 t.strictEqual(res.statusCode, 500)
1115 })
1116})
1117
1118test('onSend hook should receive valid request and reply objects if a custom content type parser fails', t => {
1119 t.plan(4)
1120 const fastify = Fastify()
1121
1122 fastify.decorateRequest('testDecorator', 'testDecoratorVal')
1123 fastify.decorateReply('testDecorator', 'testDecoratorVal')
1124
1125 fastify.addContentTypeParser('*', function (req, done) {
1126 done(new Error('content type parser failed'))
1127 })
1128
1129 fastify.addHook('onSend', function (request, reply, payload, next) {
1130 t.strictEqual(request.testDecorator, 'testDecoratorVal')
1131 t.strictEqual(reply.testDecorator, 'testDecoratorVal')
1132 next()
1133 })
1134
1135 fastify.get('/', (req, reply) => {
1136 reply.send('hello')
1137 })
1138
1139 fastify.inject({
1140 method: 'POST',
1141 url: '/',
1142 payload: 'body'
1143 }, (err, res) => {
1144 t.error(err)
1145 t.strictEqual(res.statusCode, 500)
1146 })
1147})
1148
1149test('cannot add hook after binding', t => {
1150 t.plan(2)
1151 const instance = Fastify()
1152
1153 instance.get('/', function (request, reply) {
1154 reply.send({ hello: 'world' })
1155 })
1156
1157 instance.listen(0, err => {
1158 t.error(err)
1159 t.tearDown(instance.server.close.bind(instance.server))
1160
1161 try {
1162 instance.addHook('onRequest', () => {})
1163 t.fail()
1164 } catch (e) {
1165 t.pass()
1166 }
1167 })
1168})
1169
1170test('onRequest hooks should be able to block a request', t => {
1171 t.plan(5)
1172 const fastify = Fastify()
1173
1174 fastify.addHook('onRequest', (req, reply, next) => {
1175 reply.send('hello')
1176 next()
1177 })
1178
1179 fastify.addHook('onRequest', (req, reply, next) => {
1180 t.fail('this should not be called')
1181 })
1182
1183 fastify.addHook('preHandler', (req, reply, next) => {
1184 t.fail('this should not be called')
1185 })
1186
1187 fastify.addHook('onSend', (req, reply, payload, next) => {
1188 t.ok('called')
1189 next()
1190 })
1191
1192 fastify.addHook('onResponse', (request, reply, next) => {
1193 t.ok('called')
1194 next()
1195 })
1196
1197 fastify.get('/', function (request, reply) {
1198 t.fail('we should not be here')
1199 })
1200
1201 fastify.inject({
1202 url: '/',
1203 method: 'GET'
1204 }, (err, res) => {
1205 t.error(err)
1206 t.is(res.statusCode, 200)
1207 t.is(res.payload, 'hello')
1208 })
1209})
1210
1211test('preValidation hooks should be able to block a request', t => {
1212 t.plan(5)
1213 const fastify = Fastify()
1214
1215 fastify.addHook('preValidation', (req, reply, next) => {
1216 reply.send('hello')
1217 next()
1218 })
1219
1220 fastify.addHook('preValidation', (req, reply, next) => {
1221 t.fail('this should not be called')
1222 })
1223
1224 fastify.addHook('preHandler', (req, reply, next) => {
1225 t.fail('this should not be called')
1226 })
1227
1228 fastify.addHook('onSend', (req, reply, payload, next) => {
1229 t.ok('called')
1230 next()
1231 })
1232
1233 fastify.addHook('onResponse', (request, reply, next) => {
1234 t.ok('called')
1235 next()
1236 })
1237
1238 fastify.get('/', function (request, reply) {
1239 t.fail('we should not be here')
1240 })
1241
1242 fastify.inject({
1243 url: '/',
1244 method: 'GET'
1245 }, (err, res) => {
1246 t.error(err)
1247 t.is(res.statusCode, 200)
1248 t.is(res.payload, 'hello')
1249 })
1250})
1251
1252test('preParsing hooks should be able to block a request', t => {
1253 t.plan(5)
1254 const fastify = Fastify()
1255
1256 fastify.addHook('preParsing', (req, reply, next) => {
1257 reply.send('hello')
1258 next()
1259 })
1260
1261 fastify.addHook('preParsing', (req, reply, next) => {
1262 t.fail('this should not be called')
1263 })
1264
1265 fastify.addHook('preHandler', (req, reply, next) => {
1266 t.fail('this should not be called')
1267 })
1268
1269 fastify.addHook('onSend', (req, reply, payload, next) => {
1270 t.ok('called')
1271 next()
1272 })
1273
1274 fastify.addHook('onResponse', (request, reply, next) => {
1275 t.ok('called')
1276 next()
1277 })
1278
1279 fastify.get('/', function (request, reply) {
1280 t.fail('we should not be here')
1281 })
1282
1283 fastify.inject({
1284 url: '/',
1285 method: 'GET'
1286 }, (err, res) => {
1287 t.error(err)
1288 t.is(res.statusCode, 200)
1289 t.is(res.payload, 'hello')
1290 })
1291})
1292
1293test('preHandler hooks should be able to block a request', t => {
1294 t.plan(5)
1295 const fastify = Fastify()
1296
1297 fastify.addHook('preHandler', (req, reply, next) => {
1298 reply.send('hello')
1299 next()
1300 })
1301
1302 fastify.addHook('preHandler', (req, reply, next) => {
1303 t.fail('this should not be called')
1304 })
1305
1306 fastify.addHook('onSend', (req, reply, payload, next) => {
1307 t.equal(payload, 'hello')
1308 next()
1309 })
1310
1311 fastify.addHook('onResponse', (request, reply, next) => {
1312 t.ok('called')
1313 next()
1314 })
1315
1316 fastify.get('/', function (request, reply) {
1317 t.fail('we should not be here')
1318 })
1319
1320 fastify.inject({
1321 url: '/',
1322 method: 'GET'
1323 }, (err, res) => {
1324 t.error(err)
1325 t.is(res.statusCode, 200)
1326 t.is(res.payload, 'hello')
1327 })
1328})
1329
1330test('onRequest hooks should be able to block a request (last hook)', t => {
1331 t.plan(5)
1332 const fastify = Fastify()
1333
1334 fastify.addHook('onRequest', (req, reply, next) => {
1335 reply.send('hello')
1336 next()
1337 })
1338
1339 fastify.addHook('preHandler', (req, reply, next) => {
1340 t.fail('this should not be called')
1341 })
1342
1343 fastify.addHook('onSend', (req, reply, payload, next) => {
1344 t.ok('called')
1345 next()
1346 })
1347
1348 fastify.addHook('onResponse', (request, reply, next) => {
1349 t.ok('called')
1350 next()
1351 })
1352
1353 fastify.get('/', function (request, reply) {
1354 t.fail('we should not be here')
1355 })
1356
1357 fastify.inject({
1358 url: '/',
1359 method: 'GET'
1360 }, (err, res) => {
1361 t.error(err)
1362 t.is(res.statusCode, 200)
1363 t.is(res.payload, 'hello')
1364 })
1365})
1366
1367test('preHandler hooks should be able to block a request (last hook)', t => {
1368 t.plan(5)
1369 const fastify = Fastify()
1370
1371 fastify.addHook('preHandler', (req, reply, next) => {
1372 reply.send('hello')
1373 next()
1374 })
1375
1376 fastify.addHook('onSend', (req, reply, payload, next) => {
1377 t.equal(payload, 'hello')
1378 next()
1379 })
1380
1381 fastify.addHook('onResponse', (request, reply, next) => {
1382 t.ok('called')
1383 next()
1384 })
1385
1386 fastify.get('/', function (request, reply) {
1387 t.fail('we should not be here')
1388 })
1389
1390 fastify.inject({
1391 url: '/',
1392 method: 'GET'
1393 }, (err, res) => {
1394 t.error(err)
1395 t.is(res.statusCode, 200)
1396 t.is(res.payload, 'hello')
1397 })
1398})
1399
1400test('onRequest respond with a stream', t => {
1401 t.plan(4)
1402 const fastify = Fastify()
1403
1404 fastify.addHook('onRequest', (req, reply, next) => {
1405 const stream = fs.createReadStream(process.cwd() + '/test/stream.test.js', 'utf8')
1406 // stream.pipe(res)
1407 // res.once('finish', next)
1408 reply.send(stream)
1409 })
1410
1411 fastify.addHook('onRequest', (req, res, next) => {
1412 t.fail('this should not be called')
1413 })
1414
1415 fastify.addHook('preHandler', (req, reply, next) => {
1416 t.fail('this should not be called')
1417 })
1418
1419 fastify.addHook('onSend', (req, reply, payload, next) => {
1420 t.ok('called')
1421 next()
1422 })
1423
1424 fastify.addHook('onResponse', (request, reply, next) => {
1425 t.ok('called')
1426 next()
1427 })
1428
1429 fastify.get('/', function (request, reply) {
1430 t.fail('we should not be here')
1431 })
1432
1433 fastify.inject({
1434 url: '/',
1435 method: 'GET'
1436 }, (err, res) => {
1437 t.error(err)
1438 t.is(res.statusCode, 200)
1439 })
1440})
1441
1442test('preHandler respond with a stream', t => {
1443 t.plan(7)
1444 const fastify = Fastify()
1445
1446 fastify.addHook('onRequest', (req, reply, next) => {
1447 t.ok('called')
1448 next()
1449 })
1450
1451 // we are calling `reply.send` inside the `preHandler` hook with a stream,
1452 // this triggers the `onSend` hook event if `preHanlder` has not yet finished
1453 const order = [1, 2]
1454
1455 fastify.addHook('preHandler', (req, reply, next) => {
1456 const stream = fs.createReadStream(process.cwd() + '/test/stream.test.js', 'utf8')
1457 reply.send(stream)
1458 reply.res.once('finish', () => {
1459 t.is(order.shift(), 2)
1460 next()
1461 })
1462 })
1463
1464 fastify.addHook('preHandler', (req, reply, next) => {
1465 t.fail('this should not be called')
1466 })
1467
1468 fastify.addHook('onSend', (req, reply, payload, next) => {
1469 t.is(order.shift(), 1)
1470 t.is(typeof payload.pipe, 'function')
1471 next()
1472 })
1473
1474 fastify.addHook('onResponse', (request, reply, next) => {
1475 t.ok('called')
1476 next()
1477 })
1478
1479 fastify.get('/', function (request, reply) {
1480 t.fail('we should not be here')
1481 })
1482
1483 fastify.inject({
1484 url: '/',
1485 method: 'GET'
1486 }, (err, res) => {
1487 t.error(err)
1488 t.is(res.statusCode, 200)
1489 })
1490})
1491
1492test('Register an hook after a plugin inside a plugin', t => {
1493 t.plan(6)
1494 const fastify = Fastify()
1495
1496 fastify.register(fp(function (instance, opts, next) {
1497 instance.addHook('preHandler', function (req, reply, next) {
1498 t.ok('called')
1499 next()
1500 })
1501
1502 instance.get('/', function (request, reply) {
1503 reply.send({ hello: 'world' })
1504 })
1505
1506 next()
1507 }))
1508
1509 fastify.register(fp(function (instance, opts, next) {
1510 instance.addHook('preHandler', function (req, reply, next) {
1511 t.ok('called')
1512 next()
1513 })
1514
1515 instance.addHook('preHandler', function (req, reply, next) {
1516 t.ok('called')
1517 next()
1518 })
1519
1520 next()
1521 }))
1522
1523 fastify.inject({
1524 url: '/',
1525 method: 'GET'
1526 }, (err, res) => {
1527 t.error(err)
1528 t.is(res.statusCode, 200)
1529 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
1530 })
1531})
1532
1533test('Register an hook after a plugin inside a plugin (with preHandler option)', t => {
1534 t.plan(7)
1535 const fastify = Fastify()
1536
1537 fastify.register(fp(function (instance, opts, next) {
1538 instance.addHook('preHandler', function (req, reply, next) {
1539 t.ok('called')
1540 next()
1541 })
1542
1543 instance.get('/', {
1544 preHandler: (req, reply, next) => {
1545 t.ok('called')
1546 next()
1547 }
1548 }, function (request, reply) {
1549 reply.send({ hello: 'world' })
1550 })
1551
1552 next()
1553 }))
1554
1555 fastify.register(fp(function (instance, opts, next) {
1556 instance.addHook('preHandler', function (req, reply, next) {
1557 t.ok('called')
1558 next()
1559 })
1560
1561 instance.addHook('preHandler', function (req, reply, next) {
1562 t.ok('called')
1563 next()
1564 })
1565
1566 next()
1567 }))
1568
1569 fastify.inject({
1570 url: '/',
1571 method: 'GET'
1572 }, (err, res) => {
1573 t.error(err)
1574 t.is(res.statusCode, 200)
1575 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
1576 })
1577})
1578
1579test('Register hooks inside a plugin after an encapsulated plugin', t => {
1580 t.plan(7)
1581 const fastify = Fastify()
1582
1583 fastify.register(function (instance, opts, next) {
1584 instance.get('/', function (request, reply) {
1585 reply.send({ hello: 'world' })
1586 })
1587
1588 next()
1589 })
1590
1591 fastify.register(fp(function (instance, opts, next) {
1592 instance.addHook('onRequest', function (req, reply, next) {
1593 t.ok('called')
1594 next()
1595 })
1596
1597 instance.addHook('preHandler', function (request, reply, next) {
1598 t.ok('called')
1599 next()
1600 })
1601
1602 instance.addHook('onSend', function (request, reply, payload, next) {
1603 t.ok('called')
1604 next()
1605 })
1606
1607 instance.addHook('onResponse', function (request, reply, next) {
1608 t.ok('called')
1609 next()
1610 })
1611
1612 next()
1613 }))
1614
1615 fastify.inject('/', (err, res) => {
1616 t.error(err)
1617 t.is(res.statusCode, 200)
1618 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
1619 })
1620})
1621
1622test('onRequest hooks should run in the order in which they are defined', t => {
1623 t.plan(9)
1624 const fastify = Fastify()
1625
1626 fastify.register(function (instance, opts, next) {
1627 instance.addHook('onRequest', function (req, reply, next) {
1628 t.strictEqual(req.previous, undefined)
1629 req.previous = 1
1630 next()
1631 })
1632
1633 instance.get('/', function (request, reply) {
1634 t.strictEqual(request.previous, 5)
1635 reply.send({ hello: 'world' })
1636 })
1637
1638 instance.register(fp(function (i, opts, next) {
1639 i.addHook('onRequest', function (req, reply, next) {
1640 t.strictEqual(req.previous, 1)
1641 req.previous = 2
1642 next()
1643 })
1644 next()
1645 }))
1646
1647 next()
1648 })
1649
1650 fastify.register(fp(function (instance, opts, next) {
1651 instance.addHook('onRequest', function (req, reply, next) {
1652 t.strictEqual(req.previous, 2)
1653 req.previous = 3
1654 next()
1655 })
1656
1657 instance.register(fp(function (i, opts, next) {
1658 i.addHook('onRequest', function (req, reply, next) {
1659 t.strictEqual(req.previous, 3)
1660 req.previous = 4
1661 next()
1662 })
1663 next()
1664 }))
1665
1666 instance.addHook('onRequest', function (req, reply, next) {
1667 t.strictEqual(req.previous, 4)
1668 req.previous = 5
1669 next()
1670 })
1671
1672 next()
1673 }))
1674
1675 fastify.inject('/', (err, res) => {
1676 t.error(err)
1677 t.strictEqual(res.statusCode, 200)
1678 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
1679 })
1680})
1681
1682test('preHandler hooks should run in the order in which they are defined', t => {
1683 t.plan(9)
1684 const fastify = Fastify()
1685
1686 fastify.register(function (instance, opts, next) {
1687 instance.addHook('preHandler', function (request, reply, next) {
1688 t.strictEqual(request.previous, undefined)
1689 request.previous = 1
1690 next()
1691 })
1692
1693 instance.get('/', function (request, reply) {
1694 t.strictEqual(request.previous, 5)
1695 reply.send({ hello: 'world' })
1696 })
1697
1698 instance.register(fp(function (i, opts, next) {
1699 i.addHook('preHandler', function (request, reply, next) {
1700 t.strictEqual(request.previous, 1)
1701 request.previous = 2
1702 next()
1703 })
1704 next()
1705 }))
1706
1707 next()
1708 })
1709
1710 fastify.register(fp(function (instance, opts, next) {
1711 instance.addHook('preHandler', function (request, reply, next) {
1712 t.strictEqual(request.previous, 2)
1713 request.previous = 3
1714 next()
1715 })
1716
1717 instance.register(fp(function (i, opts, next) {
1718 i.addHook('preHandler', function (request, reply, next) {
1719 t.strictEqual(request.previous, 3)
1720 request.previous = 4
1721 next()
1722 })
1723 next()
1724 }))
1725
1726 instance.addHook('preHandler', function (request, reply, next) {
1727 t.strictEqual(request.previous, 4)
1728 request.previous = 5
1729 next()
1730 })
1731
1732 next()
1733 }))
1734
1735 fastify.inject('/', (err, res) => {
1736 t.error(err)
1737 t.strictEqual(res.statusCode, 200)
1738 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
1739 })
1740})
1741
1742test('onSend hooks should run in the order in which they are defined', t => {
1743 t.plan(8)
1744 const fastify = Fastify()
1745
1746 fastify.register(function (instance, opts, next) {
1747 instance.addHook('onSend', function (request, reply, payload, next) {
1748 t.strictEqual(request.previous, undefined)
1749 request.previous = 1
1750 next()
1751 })
1752
1753 instance.get('/', function (request, reply) {
1754 reply.send({})
1755 })
1756
1757 instance.register(fp(function (i, opts, next) {
1758 i.addHook('onSend', function (request, reply, payload, next) {
1759 t.strictEqual(request.previous, 1)
1760 request.previous = 2
1761 next()
1762 })
1763 next()
1764 }))
1765
1766 next()
1767 })
1768
1769 fastify.register(fp(function (instance, opts, next) {
1770 instance.addHook('onSend', function (request, reply, payload, next) {
1771 t.strictEqual(request.previous, 2)
1772 request.previous = 3
1773 next()
1774 })
1775
1776 instance.register(fp(function (i, opts, next) {
1777 i.addHook('onSend', function (request, reply, payload, next) {
1778 t.strictEqual(request.previous, 3)
1779 request.previous = 4
1780 next()
1781 })
1782 next()
1783 }))
1784
1785 instance.addHook('onSend', function (request, reply, payload, next) {
1786 t.strictEqual(request.previous, 4)
1787 next(null, '5')
1788 })
1789
1790 next()
1791 }))
1792
1793 fastify.inject('/', (err, res) => {
1794 t.error(err)
1795 t.strictEqual(res.statusCode, 200)
1796 t.deepEqual(JSON.parse(res.payload), 5)
1797 })
1798})
1799
1800test('onResponse hooks should run in the order in which they are defined', t => {
1801 t.plan(8)
1802 const fastify = Fastify()
1803
1804 fastify.register(function (instance, opts, next) {
1805 instance.addHook('onResponse', function (request, reply, next) {
1806 t.strictEqual(reply.previous, undefined)
1807 reply.previous = 1
1808 next()
1809 })
1810
1811 instance.get('/', function (request, reply) {
1812 reply.send({ hello: 'world' })
1813 })
1814
1815 instance.register(fp(function (i, opts, next) {
1816 i.addHook('onResponse', function (request, reply, next) {
1817 t.strictEqual(reply.previous, 1)
1818 reply.previous = 2
1819 next()
1820 })
1821 next()
1822 }))
1823
1824 next()
1825 })
1826
1827 fastify.register(fp(function (instance, opts, next) {
1828 instance.addHook('onResponse', function (request, reply, next) {
1829 t.strictEqual(reply.previous, 2)
1830 reply.previous = 3
1831 next()
1832 })
1833
1834 instance.register(fp(function (i, opts, next) {
1835 i.addHook('onResponse', function (request, reply, next) {
1836 t.strictEqual(reply.previous, 3)
1837 reply.previous = 4
1838 next()
1839 })
1840 next()
1841 }))
1842
1843 instance.addHook('onResponse', function (request, reply, next) {
1844 t.strictEqual(reply.previous, 4)
1845 next()
1846 })
1847
1848 next()
1849 }))
1850
1851 fastify.inject('/', (err, res) => {
1852 t.error(err)
1853 t.strictEqual(res.statusCode, 200)
1854 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
1855 })
1856})
1857
1858test('onRequest, preHandler, and onResponse hooks that resolve to a value do not cause an error', t => {
1859 t.plan(3)
1860 const fastify = Fastify()
1861
1862 fastify
1863 .addHook('onRequest', () => Promise.resolve(1))
1864 .addHook('onRequest', () => Promise.resolve(true))
1865 .addHook('preValidation', () => Promise.resolve(null))
1866 .addHook('preValidation', () => Promise.resolve('a'))
1867 .addHook('preHandler', () => Promise.resolve(null))
1868 .addHook('preHandler', () => Promise.resolve('a'))
1869 .addHook('onResponse', () => Promise.resolve({}))
1870 .addHook('onResponse', () => Promise.resolve([]))
1871
1872 fastify.get('/', (request, reply) => {
1873 reply.send('hello')
1874 })
1875
1876 fastify.inject('/', (err, res) => {
1877 t.error(err)
1878 t.strictEqual(res.statusCode, 200)
1879 t.strictEqual(res.payload, 'hello')
1880 })
1881})
1882
1883test('If a response header has been set inside an hook it shoulod not be overwritten by the final response handler', t => {
1884 t.plan(5)
1885 const fastify = Fastify()
1886
1887 fastify.addHook('onRequest', (req, reply, next) => {
1888 reply.header('X-Custom-Header', 'hello')
1889 next()
1890 })
1891
1892 fastify.get('/', (request, reply) => {
1893 reply.send('hello')
1894 })
1895
1896 fastify.inject('/', (err, res) => {
1897 t.error(err)
1898 t.strictEqual(res.headers['x-custom-header'], 'hello')
1899 t.strictEqual(res.headers['content-type'], 'text/plain; charset=utf-8')
1900 t.strictEqual(res.statusCode, 200)
1901 t.strictEqual(res.payload, 'hello')
1902 })
1903})
1904
1905test('If the content type has been set inside an hook it should not be changed', t => {
1906 t.plan(5)
1907 const fastify = Fastify()
1908
1909 fastify.addHook('onRequest', (req, reply, next) => {
1910 reply.header('content-type', 'text/html')
1911 next()
1912 })
1913
1914 fastify.get('/', (request, reply) => {
1915 t.ok(reply[symbols.kReplyHeaders]['content-type'])
1916 reply.send('hello')
1917 })
1918
1919 fastify.inject('/', (err, res) => {
1920 t.error(err)
1921 t.strictEqual(res.headers['content-type'], 'text/html')
1922 t.strictEqual(res.statusCode, 200)
1923 t.strictEqual(res.payload, 'hello')
1924 })
1925})
1926
1927test('request in onRequest, preParsing, preValidation and onResponse', t => {
1928 t.plan(18)
1929 const fastify = Fastify()
1930
1931 fastify.addHook('onRequest', function (request, reply, next) {
1932 t.deepEqual(request.body, null)
1933 t.deepEqual(request.query, { key: 'value' })
1934 t.deepEqual(request.params, { greeting: 'hello' })
1935 t.deepEqual(request.headers, {
1936 'content-length': '17',
1937 'content-type': 'application/json',
1938 host: 'localhost:80',
1939 'user-agent': 'lightMyRequest',
1940 'x-custom': 'hello'
1941 })
1942 next()
1943 })
1944
1945 fastify.addHook('preParsing', function (request, reply, next) {
1946 t.deepEqual(request.body, null)
1947 t.deepEqual(request.query, { key: 'value' })
1948 t.deepEqual(request.params, { greeting: 'hello' })
1949 t.deepEqual(request.headers, {
1950 'content-length': '17',
1951 'content-type': 'application/json',
1952 host: 'localhost:80',
1953 'user-agent': 'lightMyRequest',
1954 'x-custom': 'hello'
1955 })
1956 next()
1957 })
1958
1959 fastify.addHook('preValidation', function (request, reply, next) {
1960 t.deepEqual(request.body, { hello: 'world' })
1961 t.deepEqual(request.query, { key: 'value' })
1962 t.deepEqual(request.params, { greeting: 'hello' })
1963 t.deepEqual(request.headers, {
1964 'content-length': '17',
1965 'content-type': 'application/json',
1966 host: 'localhost:80',
1967 'user-agent': 'lightMyRequest',
1968 'x-custom': 'hello'
1969 })
1970 next()
1971 })
1972
1973 fastify.addHook('onResponse', function (request, reply, next) {
1974 t.deepEqual(request.body, { hello: 'world' })
1975 t.deepEqual(request.query, { key: 'value' })
1976 t.deepEqual(request.params, { greeting: 'hello' })
1977 t.deepEqual(request.headers, {
1978 'content-length': '17',
1979 'content-type': 'application/json',
1980 host: 'localhost:80',
1981 'user-agent': 'lightMyRequest',
1982 'x-custom': 'hello'
1983 })
1984 next()
1985 })
1986
1987 fastify.post('/:greeting', function (req, reply) {
1988 reply.send('ok')
1989 })
1990
1991 fastify.inject({
1992 method: 'POST',
1993 url: '/hello?key=value',
1994 headers: { 'x-custom': 'hello' },
1995 payload: { hello: 'world' }
1996 }, (err, res) => {
1997 t.error(err)
1998 t.strictEqual(res.statusCode, 200)
1999 })
2000})
2001
2002test('preValidation hook should support encapsulation / 1', t => {
2003 t.plan(5)
2004 const fastify = Fastify()
2005
2006 fastify.register((instance, opts, next) => {
2007 instance.addHook('preValidation', (req, reply, next) => {
2008 t.strictEqual(req.raw.url, '/plugin')
2009 next()
2010 })
2011
2012 instance.get('/plugin', (request, reply) => {
2013 reply.send()
2014 })
2015
2016 next()
2017 })
2018
2019 fastify.get('/root', (request, reply) => {
2020 reply.send()
2021 })
2022
2023 fastify.inject('/root', (err, res) => {
2024 t.error(err)
2025 t.strictEqual(res.statusCode, 200)
2026 })
2027
2028 fastify.inject('/plugin', (err, res) => {
2029 t.error(err)
2030 t.strictEqual(res.statusCode, 200)
2031 })
2032})
2033
2034test('preValidation hook should support encapsulation / 2', t => {
2035 t.plan(3)
2036 const fastify = Fastify()
2037 var pluginInstance
2038
2039 fastify.addHook('preValidation', () => {})
2040
2041 fastify.register((instance, opts, next) => {
2042 instance.addHook('preValidation', () => {})
2043 pluginInstance = instance
2044 next()
2045 })
2046
2047 fastify.ready(err => {
2048 t.error(err)
2049 t.is(fastify[symbols.kHooks].preValidation.length, 1)
2050 t.is(pluginInstance[symbols.kHooks].preValidation.length, 2)
2051 })
2052})
2053
2054test('preValidation hook should support encapsulation / 3', t => {
2055 t.plan(20)
2056 const fastify = Fastify()
2057 fastify.decorate('hello', 'world')
2058
2059 fastify.addHook('preValidation', function (req, reply, next) {
2060 t.ok(this.hello)
2061 t.ok(this.hello2)
2062 req.first = true
2063 next()
2064 })
2065
2066 fastify.decorate('hello2', 'world')
2067
2068 fastify.get('/first', (req, reply) => {
2069 t.ok(req.first)
2070 t.notOk(req.second)
2071 reply.send({ hello: 'world' })
2072 })
2073
2074 fastify.register((instance, opts, next) => {
2075 instance.decorate('hello3', 'world')
2076 instance.addHook('preValidation', function (req, reply, next) {
2077 t.ok(this.hello)
2078 t.ok(this.hello2)
2079 t.ok(this.hello3)
2080 req.second = true
2081 next()
2082 })
2083
2084 instance.get('/second', (req, reply) => {
2085 t.ok(req.first)
2086 t.ok(req.second)
2087 reply.send({ hello: 'world' })
2088 })
2089
2090 next()
2091 })
2092
2093 fastify.listen(0, err => {
2094 t.error(err)
2095 fastify.server.unref()
2096
2097 sget({
2098 method: 'GET',
2099 url: 'http://localhost:' + fastify.server.address().port + '/first'
2100 }, (err, response, body) => {
2101 t.error(err)
2102 t.strictEqual(response.statusCode, 200)
2103 t.strictEqual(response.headers['content-length'], '' + body.length)
2104 t.deepEqual(JSON.parse(body), { hello: 'world' })
2105 })
2106
2107 sget({
2108 method: 'GET',
2109 url: 'http://localhost:' + fastify.server.address().port + '/second'
2110 }, (err, response, body) => {
2111 t.error(err)
2112 t.strictEqual(response.statusCode, 200)
2113 t.strictEqual(response.headers['content-length'], '' + body.length)
2114 t.deepEqual(JSON.parse(body), { hello: 'world' })
2115 })
2116 })
2117})
2118
2119test('onError hook', t => {
2120 t.plan(3)
2121
2122 const fastify = Fastify()
2123
2124 const err = new Error('kaboom')
2125
2126 fastify.addHook('onError', (request, reply, error, next) => {
2127 t.match(error, err)
2128 next()
2129 })
2130
2131 fastify.get('/', (req, reply) => {
2132 reply.send(err)
2133 })
2134
2135 fastify.inject({
2136 method: 'GET',
2137 url: '/'
2138 }, (err, res) => {
2139 t.error(err)
2140 t.deepEqual(JSON.parse(res.payload), {
2141 error: 'Internal Server Error',
2142 message: 'kaboom',
2143 statusCode: 500
2144 })
2145 })
2146})
2147
2148test('reply.send should throw if called inside the onError hook', t => {
2149 t.plan(3)
2150
2151 const fastify = Fastify()
2152
2153 const err = new Error('kaboom')
2154
2155 fastify.addHook('onError', (request, reply, error, next) => {
2156 try {
2157 reply.send()
2158 t.fail('Should throw')
2159 } catch (err) {
2160 t.is(err.code, 'FST_ERR_SEND_INSIDE_ONERR')
2161 }
2162 next()
2163 })
2164
2165 fastify.get('/', (req, reply) => {
2166 reply.send(err)
2167 })
2168
2169 fastify.inject({
2170 method: 'GET',
2171 url: '/'
2172 }, (err, res) => {
2173 t.error(err)
2174 t.deepEqual(JSON.parse(res.payload), {
2175 error: 'Internal Server Error',
2176 message: 'kaboom',
2177 statusCode: 500
2178 })
2179 })
2180})
2181
2182test('onError hook with setErrorHandler', t => {
2183 t.test('Send error', t => {
2184 t.plan(3)
2185
2186 const fastify = Fastify()
2187
2188 const err = new Error('ouch')
2189
2190 fastify.setErrorHandler((_, req, reply) => {
2191 reply.send(err)
2192 })
2193
2194 fastify.addHook('onError', (request, reply, error, next) => {
2195 t.match(error, err)
2196 next()
2197 })
2198
2199 fastify.get('/', (req, reply) => {
2200 reply.send(new Error('kaboom'))
2201 })
2202
2203 fastify.inject({
2204 method: 'GET',
2205 url: '/'
2206 }, (err, res) => {
2207 t.error(err)
2208 t.deepEqual(JSON.parse(res.payload), {
2209 error: 'Internal Server Error',
2210 message: 'ouch',
2211 statusCode: 500
2212 })
2213 })
2214 })
2215
2216 t.test('Hide error', t => {
2217 t.plan(2)
2218
2219 const fastify = Fastify()
2220
2221 fastify.setErrorHandler((_, req, reply) => {
2222 reply.send({ hello: 'world' })
2223 })
2224
2225 fastify.addHook('onError', (request, reply, error, next) => {
2226 t.fail('Should not be called')
2227 })
2228
2229 fastify.get('/', (req, reply) => {
2230 reply.send(new Error('kaboom'))
2231 })
2232
2233 fastify.inject({
2234 method: 'GET',
2235 url: '/'
2236 }, (err, res) => {
2237 t.error(err)
2238 t.deepEqual(
2239 JSON.parse(res.payload),
2240 { hello: 'world' }
2241 )
2242 })
2243 })
2244 t.end()
2245})
2246
2247test('preParsing hook should support encapsulation / 1', t => {
2248 t.plan(5)
2249 const fastify = Fastify()
2250
2251 fastify.register((instance, opts, next) => {
2252 instance.addHook('preParsing', (req, reply, next) => {
2253 t.strictEqual(req.raw.url, '/plugin')
2254 next()
2255 })
2256
2257 instance.get('/plugin', (request, reply) => {
2258 reply.send()
2259 })
2260
2261 next()
2262 })
2263
2264 fastify.get('/root', (request, reply) => {
2265 reply.send()
2266 })
2267
2268 fastify.inject('/root', (err, res) => {
2269 t.error(err)
2270 t.strictEqual(res.statusCode, 200)
2271 })
2272
2273 fastify.inject('/plugin', (err, res) => {
2274 t.error(err)
2275 t.strictEqual(res.statusCode, 200)
2276 })
2277})
2278
2279test('preParsing hook should support encapsulation / 2', t => {
2280 t.plan(3)
2281 const fastify = Fastify()
2282 var pluginInstance
2283
2284 fastify.addHook('preParsing', function a () {})
2285
2286 fastify.register((instance, opts, next) => {
2287 instance.addHook('preParsing', function b () {})
2288 pluginInstance = instance
2289 next()
2290 })
2291
2292 fastify.ready(err => {
2293 t.error(err)
2294 t.is(fastify[symbols.kHooks].preParsing.length, 1)
2295 t.is(pluginInstance[symbols.kHooks].preParsing.length, 2)
2296 })
2297})
2298
2299test('preParsing hook should support encapsulation / 3', t => {
2300 t.plan(20)
2301 const fastify = Fastify()
2302 fastify.decorate('hello', 'world')
2303
2304 fastify.addHook('preParsing', function (req, reply, next) {
2305 t.ok(this.hello)
2306 t.ok(this.hello2)
2307 req.first = true
2308 next()
2309 })
2310
2311 fastify.decorate('hello2', 'world')
2312
2313 fastify.get('/first', (req, reply) => {
2314 t.ok(req.first)
2315 t.notOk(req.second)
2316 reply.send({ hello: 'world' })
2317 })
2318
2319 fastify.register((instance, opts, next) => {
2320 instance.decorate('hello3', 'world')
2321 instance.addHook('preParsing', function (req, reply, next) {
2322 t.ok(this.hello)
2323 t.ok(this.hello2)
2324 t.ok(this.hello3)
2325 req.second = true
2326 next()
2327 })
2328
2329 instance.get('/second', (req, reply) => {
2330 t.ok(req.first)
2331 t.ok(req.second)
2332 reply.send({ hello: 'world' })
2333 })
2334
2335 next()
2336 })
2337
2338 fastify.listen(0, err => {
2339 t.error(err)
2340 fastify.server.unref()
2341
2342 sget({
2343 method: 'GET',
2344 url: 'http://localhost:' + fastify.server.address().port + '/first'
2345 }, (err, response, body) => {
2346 t.error(err)
2347 t.strictEqual(response.statusCode, 200)
2348 t.strictEqual(response.headers['content-length'], '' + body.length)
2349 t.deepEqual(JSON.parse(body), { hello: 'world' })
2350 })
2351
2352 sget({
2353 method: 'GET',
2354 url: 'http://localhost:' + fastify.server.address().port + '/second'
2355 }, (err, response, body) => {
2356 t.error(err)
2357 t.strictEqual(response.statusCode, 200)
2358 t.strictEqual(response.headers['content-length'], '' + body.length)
2359 t.deepEqual(JSON.parse(body), { hello: 'world' })
2360 })
2361 })
2362})
2363
2364test('preSerialization hook should run before serialization and be able to modify the payload', t => {
2365 t.plan(5)
2366 const fastify = Fastify()
2367
2368 fastify.addHook('preSerialization', function (req, reply, payload, next) {
2369 payload.hello += '1'
2370 payload.world = 'ok'
2371
2372 next(null, payload)
2373 })
2374
2375 fastify.route({
2376 method: 'GET',
2377 url: '/first',
2378 handler: function (req, reply) {
2379 reply.send({ hello: 'world' })
2380 },
2381 schema: {
2382 response: {
2383 200: {
2384 type: 'object',
2385 properties: {
2386 hello: {
2387 type: 'string'
2388 },
2389 world: {
2390 type: 'string'
2391 }
2392 },
2393 required: ['world'],
2394 additionalProperties: false
2395 }
2396 }
2397 }
2398 })
2399
2400 fastify.listen(0, err => {
2401 t.error(err)
2402 fastify.server.unref()
2403
2404 sget({
2405 method: 'GET',
2406 url: 'http://localhost:' + fastify.server.address().port + '/first'
2407 }, (err, response, body) => {
2408 t.error(err)
2409 t.strictEqual(response.statusCode, 200)
2410 t.strictEqual(response.headers['content-length'], '' + body.length)
2411 t.deepEqual(JSON.parse(body), { hello: 'world1', world: 'ok' })
2412 })
2413 })
2414})
2415
2416test('preSerialization hook should be able to throw errors which are not validated against schema response', t => {
2417 const fastify = Fastify()
2418
2419 fastify.addHook('preSerialization', function (req, reply, payload, next) {
2420 next(new Error('preSerialization aborted'))
2421 })
2422
2423 fastify.route({
2424 method: 'GET',
2425 url: '/first',
2426 handler: function (req, reply) {
2427 reply.send({ hello: 'world' })
2428 },
2429 schema: {
2430 response: {
2431 500: {
2432 type: 'object',
2433 properties: {
2434 world: {
2435 type: 'string'
2436 }
2437 },
2438 required: ['world'],
2439 additionalProperties: false
2440 }
2441 }
2442 }
2443 })
2444
2445 fastify.listen(0, err => {
2446 t.error(err)
2447 fastify.server.unref()
2448
2449 sget({
2450 method: 'GET',
2451 url: 'http://localhost:' + fastify.server.address().port + '/first'
2452 }, (err, response, body) => {
2453 t.error(err)
2454 t.strictEqual(response.statusCode, 500)
2455 t.strictEqual(response.headers['content-length'], '' + body.length)
2456 t.deepEqual(JSON.parse(body), { error: 'Internal Server Error', message: 'preSerialization aborted', statusCode: 500 })
2457 t.end()
2458 })
2459 })
2460})
2461
2462test('preSerialization hook which returned error should still run onError hooks', t => {
2463 t.plan(4)
2464 const fastify = Fastify()
2465
2466 fastify.addHook('preSerialization', function (req, reply, payload, next) {
2467 next(new Error('preSerialization aborted'))
2468 })
2469
2470 fastify.addHook('onError', function (req, reply, payload, next) {
2471 t.pass()
2472 next()
2473 })
2474
2475 fastify.get('/first', (req, reply) => {
2476 reply.send({ hello: 'world' })
2477 })
2478
2479 fastify.listen(0, err => {
2480 t.error(err)
2481 fastify.server.unref()
2482
2483 sget({
2484 method: 'GET',
2485 url: 'http://localhost:' + fastify.server.address().port + '/first'
2486 }, (err, response, body) => {
2487 t.error(err)
2488 t.strictEqual(response.statusCode, 500)
2489 })
2490 })
2491})
2492
2493test('preSerialization hooks should run in the order in which they are defined', t => {
2494 t.plan(5)
2495 const fastify = Fastify()
2496
2497 fastify.addHook('preSerialization', function (req, reply, payload, next) {
2498 payload.hello += '2'
2499
2500 next(null, payload)
2501 })
2502
2503 fastify.addHook('preSerialization', function (req, reply, payload, next) {
2504 payload.hello += '1'
2505
2506 next(null, payload)
2507 })
2508
2509 fastify.get('/first', (req, reply) => {
2510 reply.send(payload)
2511 })
2512
2513 fastify.listen(0, err => {
2514 t.error(err)
2515 fastify.server.unref()
2516
2517 sget({
2518 method: 'GET',
2519 url: 'http://localhost:' + fastify.server.address().port + '/first'
2520 }, (err, response, body) => {
2521 t.error(err)
2522 t.strictEqual(response.statusCode, 200)
2523 t.strictEqual(response.headers['content-length'], '' + body.length)
2524 t.deepEqual(JSON.parse(body), { hello: 'world21' })
2525 })
2526 })
2527})
2528
2529test('preSerialization hooks should support encapsulation', t => {
2530 t.plan(9)
2531 const fastify = Fastify()
2532
2533 fastify.addHook('preSerialization', function (req, reply, payload, next) {
2534 payload.hello += '1'
2535
2536 next(null, payload)
2537 })
2538
2539 fastify.get('/first', (req, reply) => {
2540 reply.send({ hello: 'world' })
2541 })
2542
2543 fastify.register((instance, opts, next) => {
2544 instance.addHook('preSerialization', function (req, reply, payload, next) {
2545 payload.hello += '2'
2546
2547 next(null, payload)
2548 })
2549
2550 instance.get('/second', (req, reply) => {
2551 reply.send({ hello: 'world' })
2552 })
2553
2554 next()
2555 })
2556
2557 fastify.listen(0, err => {
2558 t.error(err)
2559 fastify.server.unref()
2560
2561 sget({
2562 method: 'GET',
2563 url: 'http://localhost:' + fastify.server.address().port + '/first'
2564 }, (err, response, body) => {
2565 t.error(err)
2566 t.strictEqual(response.statusCode, 200)
2567 t.strictEqual(response.headers['content-length'], '' + body.length)
2568 t.deepEqual(JSON.parse(body), { hello: 'world1' })
2569 })
2570
2571 sget({
2572 method: 'GET',
2573 url: 'http://localhost:' + fastify.server.address().port + '/second'
2574 }, (err, response, body) => {
2575 t.error(err)
2576 t.strictEqual(response.statusCode, 200)
2577 t.strictEqual(response.headers['content-length'], '' + body.length)
2578 t.deepEqual(JSON.parse(body), { hello: 'world12' })
2579 })
2580 })
2581})
2582
2583test('onRegister hook should be called / 1', t => {
2584 t.plan(3)
2585 const fastify = Fastify()
2586
2587 fastify.register((instance, opts, next) => {
2588 next()
2589 })
2590
2591 fastify.addHook('onRegister', instance => {
2592 // duck typing for the win!
2593 t.ok(instance.addHook)
2594 })
2595
2596 fastify.ready(err => {
2597 t.error(err)
2598 })
2599})
2600
2601test('onRegister hook should be called / 2', t => {
2602 t.plan(5)
2603 const fastify = Fastify()
2604
2605 fastify.register((instance, opts, next) => {
2606 instance.register((instance, opts, next) => {
2607 next()
2608 })
2609 next()
2610 })
2611
2612 fastify.register((instance, opts, next) => {
2613 next()
2614 })
2615
2616 fastify.addHook('onRegister', instance => {
2617 // duck typing for the win!
2618 t.ok(instance.addHook)
2619 })
2620
2621 fastify.ready(err => {
2622 t.error(err)
2623 })
2624})
2625
2626test('onRegister hook should be called / 3', t => {
2627 t.plan(4)
2628 const fastify = Fastify()
2629
2630 fastify.decorate('data', [])
2631
2632 fastify.register((instance, opts, next) => {
2633 instance.data.push(1)
2634 instance.register((instance, opts, next) => {
2635 instance.data.push(2)
2636 t.deepEqual(instance.data, [1, 2])
2637 next()
2638 })
2639 t.deepEqual(instance.data, [1])
2640 next()
2641 })
2642
2643 fastify.register((instance, opts, next) => {
2644 t.deepEqual(instance.data, [])
2645 next()
2646 })
2647
2648 fastify.addHook('onRegister', instance => {
2649 instance.data = instance.data.slice()
2650 })
2651
2652 fastify.ready(err => {
2653 t.error(err)
2654 })
2655})
2656
2657test('onRegister hook should be called / 4', t => {
2658 t.plan(2)
2659 const fastify = Fastify()
2660
2661 function plugin (instance, opts, next) {
2662 next()
2663 }
2664 plugin[Symbol.for('skip-override')] = true
2665
2666 fastify.register(plugin)
2667
2668 fastify.addHook('onRegister', instance => {
2669 // duck typing for the win!
2670 t.ok(instance.addHook)
2671 })
2672
2673 fastify.ready(err => {
2674 t.error(err)
2675 })
2676})
2677
2678if (semver.gt(process.versions.node, '8.0.0')) {
2679 require('./hooks-async')(t)
2680} else {
2681 t.pass('Skip because Node version < 8')
2682 t.end()
2683}