strong-tie/inbound-calls
0
1'use strict'2 3const { Readable } = require('node:stream')4const t = require('tap')5const test = t.test6const sget = require('simple-get').concat7const Fastify = require('../fastify')8const fs = require('node:fs')9const { sleep } = require('./helper')10 11process.removeAllListeners('warning')12 13test('async hooks', t => {14 t.plan(21)15 16 const fastify = Fastify({ exposeHeadRoutes: false })17 fastify.addHook('onRequest', async function (request, reply) {18 await sleep(1)19 request.test = 'the request is coming'20 reply.test = 'the reply has come'21 if (request.raw.method === 'DELETE') {22 throw new Error('some error')23 }24 })25 26 fastify.addHook('preHandler', async function (request, reply) {27 await sleep(1)28 t.equal(request.test, 'the request is coming')29 t.equal(reply.test, 'the reply has come')30 if (request.raw.method === 'HEAD') {31 throw new Error('some error')32 }33 })34 35 fastify.addHook('onSend', async function (request, reply, payload) {36 await sleep(1)37 t.ok('onSend called')38 })39 40 fastify.addHook('onResponse', async function (request, reply) {41 await sleep(1)42 t.ok('onResponse called')43 })44 45 fastify.get('/', function (request, reply) {46 t.equal(request.test, 'the request is coming')47 t.equal(reply.test, 'the reply has come')48 reply.code(200).send({ hello: 'world' })49 })50 51 fastify.head('/', function (req, reply) {52 reply.code(200).send({ hello: 'world' })53 })54 55 fastify.delete('/', function (req, reply) {56 reply.code(200).send({ hello: 'world' })57 })58 59 fastify.listen({ port: 0 }, err => {60 t.error(err)61 t.teardown(() => { fastify.close() })62 63 sget({64 method: 'GET',65 url: 'http://localhost:' + fastify.server.address().port66 }, (err, response, body) => {67 t.error(err)68 t.equal(response.statusCode, 200)69 t.equal(response.headers['content-length'], '' + body.length)70 t.same(JSON.parse(body), { hello: 'world' })71 })72 73 sget({74 method: 'HEAD',75 url: 'http://localhost:' + fastify.server.address().port76 }, (err, response, body) => {77 t.error(err)78 t.equal(response.statusCode, 500)79 })80 81 sget({82 method: 'DELETE',83 url: 'http://localhost:' + fastify.server.address().port84 }, (err, response, body) => {85 t.error(err)86 t.equal(response.statusCode, 500)87 })88 })89})90 91test('modify payload', t => {92 t.plan(10)93 const fastify = Fastify()94 const payload = { hello: 'world' }95 const modifiedPayload = { hello: 'modified' }96 const anotherPayload = '"winter is coming"'97 98 fastify.addHook('onSend', async function (request, reply, thePayload) {99 t.ok('onSend called')100 t.same(JSON.parse(thePayload), payload)101 return thePayload.replace('world', 'modified')102 })103 104 fastify.addHook('onSend', async function (request, reply, thePayload) {105 t.ok('onSend called')106 t.same(JSON.parse(thePayload), modifiedPayload)107 return anotherPayload108 })109 110 fastify.addHook('onSend', async function (request, reply, thePayload) {111 t.ok('onSend called')112 t.equal(thePayload, anotherPayload)113 })114 115 fastify.get('/', (req, reply) => {116 reply.send(payload)117 })118 119 fastify.inject({120 method: 'GET',121 url: '/'122 }, (err, res) => {123 t.error(err)124 t.equal(res.payload, anotherPayload)125 t.equal(res.statusCode, 200)126 t.equal(res.headers['content-length'], '18')127 })128})129 130test('onRequest hooks should be able to block a request', t => {131 t.plan(5)132 const fastify = Fastify()133 134 fastify.addHook('onRequest', async (req, reply) => {135 await reply.send('hello')136 })137 138 fastify.addHook('onRequest', async (req, reply) => {139 t.fail('this should not be called')140 })141 142 fastify.addHook('preHandler', async (req, reply) => {143 t.fail('this should not be called')144 })145 146 fastify.addHook('onSend', async (req, reply, payload) => {147 t.ok('called')148 })149 150 fastify.addHook('onResponse', async (request, reply) => {151 t.ok('called')152 })153 154 fastify.get('/', function (request, reply) {155 t.fail('we should not be here')156 })157 158 fastify.inject({159 url: '/',160 method: 'GET'161 }, (err, res) => {162 t.error(err)163 t.equal(res.statusCode, 200)164 t.equal(res.payload, 'hello')165 })166})167 168test('preParsing hooks should be able to modify the payload', t => {169 t.plan(3)170 const fastify = Fastify()171 172 fastify.addHook('preParsing', async (req, reply, payload) => {173 const stream = new Readable()174 175 stream.receivedEncodedLength = parseInt(req.headers['content-length'], 10)176 stream.push(JSON.stringify({ hello: 'another world' }))177 stream.push(null)178 179 return stream180 })181 182 fastify.post('/', function (request, reply) {183 reply.send(request.body)184 })185 186 fastify.inject({187 method: 'POST',188 url: '/',189 payload: { hello: 'world' }190 }, (err, res) => {191 t.error(err)192 t.equal(res.statusCode, 200)193 t.same(JSON.parse(res.payload), { hello: 'another world' })194 })195})196 197test('preParsing hooks should be able to supply statusCode', t => {198 t.plan(4)199 const fastify = Fastify()200 201 fastify.addHook('preParsing', async (req, reply, payload) => {202 const stream = new Readable({203 read () {204 const error = new Error('kaboom')205 error.statusCode = 408206 this.destroy(error)207 }208 })209 stream.receivedEncodedLength = 20210 return stream211 })212 213 fastify.addHook('onError', async (req, res, err) => {214 t.equal(err.statusCode, 408)215 })216 217 fastify.post('/', function (request, reply) {218 t.fail('should not be called')219 })220 221 fastify.inject({222 method: 'POST',223 url: '/',224 payload: { hello: 'world' }225 }, (err, res) => {226 t.error(err)227 t.equal(res.statusCode, 408)228 t.same(JSON.parse(res.payload), {229 statusCode: 408,230 error: 'Request Timeout',231 message: 'kaboom'232 })233 })234})235 236test('preParsing hooks should ignore statusCode 200 in stream error', t => {237 t.plan(4)238 const fastify = Fastify()239 240 fastify.addHook('preParsing', async (req, reply, payload) => {241 const stream = new Readable({242 read () {243 const error = new Error('kaboom')244 error.statusCode = 200245 this.destroy(error)246 }247 })248 stream.receivedEncodedLength = 20249 return stream250 })251 252 fastify.addHook('onError', async (req, res, err) => {253 t.equal(err.statusCode, 400)254 })255 256 fastify.post('/', function (request, reply) {257 t.fail('should not be called')258 })259 260 fastify.inject({261 method: 'POST',262 url: '/',263 payload: { hello: 'world' }264 }, (err, res) => {265 t.error(err)266 t.equal(res.statusCode, 400)267 t.same(JSON.parse(res.payload), {268 statusCode: 400,269 error: 'Bad Request',270 message: 'kaboom'271 })272 })273})274 275test('preParsing hooks should ignore non-number statusCode in stream error', t => {276 t.plan(4)277 const fastify = Fastify()278 279 fastify.addHook('preParsing', async (req, reply, payload) => {280 const stream = new Readable({281 read () {282 const error = new Error('kaboom')283 error.statusCode = '418'284 this.destroy(error)285 }286 })287 stream.receivedEncodedLength = 20288 return stream289 })290 291 fastify.addHook('onError', async (req, res, err) => {292 t.equal(err.statusCode, 400)293 })294 295 fastify.post('/', function (request, reply) {296 t.fail('should not be called')297 })298 299 fastify.inject({300 method: 'POST',301 url: '/',302 payload: { hello: 'world' }303 }, (err, res) => {304 t.error(err)305 t.equal(res.statusCode, 400)306 t.same(JSON.parse(res.payload), {307 statusCode: 400,308 error: 'Bad Request',309 message: 'kaboom'310 })311 })312})313 314test('preParsing hooks should default to statusCode 400 if stream error', t => {315 t.plan(4)316 const fastify = Fastify()317 318 fastify.addHook('preParsing', async (req, reply, payload) => {319 const stream = new Readable({320 read () {321 this.destroy(new Error('kaboom'))322 }323 })324 stream.receivedEncodedLength = 20325 return stream326 })327 328 fastify.addHook('onError', async (req, res, err) => {329 t.equal(err.statusCode, 400)330 })331 332 fastify.post('/', function (request, reply) {333 t.fail('should not be called')334 })335 336 fastify.inject({337 method: 'POST',338 url: '/',339 payload: { hello: 'world' }340 }, (err, res) => {341 t.error(err)342 t.equal(res.statusCode, 400)343 t.same(JSON.parse(res.payload), {344 statusCode: 400,345 error: 'Bad Request',346 message: 'kaboom'347 })348 })349})350 351test('preParsing hooks should handle errors', t => {352 t.plan(3)353 const fastify = Fastify()354 355 fastify.addHook('preParsing', async (req, reply, payload) => {356 const e = new Error('kaboom')357 e.statusCode = 501358 throw e359 })360 361 fastify.post('/', function (request, reply) {362 reply.send(request.body)363 })364 365 fastify.inject({366 method: 'POST',367 url: '/',368 payload: { hello: 'world' }369 }, (err, res) => {370 t.error(err)371 t.equal(res.statusCode, 501)372 t.same(JSON.parse(res.payload), { error: 'Not Implemented', message: 'kaboom', statusCode: 501 })373 })374})375 376test('preHandler hooks should be able to block a request', t => {377 t.plan(5)378 const fastify = Fastify()379 380 fastify.addHook('preHandler', async (req, reply) => {381 await reply.send('hello')382 })383 384 fastify.addHook('preHandler', async (req, reply) => {385 t.fail('this should not be called')386 })387 388 fastify.addHook('onSend', async (req, reply, payload) => {389 t.equal(payload, 'hello')390 })391 392 fastify.addHook('onResponse', async (request, reply) => {393 t.ok('called')394 })395 396 fastify.get('/', function (request, reply) {397 t.fail('we should not be here')398 })399 400 fastify.inject({401 url: '/',402 method: 'GET'403 }, (err, res) => {404 t.error(err)405 t.equal(res.statusCode, 200)406 t.equal(res.payload, 'hello')407 })408})409 410test('preValidation hooks should be able to block a request', t => {411 t.plan(5)412 const fastify = Fastify()413 414 fastify.addHook('preValidation', async (req, reply) => {415 await reply.send('hello')416 })417 418 fastify.addHook('preValidation', async (req, reply) => {419 t.fail('this should not be called')420 })421 422 fastify.addHook('onSend', async (req, reply, payload) => {423 t.equal(payload, 'hello')424 })425 426 fastify.addHook('onResponse', async (request, reply) => {427 t.ok('called')428 })429 430 fastify.get('/', function (request, reply) {431 t.fail('we should not be here')432 })433 434 fastify.inject({435 url: '/',436 method: 'GET'437 }, (err, res) => {438 t.error(err)439 t.equal(res.statusCode, 200)440 t.equal(res.payload, 'hello')441 })442})443 444test('preValidation hooks should be able to change request body before validation', t => {445 t.plan(4)446 const fastify = Fastify()447 448 fastify.addHook('preValidation', async (req, _reply) => {449 const buff = Buffer.from(req.body.message, 'base64')450 req.body = JSON.parse(buff.toString('utf-8'))451 })452 453 fastify.post(454 '/',455 {456 schema: {457 body: {458 type: 'object',459 properties: {460 foo: {461 type: 'string'462 },463 bar: {464 type: 'number'465 }466 },467 required: ['foo', 'bar']468 }469 }470 },471 (req, reply) => {472 t.pass()473 reply.status(200).send('hello')474 }475 )476 477 fastify.inject({478 url: '/',479 method: 'POST',480 payload: {481 message: Buffer.from(JSON.stringify({ foo: 'example', bar: 1 })).toString('base64')482 }483 }, (err, res) => {484 t.error(err)485 t.equal(res.statusCode, 200)486 t.equal(res.payload, 'hello')487 })488})489 490test('preSerialization hooks should be able to modify the payload', t => {491 t.plan(3)492 const fastify = Fastify()493 494 fastify.addHook('preSerialization', async (req, reply, payload) => {495 return { hello: 'another world' }496 })497 498 fastify.get('/', function (request, reply) {499 reply.send({ hello: 'world' })500 })501 502 fastify.inject({503 url: '/',504 method: 'GET'505 }, (err, res) => {506 t.error(err)507 t.equal(res.statusCode, 200)508 t.same(JSON.parse(res.payload), { hello: 'another world' })509 })510})511 512test('preSerialization hooks should handle errors', t => {513 t.plan(3)514 const fastify = Fastify()515 516 fastify.addHook('preSerialization', async (req, reply, payload) => {517 throw new Error('kaboom')518 })519 520 fastify.get('/', function (request, reply) {521 reply.send({ hello: 'world' })522 })523 524 fastify.inject({525 url: '/',526 method: 'GET'527 }, (err, res) => {528 t.error(err)529 t.equal(res.statusCode, 500)530 t.same(JSON.parse(res.payload), { error: 'Internal Server Error', message: 'kaboom', statusCode: 500 })531 })532})533 534test('preValidation hooks should handle throwing null', t => {535 t.plan(4)536 const fastify = Fastify()537 538 fastify.setErrorHandler(async (error, request, reply) => {539 t.ok(error instanceof Error)540 await reply.send(error)541 })542 543 fastify.addHook('preValidation', async () => {544 // eslint-disable-next-line no-throw-literal545 throw null546 })547 548 fastify.get('/', function (request, reply) { t.fail('the handler must not be called') })549 550 fastify.inject({551 url: '/',552 method: 'GET'553 }, (err, res) => {554 t.error(err)555 t.equal(res.statusCode, 500)556 t.same(res.json(), {557 error: 'Internal Server Error',558 code: 'FST_ERR_SEND_UNDEFINED_ERR',559 message: 'Undefined error has occurred',560 statusCode: 500561 })562 })563})564 565test('preValidation hooks should handle throwing a string', t => {566 t.plan(3)567 const fastify = Fastify()568 569 fastify.addHook('preValidation', async () => {570 // eslint-disable-next-line no-throw-literal571 throw 'this is an error'572 })573 574 fastify.get('/', function (request, reply) { t.fail('the handler must not be called') })575 576 fastify.inject({577 url: '/',578 method: 'GET'579 }, (err, res) => {580 t.error(err)581 t.equal(res.statusCode, 500)582 t.equal(res.payload, 'this is an error')583 })584})585 586test('onRequest hooks should be able to block a request (last hook)', t => {587 t.plan(5)588 const fastify = Fastify()589 590 fastify.addHook('onRequest', async (req, reply) => {591 await reply.send('hello')592 })593 594 fastify.addHook('preHandler', async (req, reply) => {595 t.fail('this should not be called')596 })597 598 fastify.addHook('onSend', async (req, reply, payload) => {599 t.ok('called')600 })601 602 fastify.addHook('onResponse', async (request, reply) => {603 t.ok('called')604 })605 606 fastify.get('/', function (request, reply) {607 t.fail('we should not be here')608 })609 610 fastify.inject({611 url: '/',612 method: 'GET'613 }, (err, res) => {614 t.error(err)615 t.equal(res.statusCode, 200)616 t.equal(res.payload, 'hello')617 })618})619 620test('preHandler hooks should be able to block a request (last hook)', t => {621 t.plan(5)622 const fastify = Fastify()623 624 fastify.addHook('preHandler', async (req, reply) => {625 await reply.send('hello')626 })627 628 fastify.addHook('onSend', async (req, reply, payload) => {629 t.equal(payload, 'hello')630 })631 632 fastify.addHook('onResponse', async (request, reply) => {633 t.ok('called')634 })635 636 fastify.get('/', function (request, reply) {637 t.fail('we should not be here')638 })639 640 fastify.inject({641 url: '/',642 method: 'GET'643 }, (err, res) => {644 t.error(err)645 t.equal(res.statusCode, 200)646 t.equal(res.payload, 'hello')647 })648})649 650test('onRequest respond with a stream', t => {651 t.plan(4)652 const fastify = Fastify()653 654 fastify.addHook('onRequest', async (req, reply) => {655 return new Promise((resolve, reject) => {656 const stream = fs.createReadStream(__filename, 'utf8')657 // stream.pipe(res)658 // res.once('finish', resolve)659 reply.send(stream).then(() => {660 reply.raw.once('finish', () => resolve())661 })662 })663 })664 665 fastify.addHook('onRequest', async (req, res) => {666 t.fail('this should not be called')667 })668 669 fastify.addHook('preHandler', async (req, reply) => {670 t.fail('this should not be called')671 })672 673 fastify.addHook('onSend', async (req, reply, payload) => {674 t.ok('called')675 })676 677 fastify.addHook('onResponse', async (request, reply) => {678 t.ok('called')679 })680 681 fastify.get('/', function (request, reply) {682 t.fail('we should not be here')683 })684 685 fastify.inject({686 url: '/',687 method: 'GET'688 }, (err, res) => {689 t.error(err)690 t.equal(res.statusCode, 200)691 })692})693 694test('preHandler respond with a stream', t => {695 t.plan(7)696 const fastify = Fastify()697 698 fastify.addHook('onRequest', async (req, res) => {699 t.ok('called')700 })701 702 // we are calling `reply.send` inside the `preHandler` hook with a stream,703 // this triggers the `onSend` hook event if `preHandler` has not yet finished704 const order = [1, 2]705 706 fastify.addHook('preHandler', async (req, reply) => {707 const stream = fs.createReadStream(__filename, 'utf8')708 reply.raw.once('finish', () => {709 t.equal(order.shift(), 2)710 })711 return reply.send(stream)712 })713 714 fastify.addHook('preHandler', async (req, reply) => {715 t.fail('this should not be called')716 })717 718 fastify.addHook('onSend', async (req, reply, payload) => {719 t.equal(order.shift(), 1)720 t.equal(typeof payload.pipe, 'function')721 })722 723 fastify.addHook('onResponse', async (request, reply) => {724 t.ok('called')725 })726 727 fastify.get('/', function (request, reply) {728 t.fail('we should not be here')729 })730 731 fastify.inject({732 url: '/',733 method: 'GET'734 }, (err, res) => {735 t.error(err)736 t.equal(res.statusCode, 200)737 })738})739 740test('Should log a warning if is an async function with `done`', t => {741 t.test('2 arguments', t => {742 t.plan(2)743 const fastify = Fastify()744 745 try {746 fastify.addHook('onRequestAbort', async (req, done) => {})747 } catch (e) {748 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')749 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')750 }751 })752 753 t.test('3 arguments', t => {754 t.plan(2)755 const fastify = Fastify()756 757 try {758 fastify.addHook('onRequest', async (req, reply, done) => {})759 } catch (e) {760 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')761 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')762 }763 })764 765 t.test('4 arguments', t => {766 t.plan(6)767 const fastify = Fastify()768 769 try {770 fastify.addHook('onSend', async (req, reply, payload, done) => {})771 } catch (e) {772 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')773 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')774 }775 try {776 fastify.addHook('preSerialization', async (req, reply, payload, done) => {})777 } catch (e) {778 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')779 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')780 }781 try {782 fastify.addHook('onError', async (req, reply, payload, done) => {})783 } catch (e) {784 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')785 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')786 }787 })788 789 t.end()790})791 792test('early termination, onRequest async', async t => {793 t.plan(2)794 795 const app = Fastify()796 797 app.addHook('onRequest', async (req, reply) => {798 setImmediate(() => reply.send('hello world'))799 return reply800 })801 802 app.get('/', (req, reply) => {803 t.fail('should not happen')804 })805 806 const res = await app.inject('/')807 t.equal(res.statusCode, 200)808 t.equal(res.body.toString(), 'hello world')809})810 811test('The this should be the same of the encapsulation level', async t => {812 const fastify = Fastify()813 814 fastify.addHook('onRequest', async function (req, reply) {815 if (req.raw.url === '/nested') {816 t.equal(this.foo, 'bar')817 } else {818 t.equal(this.foo, undefined)819 }820 })821 822 fastify.register(plugin)823 fastify.get('/', (req, reply) => reply.send('ok'))824 825 async function plugin (fastify, opts) {826 fastify.decorate('foo', 'bar')827 fastify.get('/nested', (req, reply) => reply.send('ok'))828 }829 830 await fastify.inject({ method: 'GET', path: '/' })831 await fastify.inject({ method: 'GET', path: '/nested' })832 await fastify.inject({ method: 'GET', path: '/' })833 await fastify.inject({ method: 'GET', path: '/nested' })834})835 836test('preSerializationEnd should handle errors if the serialize method throws', t => {837 t.test('works with sync preSerialization', t => {838 t.plan(2)839 const fastify = Fastify()840 841 fastify.addHook('preSerialization', (request, reply, payload, done) => {842 done(null, payload)843 })844 845 fastify.post('/', {846 handler (req, reply) { reply.send({ notOk: true }) },847 schema: { response: { 200: { required: ['ok'], properties: { ok: { type: 'boolean' } } } } }848 })849 850 fastify.inject({851 method: 'POST',852 url: '/'853 }, (err, res) => {854 t.error(err)855 t.not(res.statusCode, 200)856 })857 })858 859 t.test('works with async preSerialization', t => {860 t.plan(2)861 const fastify = Fastify()862 863 fastify.addHook('preSerialization', async (request, reply, payload) => {864 return payload865 })866 867 fastify.post('/', {868 handler (req, reply) { reply.send({ notOk: true }) },869 schema: { response: { 200: { required: ['ok'], properties: { ok: { type: 'boolean' } } } } }870 })871 872 fastify.inject({873 method: 'POST',874 url: '/'875 }, (err, res) => {876 t.error(err)877 t.not(res.statusCode, 200)878 })879 })880 881 t.end()882})883 884t.test('nested hooks to do not crash on 404', t => {885 t.plan(2)886 const fastify = Fastify()887 888 fastify.get('/hello', (req, reply) => {889 reply.send({ hello: 'world' })890 })891 892 fastify.register(async function (fastify) {893 fastify.get('/something', (req, reply) => {894 reply.callNotFound()895 })896 897 fastify.setNotFoundHandler(async (request, reply) => {898 reply.statusCode = 404899 return { status: 'nested-not-found' }900 })901 902 fastify.setErrorHandler(async (error, request, reply) => {903 reply.statusCode = 500904 return { status: 'nested-error', error }905 })906 }, { prefix: '/nested' })907 908 fastify.setNotFoundHandler(async (request, reply) => {909 reply.statusCode = 404910 return { status: 'not-found' }911 })912 913 fastify.setErrorHandler(async (error, request, reply) => {914 reply.statusCode = 500915 return { status: 'error', error }916 })917 918 fastify.inject({919 method: 'GET',920 url: '/nested/something'921 }, (err, res) => {922 t.error(err)923 t.equal(res.statusCode, 404)924 })925})926 927test('Register an hook (preHandler) as route option should fail if mixing async and callback style', t => {928 t.plan(2)929 const fastify = Fastify()930 931 try {932 fastify.get(933 '/',934 {935 preHandler: [936 async (request, reply, done) => {937 done()938 }939 ]940 },941 async (request, reply) => {942 return { hello: 'world' }943 }944 )945 t.fail('preHandler mixing async and callback style')946 } catch (e) {947 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')948 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')949 }950})951 952test('Register an hook (onSend) as route option should fail if mixing async and callback style', t => {953 t.plan(2)954 const fastify = Fastify()955 956 try {957 fastify.get(958 '/',959 {960 onSend: [961 async (request, reply, payload, done) => {962 done()963 }964 ]965 },966 async (request, reply) => {967 return { hello: 'world' }968 }969 )970 t.fail('onSend mixing async and callback style')971 } catch (e) {972 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')973 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')974 }975})976 977test('Register an hook (preSerialization) as route option should fail if mixing async and callback style', t => {978 t.plan(2)979 const fastify = Fastify()980 981 try {982 fastify.get(983 '/',984 {985 preSerialization: [986 async (request, reply, payload, done) => {987 done()988 }989 ]990 },991 async (request, reply) => {992 return { hello: 'world' }993 }994 )995 t.fail('preSerialization mixing async and callback style')996 } catch (e) {997 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')998 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')999 }1000})1001 1002test('Register an hook (onError) as route option should fail if mixing async and callback style', t => {1003 t.plan(2)1004 const fastify = Fastify()1005 1006 try {1007 fastify.get(1008 '/',1009 {1010 onError: [1011 async (request, reply, error, done) => {1012 done()1013 }1014 ]1015 },1016 async (request, reply) => {1017 return { hello: 'world' }1018 }1019 )1020 t.fail('onError mixing async and callback style')1021 } catch (e) {1022 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')1023 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')1024 }1025})1026 1027test('Register an hook (preParsing) as route option should fail if mixing async and callback style', t => {1028 t.plan(2)1029 const fastify = Fastify()1030 1031 try {1032 fastify.get(1033 '/',1034 {1035 preParsing: [1036 async (request, reply, payload, done) => {1037 done()1038 }1039 ]1040 },1041 async (request, reply) => {1042 return { hello: 'world' }1043 }1044 )1045 t.fail('preParsing mixing async and callback style')1046 } catch (e) {1047 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')1048 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')1049 }1050})1051 1052test('Register an hook (onRequestAbort) as route option should fail if mixing async and callback style', t => {1053 t.plan(2)1054 const fastify = Fastify()1055 1056 try {1057 fastify.get(1058 '/',1059 {1060 onRequestAbort: [1061 async (request, done) => {1062 done()1063 }1064 ]1065 },1066 async (request, reply) => {1067 return { hello: 'world' }1068 }1069 )1070 t.fail('onRequestAbort mixing async and callback style')1071 } catch (e) {1072 t.equal(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')1073 t.equal(e.message, 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')1074 }1075})1076 