CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
stream.test.js360 linesDownload Raw Back to test
1'use strict'2 3const t = require('node:test')4const fs = require('node:fs')5const test = t.test6const zlib = require('node:zlib')7const express = require('express')8 9const inject = require('../index')10 11function accumulate (stream, cb) {12  const chunks = []13  stream.on('error', cb)14  stream.on('data', (chunk) => {15    chunks.push(chunk)16  })17  stream.on('end', () => {18    cb(null, Buffer.concat(chunks))19  })20}21 22test('stream mode - non-chunked payload', (t, done) => {23  t.plan(9)24  const output = 'example.com:8080|/hello'25 26  const dispatch = function (req, res) {27    res.statusMessage = 'Super'28    res.setHeader('x-extra', 'hello')29    res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': output.length })30    res.end(req.headers.host + '|' + req.url)31  }32 33  inject(dispatch, {34    url: 'http://example.com:8080/hello',35    payloadAsStream: true36  }, (err, res) => {37    t.assert.ifError(err)38    t.assert.strictEqual(res.statusCode, 200)39    t.assert.strictEqual(res.statusMessage, 'Super')40    t.assert.ok(res.headers.date)41    t.assert.deepStrictEqual(res.headers, {42      date: res.headers.date,43      connection: 'keep-alive',44      'x-extra': 'hello',45      'content-type': 'text/plain',46      'content-length': output.length.toString()47    })48    t.assert.strictEqual(res.payload, undefined)49    t.assert.strictEqual(res.rawPayload, undefined)50 51    accumulate(res.stream(), (err, payload) => {52      t.assert.ifError(err)53      t.assert.strictEqual(payload.toString(), 'example.com:8080|/hello')54      done()55    })56  })57})58 59test('stream mode - passes headers', (t, done) => {60  t.plan(3)61  const dispatch = function (req, res) {62    res.writeHead(200, { 'Content-Type': 'text/plain' })63    res.end(req.headers.super)64  }65 66  inject(dispatch, {67    method: 'GET',68    url: 'http://example.com:8080/hello',69    headers: { Super: 'duper' },70    payloadAsStream: true71  }, (err, res) => {72    t.assert.ifError(err)73    accumulate(res.stream(), (err, payload) => {74      t.assert.ifError(err)75      t.assert.strictEqual(payload.toString(), 'duper')76      done()77    })78  })79})80 81test('stream mode - returns chunked payload', (t, done) => {82  t.plan(6)83  const dispatch = function (_req, res) {84    res.writeHead(200, 'OK')85    res.write('a')86    res.write('b')87    res.end()88  }89 90  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {91    t.assert.ifError(err)92    t.assert.ok(res.headers.date)93    t.assert.ok(res.headers.connection)94    t.assert.strictEqual(res.headers['transfer-encoding'], 'chunked')95    accumulate(res.stream(), (err, payload) => {96      t.assert.ifError(err)97      t.assert.strictEqual(payload.toString(), 'ab')98      done()99    })100  })101})102 103test('stream mode - backpressure', (t, done) => {104  t.plan(7)105  let expected106  const dispatch = function (_req, res) {107    res.writeHead(200, 'OK')108    res.write('a')109    const buf = Buffer.alloc(1024 * 1024).fill('b')110    t.assert.strictEqual(res.write(buf), false)111    expected = 'a' + buf.toString()112    res.on('drain', () => {113      res.end()114    })115  }116 117  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {118    t.assert.ifError(err)119    t.assert.ok(res.headers.date)120    t.assert.ok(res.headers.connection)121    t.assert.strictEqual(res.headers['transfer-encoding'], 'chunked')122    accumulate(res.stream(), (err, payload) => {123      t.assert.ifError(err)124      t.assert.strictEqual(payload.toString(), expected)125      done()126    })127  })128})129 130test('stream mode - sets trailers in response object', (t, done) => {131  t.plan(4)132  const dispatch = function (_req, res) {133    res.setHeader('Trailer', 'Test')134    res.addTrailers({ Test: 123 })135    res.end()136  }137 138  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {139    t.assert.ifError(err)140    t.assert.strictEqual(res.headers.trailer, 'Test')141    t.assert.strictEqual(res.headers.test, undefined)142    t.assert.strictEqual(res.trailers.test, '123')143    done()144  })145})146 147test('stream mode - parses zipped payload', (t, done) => {148  t.plan(5)149  const dispatch = function (_req, res) {150    res.writeHead(200, 'OK')151    const stream = fs.createReadStream('./package.json')152    stream.pipe(zlib.createGzip()).pipe(res)153  }154 155  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {156    t.assert.ifError(err)157    fs.readFile('./package.json', { encoding: 'utf-8' }, (err, file) => {158      t.assert.ifError(err)159 160      accumulate(res.stream(), (err, payload) => {161        t.assert.ifError(err)162 163        zlib.unzip(payload, (err, unzipped) => {164          t.assert.ifError(err)165          t.assert.strictEqual(unzipped.toString('utf-8'), file)166          done()167        })168      })169    })170  })171})172 173test('stream mode - returns multi buffer payload', (t, done) => {174  t.plan(3)175  const dispatch = function (_req, res) {176    res.writeHead(200)177    res.write('a')178    res.write(Buffer.from('b'))179    res.end()180  }181 182  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {183    t.assert.ifError(err)184 185    const chunks = []186    const stream = res.stream()187    stream.on('data', (chunk) => {188      chunks.push(chunk)189    })190 191    stream.on('end', () => {192      t.assert.strictEqual(chunks.length, 2)193      t.assert.strictEqual(Buffer.concat(chunks).toString(), 'ab')194      done()195    })196  })197})198 199test('stream mode - returns null payload', (t, done) => {200  t.plan(4)201  const dispatch = function (_req, res) {202    res.writeHead(200, { 'Content-Length': 0 })203    res.end()204  }205 206  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {207    t.assert.ifError(err)208    t.assert.strictEqual(res.payload, undefined)209    accumulate(res.stream(), (err, payload) => {210      t.assert.ifError(err)211      t.assert.strictEqual(payload.toString(), '')212      done()213    })214  })215})216 217test('stream mode - simulates error', (t, done) => {218  t.plan(3)219  const dispatch = function (req, res) {220    req.on('readable', () => {221    })222 223    req.on('error', () => {224      res.writeHead(200, { 'Content-Length': 0 })225      res.end('error')226    })227  }228 229  const body = 'something special just for you'230  inject(dispatch, { method: 'GET', url: '/', payload: body, simulate: { error: true }, payloadAsStream: true }, (err, res) => {231    t.assert.ifError(err)232    accumulate(res.stream(), (err, payload) => {233      t.assert.ifError(err)234      t.assert.strictEqual(payload.toString(), 'error')235      done()236    })237  })238})239 240test('stream mode - promises support', (t, done) => {241  t.plan(1)242  const dispatch = function (_req, res) {243    res.writeHead(200, { 'Content-Type': 'text/plain' })244    res.end('hello')245  }246 247  inject(dispatch, { method: 'GET', url: 'http://example.com:8080/hello', payloadAsStream: true })248    .then((res) => {249      return new Promise((resolve, reject) => {250        accumulate(res.stream(), (err, payload) => {251          if (err) {252            return reject(err)253          }254          resolve(payload)255        })256      })257    })258    .then(payload => t.assert.strictEqual(payload.toString(), 'hello'))259    .catch(t.assert.fail)260    .finally(done)261})262 263test('stream mode - Response.json() should throw', (t, done) => {264  t.plan(2)265 266  const jsonData = {267    a: 1,268    b: '2'269  }270 271  const dispatch = function (_req, res) {272    res.writeHead(200, { 'Content-Type': 'application/json' })273    res.end(JSON.stringify(jsonData))274  }275 276  inject(dispatch, { method: 'GET', path: 'http://example.com:8080/hello', payloadAsStream: true }, (err, res) => {277    t.assert.ifError(err)278    const { json } = res279    t.assert.throws(json, Error)280    done()281  })282})283 284test('stream mode - error for response destroy', (t, done) => {285  t.plan(2)286 287  const dispatch = function (_req, res) {288    res.writeHead(200)289    setImmediate(() => {290      res.destroy()291    })292  }293 294  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {295    t.assert.ifError(err)296    accumulate(res.stream(), (err) => {297      t.assert.ok(err)298      done()299    })300  })301})302 303test('stream mode - request destroy with error', (t, done) => {304  t.plan(3)305 306  const fakeError = new Error('some-err')307 308  const dispatch = function (req) {309    req.destroy(fakeError)310  }311 312  inject(dispatch, { method: 'GET', url: '/', payloadAsStream: true }, (err, res) => {313    t.assert.ok(err)314    t.assert.strictEqual(err, fakeError)315    t.assert.strictEqual(res, null)316    done()317  })318})319 320test('stream mode - Can abort a request using AbortController/AbortSignal', async (t) => {321  const dispatch = function (_req, res) {322    res.writeHead(200)323  }324 325  const controller = new AbortController()326  const res = await inject(dispatch, {327    method: 'GET',328    url: 'http://example.com:8080/hello',329    signal: controller.signal,330    payloadAsStream: true331  })332  controller.abort()333 334  await t.assert.rejects(async () => {335    for await (const c of res.stream()) {336      t.assert.fail(`should not loop, got ${c.toString()}`)337    }338  }, Error)339}, { skip: globalThis.AbortController == null })340 341test("stream mode - passes payload when using express' send", (t, done) => {342  t.plan(4)343 344  const app = express()345 346  app.get('/hello', (_req, res) => {347    res.send('some text')348  })349 350  inject(app, { method: 'GET', url: 'http://example.com:8080/hello', payloadAsStream: true }, (err, res) => {351    t.assert.ifError(err)352    t.assert.strictEqual(res.headers['content-length'], '9')353    accumulate(res.stream(), function (err, payload) {354      t.assert.ifError(err)355      t.assert.strictEqual(payload.toString(), 'some text')356      done()357    })358  })359})360