CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
handle-request.test.js264 linesDownload Raw Back to internals
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