Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: migrate to node:test with c8 #161

Merged
merged 5 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .taprc

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"codecov": "codecov",
"lint": "standard | snazzy",
"test": "npm run test:unit && npm run test:typescript",
"test:unit": "tap",
"test:unit": "c8 --100 node --test",
"test:typescript": "tsd"
},
"precommit": [
Expand Down Expand Up @@ -37,7 +37,7 @@
"qs": "^6.12.0",
"snazzy": "^9.0.0",
"standard": "^17.1.0",
"tap": "^18.7.1",
"c8": "^10.1.2",
"tsd": "^0.31.0"
},
"dependencies": {
Expand Down
191 changes: 97 additions & 94 deletions test/integration.test.js
Original file line number Diff line number Diff line change
@@ -1,168 +1,170 @@
'use strict'

const tap = require('tap')
const test = tap.test
const test = require('node:test')
const Fastify = require('fastify')
const plugin = require('../')
const qs = require('qs')
const formAutoContent = require('form-auto-content')

test('succes route succeeds', (t) => {
t.plan(3)
test('success route succeeds', async (t) => {
const fastify = Fastify()

fastify.register(plugin)
await fastify.register(plugin)
fastify.post('/test1', (req, res) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

fastify.inject({ path: '/test1', method: 'POST', ...formAutoContent({ foo: 'foo' }) }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 200)
t.same(JSON.parse(response.body), { foo: 'foo', message: 'done' })
})
const response = await fastify.inject({
path: '/test1',
method: 'POST',
...formAutoContent({ foo: 'foo' })
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 200)
t.assert.deepStrictEqual(JSON.parse(response.body), { foo: 'foo', message: 'done' })
})

test('cannot exceed body limit', (t) => {
t.plan(3)
test('cannot exceed body limit', async (t) => {
const fastify = Fastify()

fastify.register(plugin, { bodyLimit: 10 })
await fastify.register(plugin, { bodyLimit: 10 })
fastify.post('/limited', (req, res) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

const payload = require('node:crypto').randomBytes(128).toString('hex')
fastify.inject({ path: '/limited', method: 'POST', ...formAutoContent({ foo: payload }) }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 413)
t.equal(JSON.parse(response.body).message, 'Request body is too large')
})
const payload = require('node:crypto').randomBytes(128).toString('hex')
const response = await fastify.inject({
path: '/limited',
method: 'POST',
...formAutoContent({ foo: payload })
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 413)
t.assert.strictEqual(JSON.parse(response.body).message, 'Request body is too large')
})

test('cannot exceed body limit when Content-Length is not available', (t) => {
t.plan(3)
test('cannot exceed body limit when Content-Length is not available', async (t) => {
const fastify = Fastify()

fastify.addHook('onSend', (request, reply, payload, next) => {
reply.send = function mockSend (arg) {
t.fail('reply.send() was called multiple times')
t.assert.fail('reply.send() was called multiple times')
}
setTimeout(next, 1)
})

fastify.register(plugin, { bodyLimit: 10 })
await fastify.register(plugin, { bodyLimit: 10 })
fastify.post('/limited', (req, res) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

let sent = false
const payload = require('node:stream').Readable({
read: function () {
this.push(sent ? null : Buffer.alloc(70000, 'a'))
sent = true
}
})
fastify.inject({ path: '/limited', method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: payload }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 413)
t.equal(JSON.parse(response.body).message, 'Request body is too large')
})
let sent = false
const payload = require('node:stream').Readable({
read: function () {
this.push(sent ? null : Buffer.alloc(70000, 'a'))
sent = true
}
})

const response = await fastify.inject({
path: '/limited',
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: payload
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 413)
t.assert.strictEqual(JSON.parse(response.body).message, 'Request body is too large')
})

test('cannot exceed body limit set on Fastify instance', (t) => {
t.plan(3)
test('cannot exceed body limit set on Fastify instance', async (t) => {
const fastify = Fastify({ bodyLimit: 10 })

fastify.register(plugin)
await fastify.register(plugin)
fastify.post('/limited', (req, res) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

const payload = require('node:crypto').randomBytes(128).toString('hex')
fastify.inject({ path: '/limited', method: 'POST', ...formAutoContent({ foo: payload }) }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 413)
t.equal(JSON.parse(response.body).message, 'Request body is too large')
})
const payload = require('node:crypto').randomBytes(128).toString('hex')
const response = await fastify.inject({
path: '/limited',
method: 'POST',
...formAutoContent({ foo: payload })
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 413)
t.assert.strictEqual(JSON.parse(response.body).message, 'Request body is too large')
})

test('plugin bodyLimit should overwrite Fastify instance bodyLimit', (t) => {
t.plan(3)
test('plugin bodyLimit should overwrite Fastify instance bodyLimit', async (t) => {
const fastify = Fastify({ bodyLimit: 100000 })

fastify.register(plugin, { bodyLimit: 10 })
fastify.post('/limited', (req, res) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

const payload = require('node:crypto').randomBytes(128).toString('hex')
fastify.inject({ path: '/limited', method: 'POST', ...formAutoContent({ foo: payload }) }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 413)
t.equal(JSON.parse(response.body).message, 'Request body is too large')
})
const payload = require('node:crypto').randomBytes(128).toString('hex')
const response = await fastify.inject({
path: '/limited',
method: 'POST',
...formAutoContent({ foo: payload })
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 413)
t.assert.strictEqual(JSON.parse(response.body).message, 'Request body is too large')
})

test('plugin should throw if opts.parser is not a function', (t) => {
t.plan(2)
test('plugin should throw if opts.parser is not a function', async (t) => {
const fastify = Fastify()
fastify.register(plugin, { parser: 'invalid' })
fastify.listen({ port: 0 }, (err) => {
t.ok(err)
t.match(err.message, /parser must be a function/)
try {
await fastify.register(plugin, { parser: 'invalid' })
await fastify.listen({ port: 0 })
} catch (err) {
t.assert.ok(err)
t.assert.match(err.message, /parser must be a function/)
} finally {
fastify.server.unref()
})
}
})

test('plugin should not parse nested objects by default', (t) => {
t.plan(3)
test('plugin should not parse nested objects by default', async (t) => {
const fastify = Fastify()

fastify.register(plugin)
fastify.post('/test1', (req, res) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

fastify.inject({ path: '/test1', method: 'POST', ...formAutoContent({ 'foo[one]': 'foo', 'foo[two]': 'bar' }) }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 200)
t.same(JSON.parse(response.body), { 'foo[one]': 'foo', 'foo[two]': 'bar', message: 'done' })
})
const response = await fastify.inject({
path: '/test1',
method: 'POST',
...formAutoContent({ 'foo[one]': 'foo', 'foo[two]': 'bar' })
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 200)
t.assert.deepStrictEqual(JSON.parse(response.body), { 'foo[one]': 'foo', 'foo[two]': 'bar', message: 'done' })
})

test('plugin should allow providing custom parser as option', (t) => {
t.plan(3)
test('plugin should allow providing custom parser as option', async (t) => {
const fastify = Fastify()

// this makes sure existing users for <= 4 have upgrade path
Expand All @@ -171,14 +173,15 @@ test('plugin should allow providing custom parser as option', (t) => {
res.send(Object.assign({}, req.body, { message: 'done' }))
})

fastify.listen({ port: 0 }, (err) => {
if (err) tap.error(err)
fastify.server.unref()
await fastify.listen({ port: 0 })
fastify.server.unref()

fastify.inject({ path: '/test1', method: 'POST', ...formAutoContent({ 'foo[one]': 'foo', 'foo[two]': 'bar' }) }, (err, response) => {
t.error(err)
t.equal(response.statusCode, 200)
t.same(JSON.parse(response.body), { foo: { one: 'foo', two: 'bar' }, message: 'done' })
})
const response = await fastify.inject({
path: '/test1',
method: 'POST',
...formAutoContent({ 'foo[one]': 'foo', 'foo[two]': 'bar' })
})
t.assert.ifError(response.error)
t.assert.strictEqual(response.statusCode, 200)
t.assert.deepStrictEqual(JSON.parse(response.body), { foo: { one: 'foo', two: 'bar' }, message: 'done' })
})