CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
helper.js455 linesDownload Raw Back to test
1'use strict'2 3const sget = require('simple-get').concat4const dns = require('node:dns').promises5const stream = require('node:stream')6const { promisify } = require('node:util')7const symbols = require('../lib/symbols')8 9module.exports.sleep = promisify(setTimeout)10 11/**12 * @param method HTTP request method13 * @param t tap instance14 * @param isSetErrorHandler true: using setErrorHandler15 */16module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {17  const test = t.test18  const fastify = require('..')()19 20  if (isSetErrorHandler) {21    fastify.setErrorHandler(function (err, request, reply) {22      t.type(request, 'object')23      t.type(request, fastify[symbols.kRequest].parent)24      reply25        .code(err.statusCode)26        .type('application/json; charset=utf-8')27        .send(err)28    })29  }30 31  const upMethod = method.toUpperCase()32  const loMethod = method.toLowerCase()33 34  const schema = {35    schema: {36      response: {37        '2xx': {38          type: 'object',39          properties: {40            hello: {41              type: 'string'42            }43          }44        }45      }46    }47  }48 49  test(`${upMethod} can be created`, t => {50    t.plan(1)51    try {52      fastify[loMethod]('/', schema, function (req, reply) {53        reply.code(200).send(req.body)54      })55      t.pass()56    } catch (e) {57      t.fail()58    }59  })60 61  test(`${upMethod} without schema can be created`, t => {62    t.plan(1)63    try {64      fastify[loMethod]('/missing', function (req, reply) {65        reply.code(200).send(req.body)66      })67      t.pass()68    } catch (e) {69      t.fail()70    }71  })72 73  test(`${upMethod} with body and querystring`, t => {74    t.plan(1)75    try {76      fastify[loMethod]('/with-query', function (req, reply) {77        req.body.hello = req.body.hello + req.query.foo78        reply.code(200).send(req.body)79      })80      t.pass()81    } catch (e) {82      t.fail()83    }84  })85 86  test(`${upMethod} with bodyLimit option`, t => {87    t.plan(1)88    try {89      fastify[loMethod]('/with-limit', { bodyLimit: 1 }, function (req, reply) {90        reply.send(req.body)91      })92      t.pass()93    } catch (e) {94      t.fail()95    }96  })97 98  fastify.listen({ port: 0 }, function (err) {99    if (err) {100      t.error(err)101      return102    }103 104    t.teardown(() => { fastify.close() })105 106    test(`${upMethod} - correctly replies`, t => {107      t.plan(3)108      sget({109        method: upMethod,110        url: 'http://localhost:' + fastify.server.address().port,111        body: {112          hello: 'world'113        },114        json: true115      }, (err, response, body) => {116        t.error(err)117        t.equal(response.statusCode, 200)118        t.same(body, { hello: 'world' })119      })120    })121 122    test(`${upMethod} - correctly replies with very large body`, t => {123      t.plan(3)124 125      const largeString = 'world'.repeat(13200)126      sget({127        method: upMethod,128        url: 'http://localhost:' + fastify.server.address().port,129        body: { hello: largeString },130        json: true131      }, (err, response, body) => {132        t.error(err)133        t.equal(response.statusCode, 200)134        t.same(body, { hello: largeString })135      })136    })137 138    test(`${upMethod} - correctly replies if the content type has the charset`, t => {139      t.plan(3)140      sget({141        method: upMethod,142        url: 'http://localhost:' + fastify.server.address().port,143        body: JSON.stringify({ hello: 'world' }),144        headers: {145          'content-type': 'application/json; charset=utf-8'146        }147      }, (err, response, body) => {148        t.error(err)149        t.equal(response.statusCode, 200)150        t.same(body.toString(), JSON.stringify({ hello: 'world' }))151      })152    })153 154    test(`${upMethod} without schema - correctly replies`, t => {155      t.plan(3)156      sget({157        method: upMethod,158        url: 'http://localhost:' + fastify.server.address().port + '/missing',159        body: {160          hello: 'world'161        },162        json: true163      }, (err, response, body) => {164        t.error(err)165        t.equal(response.statusCode, 200)166        t.same(body, { hello: 'world' })167      })168    })169 170    test(`${upMethod} with body and querystring - correctly replies`, t => {171      t.plan(3)172      sget({173        method: upMethod,174        url: 'http://localhost:' + fastify.server.address().port + '/with-query?foo=hello',175        body: {176          hello: 'world'177        },178        json: true179      }, (err, response, body) => {180        t.error(err)181        t.equal(response.statusCode, 200)182        t.same(body, { hello: 'worldhello' })183      })184    })185 186    test(`${upMethod} with no body - correctly replies`, t => {187      t.plan(6)188 189      sget({190        method: upMethod,191        url: 'http://localhost:' + fastify.server.address().port + '/missing',192        headers: { 'Content-Length': '0' }193      }, (err, response, body) => {194        t.error(err)195        t.equal(response.statusCode, 200)196        t.equal(body.toString(), '')197      })198 199      // Must use inject to make a request without a Content-Length header200      fastify.inject({201        method: upMethod,202        url: '/missing'203      }, (err, res) => {204        t.error(err)205        t.equal(res.statusCode, 200)206        t.equal(res.payload.toString(), '')207      })208    })209 210    test(`${upMethod} returns 415 - incorrect media type if body is not json`, t => {211      t.plan(2)212      sget({213        method: upMethod,214        url: 'http://localhost:' + fastify.server.address().port + '/missing',215        body: 'hello world'216 217      }, (err, response, body) => {218        t.error(err)219        t.equal(response.statusCode, 415)220      })221    })222 223    if (loMethod === 'options') {224      test('OPTIONS returns 415 - should return 415 if Content-Type is not json or plain text', t => {225        t.plan(2)226        sget({227          method: upMethod,228          url: 'http://localhost:' + fastify.server.address().port + '/missing',229          body: 'hello world',230          headers: {231            'Content-Type': 'text/xml'232          }233        }, (err, response, body) => {234          t.error(err)235          t.equal(response.statusCode, 415)236        })237      })238    }239 240    test(`${upMethod} returns 400 - Bad Request`, t => {241      t.plan(4)242 243      sget({244        method: upMethod,245        url: 'http://localhost:' + fastify.server.address().port,246        body: 'hello world',247        headers: {248          'Content-Type': 'application/json'249        }250      }, (err, response, body) => {251        t.error(err)252        t.equal(response.statusCode, 400)253      })254 255      sget({256        method: upMethod,257        url: 'http://localhost:' + fastify.server.address().port,258        headers: {259          'Content-Type': 'application/json',260          'Content-Length': '0'261        }262      }, (err, response, body) => {263        t.error(err)264        t.equal(response.statusCode, 400)265      })266    })267 268    test(`${upMethod} returns 413 - Payload Too Large`, t => {269      t.plan(upMethod === 'OPTIONS' ? 4 : 6)270 271      sget({272        method: upMethod,273        url: 'http://localhost:' + fastify.server.address().port,274        headers: {275          'Content-Type': 'application/json',276          'Content-Length': 1024 * 1024 + 1277        }278      }, (err, response, body) => {279        t.error(err)280        t.equal(response.statusCode, 413)281      })282 283      // Node errors for OPTIONS requests with a stream body and no Content-Length header284      if (upMethod !== 'OPTIONS') {285        let chunk = Buffer.alloc(1024 * 1024 + 1, 0)286        const largeStream = new stream.Readable({287          read () {288            this.push(chunk)289            chunk = null290          }291        })292        sget({293          method: upMethod,294          url: 'http://localhost:' + fastify.server.address().port,295          headers: { 'Content-Type': 'application/json' },296          body: largeStream297        }, (err, response, body) => {298          t.error(err)299          t.equal(response.statusCode, 413)300        })301      }302 303      sget({304        method: upMethod,305        url: `http://localhost:${fastify.server.address().port}/with-limit`,306        headers: { 'Content-Type': 'application/json' },307        body: {},308        json: true309      }, (err, response, body) => {310        t.error(err)311        t.equal(response.statusCode, 413)312      })313    })314 315    test(`${upMethod} should fail with empty body and application/json content-type`, t => {316      if (upMethod === 'OPTIONS') return t.end()317 318      t.plan(12)319 320      fastify.inject({321        method: `${upMethod}`,322        url: '/',323        headers: {324          'Content-Type': 'application/json'325        }326      }, (err, res) => {327        t.error(err)328        t.same(JSON.parse(res.payload), {329          error: 'Bad Request',330          code: 'FST_ERR_CTP_EMPTY_JSON_BODY',331          message: 'Body cannot be empty when content-type is set to \'application/json\'',332          statusCode: 400333        })334      })335 336      sget({337        method: upMethod,338        url: `http://localhost:${fastify.server.address().port}`,339        headers: {340          'Content-Type': 'application/json'341        }342      }, (err, res, body) => {343        t.error(err)344        t.same(JSON.parse(body.toString()), {345          error: 'Bad Request',346          code: 'FST_ERR_CTP_EMPTY_JSON_BODY',347          message: 'Body cannot be empty when content-type is set to \'application/json\'',348          statusCode: 400349        })350      })351 352      fastify.inject({353        method: `${upMethod}`,354        url: '/',355        headers: {356          'Content-Type': 'application/json'357        },358        payload: null359      }, (err, res) => {360        t.error(err)361        t.same(JSON.parse(res.payload), {362          error: 'Bad Request',363          code: 'FST_ERR_CTP_EMPTY_JSON_BODY',364          message: 'Body cannot be empty when content-type is set to \'application/json\'',365          statusCode: 400366        })367      })368 369      sget({370        method: upMethod,371        url: `http://localhost:${fastify.server.address().port}`,372        headers: {373          'Content-Type': 'application/json'374        },375        payload: null376      }, (err, res, body) => {377        t.error(err)378        t.same(JSON.parse(body.toString()), {379          error: 'Bad Request',380          code: 'FST_ERR_CTP_EMPTY_JSON_BODY',381          message: 'Body cannot be empty when content-type is set to \'application/json\'',382          statusCode: 400383        })384      })385 386      fastify.inject({387        method: `${upMethod}`,388        url: '/',389        headers: {390          'Content-Type': 'application/json'391        },392        payload: undefined393      }, (err, res) => {394        t.error(err)395        t.same(JSON.parse(res.payload), {396          error: 'Bad Request',397          code: 'FST_ERR_CTP_EMPTY_JSON_BODY',398          message: 'Body cannot be empty when content-type is set to \'application/json\'',399          statusCode: 400400        })401      })402 403      sget({404        method: upMethod,405        url: `http://localhost:${fastify.server.address().port}`,406        headers: {407          'Content-Type': 'application/json'408        },409        payload: undefined410      }, (err, res, body) => {411        t.error(err)412        t.same(JSON.parse(body.toString()), {413          error: 'Bad Request',414          code: 'FST_ERR_CTP_EMPTY_JSON_BODY',415          message: 'Body cannot be empty when content-type is set to \'application/json\'',416          statusCode: 400417        })418      })419    })420  })421}422 423function lookupToIp (lookup) {424  return lookup.family === 6 ? `[${lookup.address}]` : lookup.address425}426 427module.exports.getLoopbackHost = async () => {428  const lookup = await dns.lookup('localhost')429  return [lookup.address, lookupToIp(lookup)]430}431 432module.exports.plainTextParser = function (request, callback) {433  let body = ''434  request.setEncoding('utf8')435  request.on('error', onError)436  request.on('data', onData)437  request.on('end', onEnd)438  function onError (err) {439    callback(err, null)440  }441  function onData (chunk) {442    body += chunk443  }444  function onEnd () {445    callback(null, body)446  }447}448 449module.exports.getServerUrl = function (app) {450  const { address, port } = app.server.address()451  return address === '::1'452    ? `http://[${address}]:${port}`453    : `http://${address}:${port}`454}455