strong-tie/inbound-calls
0
1'use strict'2 3const { test } = require('node:test')4const sget = require('simple-get').concat5const Fastify = require('..')6const {7 FST_ERR_INVALID_URL8} = require('../lib/errors')9const { getServerUrl } = require('./helper')10 11test('Request and Reply share the route options', async t => {12 t.plan(3)13 14 const fastify = Fastify()15 16 const config = {17 this: 'is a string',18 thisIs: function aFunction () {}19 }20 21 fastify.route({22 method: 'GET',23 url: '/',24 config,25 handler: (req, reply) => {26 t.assert.deepStrictEqual(req.routeOptions, reply.routeOptions)27 t.assert.deepStrictEqual(req.routeOptions.config, reply.routeOptions.config)28 t.assert.match(req.routeOptions.config, config, 'there are url and method additional properties')29 30 reply.send({ hello: 'world' })31 }32 })33 34 await fastify.inject('/')35})36 37test('Will not try to re-createprefixed HEAD route if it already exists and exposeHeadRoutes is true', async (t) => {38 t.plan(1)39 40 const fastify = Fastify({ exposeHeadRoutes: true })41 42 fastify.register((scope, opts, next) => {43 scope.route({44 method: 'HEAD',45 path: '/route',46 handler: (req, reply) => {47 reply.header('content-type', 'text/plain')48 reply.send('custom HEAD response')49 }50 })51 scope.route({52 method: 'GET',53 path: '/route',54 handler: (req, reply) => {55 reply.send({ ok: true })56 }57 })58 59 next()60 }, { prefix: '/prefix' })61 62 await fastify.ready()63 64 t.assert.ok(true)65})66 67test('route with non-english characters', (t, done) => {68 t.plan(4)69 70 const fastify = Fastify()71 72 fastify.get('/föö', (request, reply) => {73 reply.send('here /föö')74 })75 76 fastify.listen({ port: 0 }, err => {77 t.assert.ifError(err)78 t.after(() => fastify.close())79 80 sget({81 method: 'GET',82 url: getServerUrl(fastify) + encodeURI('/föö')83 }, (err, response, body) => {84 t.assert.ifError(err)85 t.assert.strictEqual(response.statusCode, 200)86 t.assert.strictEqual(body.toString(), 'here /föö')87 done()88 })89 })90})91 92test('invalid url attribute - non string URL', t => {93 t.plan(1)94 const fastify = Fastify()95 96 try {97 fastify.get(/^\/(donations|skills|blogs)/, () => { })98 } catch (error) {99 t.assert.strictEqual(error.code, FST_ERR_INVALID_URL().code)100 }101})102 103test('exposeHeadRoute should not reuse the same route option', async t => {104 t.plan(2)105 106 const fastify = Fastify()107 108 // we update the onRequest hook in onRoute hook109 // if we reuse the same route option110 // that means we will append another function inside the array111 fastify.addHook('onRoute', function (routeOption) {112 if (Array.isArray(routeOption.onRequest)) {113 routeOption.onRequest.push(() => {})114 } else {115 routeOption.onRequest = [() => {}]116 }117 })118 119 fastify.addHook('onRoute', function (routeOption) {120 t.assert.strictEqual(routeOption.onRequest.length, 1)121 })122 123 fastify.route({124 method: 'GET',125 path: '/more-coffee',126 async handler () {127 return 'hello world'128 }129 })130})131 132test('using fastify.all when a catchall is defined does not degrade performance', { timeout: 30000 }, async t => {133 t.plan(1)134 135 const fastify = Fastify()136 137 fastify.get('/*', async (_, reply) => reply.json({ ok: true }))138 139 for (let i = 0; i < 100; i++) {140 fastify.all(`/${i}`, async (_, reply) => reply.json({ ok: true }))141 }142 143 t.assert.ok("fastify.all doesn't degrade performance")144})145 146test('Adding manually HEAD route after GET with the same path throws Fastify duplicated route instance error', t => {147 t.plan(1)148 149 const fastify = Fastify()150 151 fastify.route({152 method: 'GET',153 path: '/:param1',154 handler: (req, reply) => {155 reply.send({ hello: 'world' })156 }157 })158 159 try {160 fastify.route({161 method: 'HEAD',162 path: '/:param2',163 handler: (req, reply) => {164 reply.send({ hello: 'world' })165 }166 })167 t.assert.fail('Should throw fastify duplicated route declaration')168 } catch (error) {169 t.assert.strictEqual(error.code, 'FST_ERR_DUPLICATED_ROUTE')170 }171})172 173test('Will pass onSend hook to HEAD method if exposeHeadRoutes is true /1', async (t) => {174 t.plan(1)175 176 const fastify = Fastify({ exposeHeadRoutes: true })177 178 await fastify.register((scope, opts, next) => {179 scope.route({180 method: 'GET',181 path: '/route',182 handler: (req, reply) => {183 reply.send({ ok: true })184 },185 onSend: (req, reply, payload, done) => {186 reply.header('x-content-type', 'application/fastify')187 done(null, payload)188 }189 })190 191 next()192 }, { prefix: '/prefix' })193 194 await fastify.ready()195 196 const result = await fastify.inject({197 url: '/prefix/route',198 method: 'HEAD'199 })200 201 t.assert.strictEqual(result.headers['x-content-type'], 'application/fastify')202})203 204test('Will pass onSend hook to HEAD method if exposeHeadRoutes is true /2', async (t) => {205 t.plan(1)206 207 const fastify = Fastify({ exposeHeadRoutes: true })208 209 await fastify.register((scope, opts, next) => {210 scope.route({211 method: 'get',212 path: '/route',213 handler: (req, reply) => {214 reply.send({ ok: true })215 },216 onSend: (req, reply, payload, done) => {217 reply.header('x-content-type', 'application/fastify')218 done(null, payload)219 }220 })221 222 next()223 }, { prefix: '/prefix' })224 225 await fastify.ready()226 227 const result = await fastify.inject({228 url: '/prefix/route',229 method: 'HEAD'230 })231 232 t.assert.strictEqual(result.headers['x-content-type'], 'application/fastify')233})234 