strong-tie/inbound-calls
0
1'use strict'2 3const { test } = require('node:test')4const handleRequest = require('../../lib/handleRequest')5const internals = require('../../lib/handleRequest')[Symbol.for('internals')]6const Request = require('../../lib/request')7const Reply = require('../../lib/reply')8const { kRouteContext } = require('../../lib/symbols')9const buildSchema = require('../../lib/validation').compileSchemasForValidation10const sget = require('simple-get').concat11 12const Ajv = require('ajv')13const ajv = new Ajv({ coerceTypes: true })14 15function schemaValidator ({ schema, method, url, httpPart }) {16 const validateFunction = ajv.compile(schema)17 const fn = function (body) {18 const isOk = validateFunction(body)19 if (isOk) return20 return false21 }22 fn.errors = []23 return fn24}25 26test('handleRequest function - sent reply', t => {27 t.plan(1)28 const request = {}29 const reply = { sent: true }30 const res = handleRequest(null, request, reply)31 t.assert.strictEqual(res, undefined)32})33 34test('handleRequest function - invoke with error', t => {35 t.plan(1)36 const request = {}37 const reply = {}38 reply.send = (err) => t.assert.strictEqual(err.message, 'Kaboom')39 handleRequest(new Error('Kaboom'), request, reply)40})41 42test('handler function - invalid schema', t => {43 t.plan(1)44 const res = {}45 res.log = { error: () => {}, info: () => {} }46 const context = {47 config: {48 method: 'GET',49 url: '/an-url'50 },51 schema: {52 body: {53 type: 'object',54 properties: {55 hello: { type: 'number' }56 }57 }58 },59 errorHandler: { func: () => { t.assert.ok('errorHandler called') } },60 handler: () => {},61 Reply,62 Request,63 preValidation: [],64 preHandler: [],65 onSend: [],66 onError: [],67 attachValidation: false,68 schemaErrorFormatter: () => new Error()69 }70 buildSchema(context, schemaValidator)71 const request = {72 body: { hello: 'world' },73 [kRouteContext]: context74 }75 internals.handler(request, new Reply(res, request))76})77 78test('handler function - reply', t => {79 t.plan(3)80 const res = {}81 res.end = () => {82 t.assert.strictEqual(res.statusCode, 204)83 t.assert.ok(true)84 }85 res.writeHead = () => {}86 const context = {87 handler: (req, reply) => {88 t.assert.strictEqual(typeof reply, 'object')89 reply.code(204)90 reply.send(undefined)91 },92 Reply,93 Request,94 preValidation: [],95 preHandler: [],96 onSend: [],97 onError: [],98 config: {99 url: '',100 method: ''101 }102 }103 buildSchema(context, schemaValidator)104 internals.handler({ [kRouteContext]: context }, new Reply(res, { [kRouteContext]: context }))105})106 107test('handler function - preValidationCallback with finished response', t => {108 t.plan(0)109 const res = {}110 // Be sure to check only `writableEnded` where is available111 res.writableEnded = true112 res.end = () => {113 t.assert.fail()114 }115 res.writeHead = () => {}116 const context = {117 handler: (req, reply) => {118 t.assert.fail()119 reply.send(undefined)120 },121 Reply,122 Request,123 preValidation: null,124 preHandler: [],125 onSend: [],126 onError: []127 }128 buildSchema(context, schemaValidator)129 internals.handler({ [kRouteContext]: context }, new Reply(res, { [kRouteContext]: context }))130})131 132test('request should be defined in onSend Hook on post request with content type application/json', (t, done) => {133 t.plan(8)134 const fastify = require('../..')()135 136 t.after(() => {137 fastify.close()138 })139 140 fastify.addHook('onSend', (request, reply, payload, done) => {141 t.assert.ok(request)142 t.assert.ok(request.raw)143 t.assert.ok(request.id)144 t.assert.ok(request.params)145 t.assert.ok(request.query)146 done()147 })148 fastify.post('/', (request, reply) => {149 reply.send(200)150 })151 152 fastify.listen({ port: 0 }, err => {153 t.assert.ifError(err)154 sget({155 method: 'POST',156 url: 'http://localhost:' + fastify.server.address().port,157 headers: {158 'content-type': 'application/json'159 }160 }, (err, response, body) => {161 t.assert.ifError(err)162 // a 400 error is expected because of no body163 t.assert.strictEqual(response.statusCode, 400)164 done()165 })166 })167})168 169test('request should be defined in onSend Hook on post request with content type application/x-www-form-urlencoded', (t, done) => {170 t.plan(7)171 const fastify = require('../..')()172 173 t.after(() => { fastify.close() })174 175 fastify.addHook('onSend', (request, reply, payload, done) => {176 t.assert.ok(request)177 t.assert.ok(request.raw)178 t.assert.ok(request.params)179 t.assert.ok(request.query)180 done()181 })182 fastify.post('/', (request, reply) => {183 reply.send(200)184 })185 186 fastify.listen({ port: 0 }, err => {187 t.assert.ifError(err)188 189 sget({190 method: 'POST',191 url: 'http://localhost:' + fastify.server.address().port,192 headers: {193 'content-type': 'application/x-www-form-urlencoded'194 }195 }, (err, response, body) => {196 t.assert.ifError(err)197 // a 415 error is expected because of missing content type parser198 t.assert.strictEqual(response.statusCode, 415)199 done()200 })201 })202})203 204test('request should be defined in onSend Hook on options request with content type application/x-www-form-urlencoded', (t, done) => {205 t.plan(7)206 const fastify = require('../..')()207 208 t.after(() => { fastify.close() })209 210 fastify.addHook('onSend', (request, reply, payload, done) => {211 t.assert.ok(request)212 t.assert.ok(request.raw)213 t.assert.ok(request.params)214 t.assert.ok(request.query)215 done()216 })217 fastify.options('/', (request, reply) => {218 reply.send(200)219 })220 221 fastify.listen({ port: 0 }, err => {222 t.assert.ifError(err)223 224 sget({225 method: 'OPTIONS',226 url: 'http://localhost:' + fastify.server.address().port,227 headers: {228 'content-type': 'application/x-www-form-urlencoded'229 }230 }, (err, response, body) => {231 t.assert.ifError(err)232 // Body parsing skipped, so no body sent233 t.assert.strictEqual(response.statusCode, 200)234 done()235 })236 })237})238 239test('request should respond with an error if an unserialized payload is sent inside an async handler', (t, done) => {240 t.plan(3)241 242 const fastify = require('../..')()243 244 fastify.get('/', (request, reply) => {245 reply.type('text/html')246 return Promise.resolve(request.headers)247 })248 249 fastify.inject({250 method: 'GET',251 url: '/'252 }, (err, res) => {253 t.assert.ifError(err)254 t.assert.strictEqual(res.statusCode, 500)255 t.assert.deepStrictEqual(JSON.parse(res.payload), {256 error: 'Internal Server Error',257 code: 'FST_ERR_REP_INVALID_PAYLOAD_TYPE',258 message: 'Attempted to send payload of invalid type \'object\'. Expected a string or Buffer.',259 statusCode: 500260 })261 done()262 })263})264 