1966
node_modules/fastify/test/404s.test.js
generated
vendored
1966
node_modules/fastify/test/404s.test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
231
node_modules/fastify/test/500s.test.js
generated
vendored
231
node_modules/fastify/test/500s.test.js
generated
vendored
@@ -1,231 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const symbols = require('../lib/symbols.js')
|
||||
|
||||
test('default 500', (t, done) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 500)
|
||||
t.assert.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8')
|
||||
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
||||
error: 'Internal Server Error',
|
||||
message: 'kaboom',
|
||||
statusCode: 500
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('custom 500', (t, done) => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(function (err, request, reply) {
|
||||
t.assert.ok(typeof request === 'object')
|
||||
t.assert.ok(request instanceof fastify[symbols.kRequest].parent)
|
||||
reply
|
||||
.code(500)
|
||||
.type('text/plain')
|
||||
.send('an error happened: ' + err.message)
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 500)
|
||||
t.assert.strictEqual(res.headers['content-type'], 'text/plain')
|
||||
t.assert.deepStrictEqual(res.payload.toString(), 'an error happened: kaboom')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('encapsulated 500', async t => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
fastify.register(function (f, opts, done) {
|
||||
f.get('/', function (req, reply) {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
f.setErrorHandler(function (err, request, reply) {
|
||||
t.assert.ok(typeof request === 'object')
|
||||
t.assert.ok(request instanceof fastify[symbols.kRequest].parent)
|
||||
reply
|
||||
.code(500)
|
||||
.type('text/plain')
|
||||
.send('an error happened: ' + err.message)
|
||||
})
|
||||
|
||||
done()
|
||||
}, { prefix: 'test' })
|
||||
|
||||
{
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/test'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 500)
|
||||
t.assert.strictEqual(response.headers['content-type'], 'text/plain')
|
||||
t.assert.deepStrictEqual(response.payload.toString(), 'an error happened: kaboom')
|
||||
}
|
||||
|
||||
{
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 500)
|
||||
t.assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload), {
|
||||
error: 'Internal Server Error',
|
||||
message: 'kaboom',
|
||||
statusCode: 500
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('custom 500 with hooks', (t, done) => {
|
||||
t.plan(7)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(function (err, request, reply) {
|
||||
reply
|
||||
.code(500)
|
||||
.type('text/plain')
|
||||
.send('an error happened: ' + err.message)
|
||||
})
|
||||
|
||||
fastify.addHook('onSend', (req, res, payload, done) => {
|
||||
t.assert.ok('called', 'onSend')
|
||||
done()
|
||||
})
|
||||
fastify.addHook('onRequest', (req, res, done) => {
|
||||
t.assert.ok('called', 'onRequest')
|
||||
done()
|
||||
})
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.assert.ok('called', 'onResponse')
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 500)
|
||||
t.assert.strictEqual(res.headers['content-type'], 'text/plain')
|
||||
t.assert.deepStrictEqual(res.payload.toString(), 'an error happened: kaboom')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('cannot set errorHandler after binding', (t, done) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
try {
|
||||
fastify.setErrorHandler(() => { })
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.ok(true)
|
||||
} finally {
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('cannot set childLoggerFactory after binding', (t, done) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
try {
|
||||
fastify.setChildLoggerFactory(() => { })
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.ok(true)
|
||||
} finally {
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('catch synchronous errors', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.setErrorHandler((_, req, reply) => {
|
||||
throw new Error('kaboom2')
|
||||
})
|
||||
|
||||
fastify.post('/', function (req, reply) {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
payload: JSON.stringify({ hello: 'world' }).substring(0, 5)
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 500)
|
||||
t.assert.deepStrictEqual(res.json(), {
|
||||
error: 'Internal Server Error',
|
||||
message: 'kaboom2',
|
||||
statusCode: 500
|
||||
})
|
||||
done()
|
||||
})
|
||||
})
|
||||
92
node_modules/fastify/test/allow-unsafe-regex.test.js
generated
vendored
92
node_modules/fastify/test/allow-unsafe-regex.test.js
generated
vendored
@@ -1,92 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('allow unsafe regex', async t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify({
|
||||
allowUnsafeRegex: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/:foo(^[0-9]*$)', (req, reply) => {
|
||||
reply.send({ foo: req.params.foo })
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/1234`)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { foo: '1234' })
|
||||
})
|
||||
|
||||
test('allow unsafe regex not match', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify({
|
||||
allowUnsafeRegex: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/:foo(^[0-9]*$)', (req, reply) => {
|
||||
reply.send({ foo: req.params.foo })
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/a1234`)
|
||||
t.assert.strictEqual(result.status, 404)
|
||||
})
|
||||
|
||||
test('allow unsafe regex not safe', (t, done) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify({
|
||||
allowUnsafeRegex: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
t.assert.throws(() => {
|
||||
fastify.get('/:foo(^([0-9]+){4}$)', (req, reply) => {
|
||||
reply.send({ foo: req.params.foo })
|
||||
})
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
test('allow unsafe regex not safe by default', (t, done) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
t.assert.throws(() => {
|
||||
fastify.get('/:foo(^([0-9]+){4}$)', (req, reply) => {
|
||||
reply.send({ foo: req.params.foo })
|
||||
})
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
test('allow unsafe regex allow unsafe', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify({
|
||||
allowUnsafeRegex: true
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
t.assert.doesNotThrow(() => {
|
||||
fastify.get('/:foo(^([0-9]+){4}$)', (req, reply) => {
|
||||
reply.send({ foo: req.params.foo })
|
||||
})
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/1234`)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { foo: '1234' })
|
||||
})
|
||||
65
node_modules/fastify/test/als.test.js
generated
vendored
65
node_modules/fastify/test/als.test.js
generated
vendored
@@ -1,65 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { AsyncLocalStorage } = require('node:async_hooks')
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('Async Local Storage test', async (t) => {
|
||||
t.plan(12)
|
||||
if (!AsyncLocalStorage) {
|
||||
t.skip('AsyncLocalStorage not available, skipping test')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const storage = new AsyncLocalStorage()
|
||||
const app = Fastify({ logger: false })
|
||||
|
||||
t.after(() => app.close())
|
||||
|
||||
let counter = 0
|
||||
app.addHook('onRequest', (req, reply, next) => {
|
||||
const id = counter++
|
||||
storage.run({ id }, next)
|
||||
})
|
||||
|
||||
app.get('/', function (request, reply) {
|
||||
t.assert.ok(storage.getStore())
|
||||
const id = storage.getStore().id
|
||||
reply.send({ id })
|
||||
})
|
||||
|
||||
app.post('/', function (request, reply) {
|
||||
t.assert.ok(storage.getStore())
|
||||
const id = storage.getStore().id
|
||||
reply.send({ id })
|
||||
})
|
||||
|
||||
const fastifyServer = await app.listen({ port: 0 })
|
||||
|
||||
// First POST request
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.deepStrictEqual(await result1.json(), { id: 0 })
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.deepStrictEqual(await result2.json(), { id: 1 })
|
||||
|
||||
// GET request
|
||||
const result3 = await fetch(fastifyServer, {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(result3.ok)
|
||||
t.assert.strictEqual(result3.status, 200)
|
||||
t.assert.deepStrictEqual(await result3.json(), { id: 2 })
|
||||
})
|
||||
705
node_modules/fastify/test/async-await.test.js
generated
vendored
705
node_modules/fastify/test/async-await.test.js
generated
vendored
@@ -1,705 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const split = require('split2')
|
||||
const pino = require('pino')
|
||||
const { sleep } = require('./helper')
|
||||
const statusCodes = require('node:http').STATUS_CODES
|
||||
|
||||
const opts = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const optsWithHostnameAndPort = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
},
|
||||
hostname: {
|
||||
type: 'string'
|
||||
},
|
||||
port: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
test('async await', async t => {
|
||||
t.plan(15)
|
||||
const fastify = Fastify()
|
||||
try {
|
||||
fastify.get('/', opts, async function awaitMyFunc (req, reply) {
|
||||
await sleep(200)
|
||||
return { hello: 'world' }
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
|
||||
try {
|
||||
fastify.get('/no-await', opts, async function (req, reply) {
|
||||
return { hello: 'world' }
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
|
||||
try {
|
||||
fastify.get('/await/hostname_port', optsWithHostnameAndPort, async function awaitMyFunc (req, reply) {
|
||||
await sleep(200)
|
||||
return { hello: 'world', hostname: req.hostname, port: req.port }
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
const body = await result.text()
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
|
||||
const result1 = await fetch(`${fastifyServer}/no-await`)
|
||||
|
||||
const body1 = await result1.text()
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.strictEqual(result1.headers.get('content-length'), '' + body1.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body1), { hello: 'world' })
|
||||
|
||||
const result2 = await fetch(`http://localhost:${fastify.server.address().port}/await/hostname_port`)
|
||||
|
||||
const parsedBody = await result2.json()
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.strictEqual(parsedBody.hostname, 'localhost')
|
||||
t.assert.strictEqual(parseInt(parsedBody.port), fastify.server.address().port)
|
||||
})
|
||||
|
||||
test('ignore the result of the promise if reply.send is called beforehand (undefined)', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = Fastify()
|
||||
const payload = { hello: 'world' }
|
||||
|
||||
server.get('/', async function awaitMyFunc (req, reply) {
|
||||
await reply.send(payload)
|
||||
})
|
||||
|
||||
t.after(() => { server.close() })
|
||||
|
||||
const fastifyServer = await server.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.deepStrictEqual(payload, await result.json())
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('ignore the result of the promise if reply.send is called beforehand (object)', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = Fastify()
|
||||
const payload = { hello: 'world2' }
|
||||
|
||||
server.get('/', async function awaitMyFunc (req, reply) {
|
||||
await reply.send(payload)
|
||||
return { hello: 'world' }
|
||||
})
|
||||
|
||||
t.after(() => { server.close() })
|
||||
|
||||
const fastifyServer = await server.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.deepStrictEqual(payload, await result.json())
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('server logs an error if reply.send is called and a value is returned via async/await', (t, done) => {
|
||||
const lines = ['incoming request', 'request completed', 'Reply was already sent, did you forget to "return reply" in "/" (GET)?']
|
||||
t.plan(lines.length + 2)
|
||||
|
||||
const splitStream = split(JSON.parse)
|
||||
splitStream.on('data', (line) => {
|
||||
t.assert.strictEqual(line.msg, lines.shift())
|
||||
})
|
||||
|
||||
const logger = pino(splitStream)
|
||||
|
||||
const fastify = Fastify({
|
||||
loggerInstance: logger
|
||||
})
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
await reply.send({ hello: 'world' })
|
||||
return { hello: 'world2' }
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.deepStrictEqual(payload, { hello: 'world' })
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('ignore the result of the promise if reply.send is called beforehand (undefined)', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = Fastify()
|
||||
const payload = { hello: 'world' }
|
||||
|
||||
server.get('/', async function awaitMyFunc (req, reply) {
|
||||
await reply.send(payload)
|
||||
})
|
||||
|
||||
t.after(() => { server.close() })
|
||||
|
||||
const fastifyServer = await server.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.deepStrictEqual(payload, await result.json())
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('ignore the result of the promise if reply.send is called beforehand (object)', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const server = Fastify()
|
||||
const payload = { hello: 'world2' }
|
||||
|
||||
server.get('/', async function awaitMyFunc (req, reply) {
|
||||
await reply.send(payload)
|
||||
return { hello: 'world' }
|
||||
})
|
||||
|
||||
t.after(() => { server.close() })
|
||||
|
||||
const fastifyServer = await server.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.deepStrictEqual(payload, await result.json())
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('await reply if we will be calling reply.send in the future', (t, done) => {
|
||||
const lines = ['incoming request', 'request completed']
|
||||
t.plan(lines.length + 2)
|
||||
|
||||
const splitStream = split(JSON.parse)
|
||||
splitStream.on('data', (line) => {
|
||||
t.assert.strictEqual(line.msg, lines.shift())
|
||||
})
|
||||
|
||||
const server = Fastify({
|
||||
logger: {
|
||||
stream: splitStream
|
||||
}
|
||||
})
|
||||
const payload = { hello: 'world' }
|
||||
|
||||
server.get('/', async function awaitMyFunc (req, reply) {
|
||||
setImmediate(function () {
|
||||
reply.send(payload)
|
||||
})
|
||||
|
||||
await reply
|
||||
})
|
||||
|
||||
server.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.deepStrictEqual(payload, { hello: 'world' })
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('await reply if we will be calling reply.send in the future (error case)', (t, done) => {
|
||||
const lines = ['incoming request', 'kaboom', 'request completed']
|
||||
t.plan(lines.length + 2)
|
||||
|
||||
const splitStream = split(JSON.parse)
|
||||
splitStream.on('data', (line) => {
|
||||
t.assert.strictEqual(line.msg, lines.shift())
|
||||
})
|
||||
|
||||
const server = Fastify({
|
||||
logger: {
|
||||
stream: splitStream
|
||||
}
|
||||
})
|
||||
|
||||
server.get('/', async function awaitMyFunc (req, reply) {
|
||||
setImmediate(function () {
|
||||
reply.send(new Error('kaboom'))
|
||||
})
|
||||
|
||||
await reply
|
||||
})
|
||||
|
||||
server.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 500)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('support reply decorators with await', (t, done) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.decorateReply('wow', function () {
|
||||
setImmediate(() => {
|
||||
this.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
return this
|
||||
})
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
await sleep(1)
|
||||
await reply.wow()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.deepStrictEqual(payload, { hello: 'world' })
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('inject async await', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
try {
|
||||
const res = await fastify.inject({ method: 'GET', url: '/' })
|
||||
t.assert.deepStrictEqual({ hello: 'world' }, JSON.parse(res.payload))
|
||||
} catch (err) {
|
||||
t.assert.fail(err)
|
||||
}
|
||||
})
|
||||
|
||||
test('inject async await - when the server equal up', async t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
try {
|
||||
const res = await fastify.inject({ method: 'GET', url: '/' })
|
||||
t.assert.deepStrictEqual({ hello: 'world' }, JSON.parse(res.payload))
|
||||
} catch (err) {
|
||||
t.assert.fail(err)
|
||||
}
|
||||
|
||||
await sleep(200)
|
||||
|
||||
try {
|
||||
const res2 = await fastify.inject({ method: 'GET', url: '/' })
|
||||
t.assert.deepStrictEqual({ hello: 'world' }, JSON.parse(res2.payload))
|
||||
} catch (err) {
|
||||
t.assert.fail(err)
|
||||
}
|
||||
})
|
||||
|
||||
test('async await plugin', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(async (fastify, opts) => {
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
await sleep(200)
|
||||
})
|
||||
|
||||
try {
|
||||
const res = await fastify.inject({ method: 'GET', url: '/' })
|
||||
t.assert.deepStrictEqual({ hello: 'world' }, JSON.parse(res.payload))
|
||||
} catch (err) {
|
||||
t.assert.fail(err)
|
||||
}
|
||||
})
|
||||
|
||||
test('does not call reply.send() twice if 204 response equal already sent', (t, done) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
reply.code(204).send()
|
||||
reply.send = () => {
|
||||
throw new Error('reply.send() was called twice')
|
||||
}
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 204)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('promise was fulfilled with undefined', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
let fastify = null
|
||||
const stream = split(JSON.parse)
|
||||
try {
|
||||
fastify = Fastify({
|
||||
logger: {
|
||||
stream,
|
||||
level: 'error'
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
})
|
||||
|
||||
stream.once('data', line => {
|
||||
t.assert.fail('should not log an error')
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(await result.text(), '')
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('promise was fulfilled with undefined using inject', async (t) => {
|
||||
const stream = split(JSON.parse)
|
||||
const fastify = Fastify({
|
||||
logger: {
|
||||
stream,
|
||||
level: 'error'
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
})
|
||||
|
||||
stream.once('data', line => {
|
||||
t.assert.fail('should not log an error')
|
||||
})
|
||||
|
||||
const res = await fastify.inject('/')
|
||||
|
||||
t.assert.strictEqual(res.body, '')
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
})
|
||||
|
||||
test('error is not logged because promise was fulfilled with undefined but response was sent before promise resolution', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
let fastify = null
|
||||
const stream = split(JSON.parse)
|
||||
const payload = { hello: 'world' }
|
||||
try {
|
||||
fastify = Fastify({
|
||||
logger: {
|
||||
stream,
|
||||
level: 'error'
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
reply.send(payload)
|
||||
})
|
||||
|
||||
stream.once('data', line => {
|
||||
t.assert.fail('should not log an error')
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(
|
||||
payload,
|
||||
await result.json()
|
||||
)
|
||||
})
|
||||
|
||||
test('Thrown Error instance sets HTTP status code', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
const err = new Error('winter is coming')
|
||||
err.statusCode = 418
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
throw err
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (error, res) => {
|
||||
t.assert.ifError(error)
|
||||
t.assert.strictEqual(res.statusCode, 418)
|
||||
t.assert.deepStrictEqual(
|
||||
{
|
||||
error: statusCodes['418'],
|
||||
message: err.message,
|
||||
statusCode: 418
|
||||
},
|
||||
JSON.parse(res.payload)
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('customErrorHandler support', (t, done) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
const error = new Error('ouch')
|
||||
error.statusCode = 400
|
||||
throw error
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(async err => {
|
||||
t.assert.strictEqual(err.message, 'ouch')
|
||||
const error = new Error('kaboom')
|
||||
error.statusCode = 401
|
||||
throw error
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 401)
|
||||
t.assert.deepStrictEqual(
|
||||
{
|
||||
error: statusCodes['401'],
|
||||
message: 'kaboom',
|
||||
statusCode: 401
|
||||
},
|
||||
JSON.parse(res.payload)
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('customErrorHandler support without throwing', (t, done) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
const error = new Error('ouch')
|
||||
error.statusCode = 400
|
||||
throw error
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(async (err, req, reply) => {
|
||||
t.assert.strictEqual(err.message, 'ouch')
|
||||
await reply.code(401).send('kaboom')
|
||||
reply.send = t.assert.fail.bind(t, 'should not be called')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 401)
|
||||
t.assert.deepStrictEqual(
|
||||
'kaboom',
|
||||
res.payload
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
// See https://github.com/fastify/fastify/issues/2653
|
||||
test('customErrorHandler only called if reply not already sent', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
await reply.send('success')
|
||||
const error = new Error('ouch')
|
||||
error.statusCode = 400
|
||||
throw error
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(t.assert.fail.bind(t, 'should not be called'))
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
t.assert.deepStrictEqual(
|
||||
'success',
|
||||
res.payload
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
// See https://github.com/fastify/fastify/issues/3209
|
||||
test('setNotFoundHandler should accept return value', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async () => ({ hello: 'world' }))
|
||||
|
||||
fastify.setNotFoundHandler((req, reply) => {
|
||||
reply.code(404)
|
||||
return {
|
||||
error: statusCodes['404'],
|
||||
message: 'lost',
|
||||
statusCode: 404
|
||||
}
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/elsewhere'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 404)
|
||||
t.assert.deepStrictEqual(
|
||||
{
|
||||
error: statusCodes['404'],
|
||||
message: 'lost',
|
||||
statusCode: 404
|
||||
},
|
||||
JSON.parse(res.payload)
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
// See https://github.com/fastify/fastify/issues/3209
|
||||
test('customErrorHandler should accept return value', (t, done) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
const error = new Error('ouch')
|
||||
error.statusCode = 400
|
||||
throw error
|
||||
})
|
||||
|
||||
fastify.setErrorHandler((err, req, reply) => {
|
||||
t.assert.strictEqual(err.message, 'ouch')
|
||||
reply.code(401)
|
||||
return {
|
||||
error: statusCodes['401'],
|
||||
message: 'kaboom',
|
||||
statusCode: 401
|
||||
}
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 401)
|
||||
t.assert.deepStrictEqual(
|
||||
{
|
||||
error: statusCodes['401'],
|
||||
message: 'kaboom',
|
||||
statusCode: 401
|
||||
},
|
||||
JSON.parse(res.payload)
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('await self', async t => {
|
||||
const app = Fastify()
|
||||
t.assert.strictEqual(await app, app)
|
||||
})
|
||||
20
node_modules/fastify/test/async-dispose.test.js
generated
vendored
20
node_modules/fastify/test/async-dispose.test.js
generated
vendored
@@ -1,20 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
|
||||
// asyncDispose doesn't exist in node <= 16
|
||||
test('async dispose should close fastify', { skip: !('asyncDispose' in Symbol) }, async t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
t.assert.strictEqual(fastify.server.listening, true)
|
||||
|
||||
// the same as syntax sugar for
|
||||
// await using app = fastify()
|
||||
await fastify[Symbol.asyncDispose]()
|
||||
t.assert.strictEqual(fastify.server.listening, false)
|
||||
})
|
||||
52
node_modules/fastify/test/async_hooks.test.js
generated
vendored
52
node_modules/fastify/test/async_hooks.test.js
generated
vendored
@@ -1,52 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { createHook } = require('node:async_hooks')
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
const remainingIds = new Set()
|
||||
|
||||
createHook({
|
||||
init (asyncId, type, triggerAsyncId, resource) {
|
||||
if (type === 'content-type-parser:run') {
|
||||
remainingIds.add(asyncId)
|
||||
}
|
||||
},
|
||||
destroy (asyncId) {
|
||||
remainingIds.delete(asyncId)
|
||||
}
|
||||
})
|
||||
|
||||
const app = Fastify({ logger: false })
|
||||
|
||||
test('test async hooks', async (t) => {
|
||||
app.get('/', function (request, reply) {
|
||||
reply.send({ id: 42 })
|
||||
})
|
||||
|
||||
app.post('/', function (request, reply) {
|
||||
reply.send({ id: 42 })
|
||||
})
|
||||
|
||||
t.after(() => app.close())
|
||||
|
||||
const fastifyServer = await app.listen({ port: 0 })
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hello: 'world' })
|
||||
})
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ hello: 'world' })
|
||||
})
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
|
||||
const result3 = await fetch(fastifyServer)
|
||||
t.assert.strictEqual(result3.status, 200)
|
||||
t.assert.strictEqual(remainingIds.size, 0)
|
||||
})
|
||||
224
node_modules/fastify/test/body-limit.test.js
generated
vendored
224
node_modules/fastify/test/body-limit.test.js
generated
vendored
@@ -1,224 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const Fastify = require('../fastify')
|
||||
const zlib = require('node:zlib')
|
||||
const { test } = require('node:test')
|
||||
|
||||
test('bodyLimit', async t => {
|
||||
t.plan(4)
|
||||
|
||||
try {
|
||||
Fastify({ bodyLimit: 1.3 })
|
||||
t.assert.fail('option must be an integer')
|
||||
} catch (err) {
|
||||
t.assert.ok(err)
|
||||
}
|
||||
|
||||
try {
|
||||
Fastify({ bodyLimit: [] })
|
||||
t.assert.fail('option must be an integer')
|
||||
} catch (err) {
|
||||
t.assert.ok(err)
|
||||
}
|
||||
|
||||
const fastify = Fastify({ bodyLimit: 1 })
|
||||
|
||||
fastify.post('/', (request, reply) => {
|
||||
reply.send({ error: 'handler should not be called' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify([])
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 413)
|
||||
})
|
||||
|
||||
test('bodyLimit is applied to decoded content', async (t) => {
|
||||
t.plan(6)
|
||||
|
||||
const body = { x: 'x'.repeat(30000) }
|
||||
const json = JSON.stringify(body)
|
||||
const encoded = zlib.gzipSync(json)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('preParsing', async (req, reply, payload) => {
|
||||
t.assert.strictEqual(req.headers['content-length'], `${encoded.length}`)
|
||||
const unzip = zlib.createGunzip()
|
||||
Object.defineProperty(unzip, 'receivedEncodedLength', {
|
||||
get () {
|
||||
return unzip.bytesWritten
|
||||
}
|
||||
})
|
||||
payload.pipe(unzip)
|
||||
return unzip
|
||||
})
|
||||
|
||||
fastify.post('/body-limit-40k', {
|
||||
bodyLimit: 40000,
|
||||
onError: async (req, res, err) => {
|
||||
t.fail('should not be called')
|
||||
}
|
||||
}, (request, reply) => {
|
||||
reply.send({ x: request.body.x })
|
||||
})
|
||||
|
||||
fastify.post('/body-limit-20k', {
|
||||
bodyLimit: 20000,
|
||||
onError: async (req, res, err) => {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_BODY_TOO_LARGE')
|
||||
t.assert.strictEqual(err.statusCode, 413)
|
||||
}
|
||||
}, (request, reply) => {
|
||||
reply.send({ x: 'handler should not be called' })
|
||||
})
|
||||
|
||||
await t.test('bodyLimit 40k', async (t) => {
|
||||
const result = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/body-limit-40k',
|
||||
headers: {
|
||||
'content-encoding': 'gzip',
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
payload: encoded
|
||||
})
|
||||
t.assert.strictEqual(result.statusCode, 200)
|
||||
t.assert.deepStrictEqual(result.json(), body)
|
||||
})
|
||||
|
||||
await t.test('bodyLimit 20k', async (t) => {
|
||||
const result = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/body-limit-20k',
|
||||
headers: {
|
||||
'content-encoding': 'gzip',
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
payload: encoded
|
||||
})
|
||||
t.assert.strictEqual(result.statusCode, 413)
|
||||
})
|
||||
})
|
||||
|
||||
test('default request.routeOptions.bodyLimit should be 1048576', async t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
fastify.post('/default-bodylimit', {
|
||||
handler (request, reply) {
|
||||
t.assert.strictEqual(1048576, request.routeOptions.bodyLimit)
|
||||
reply.send({ })
|
||||
}
|
||||
})
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const result = await fetch(fastifyServer + '/default-bodylimit', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify([])
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('request.routeOptions.bodyLimit should be equal to route limit', async t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify({ bodyLimit: 1 })
|
||||
fastify.post('/route-limit', {
|
||||
bodyLimit: 1000,
|
||||
handler (request, reply) {
|
||||
t.assert.strictEqual(1000, request.routeOptions.bodyLimit)
|
||||
reply.send({})
|
||||
}
|
||||
})
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const result = await fetch(fastifyServer + '/route-limit', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify([])
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('request.routeOptions.bodyLimit should be equal to server limit', async t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify({ bodyLimit: 100 })
|
||||
fastify.post('/server-limit', {
|
||||
handler (request, reply) {
|
||||
t.assert.strictEqual(100, request.routeOptions.bodyLimit)
|
||||
reply.send({})
|
||||
}
|
||||
})
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const result = await fetch(fastifyServer + '/server-limit', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify([])
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
test('bodyLimit should use byte length for UTF-8 strings, not character length', async t => {
|
||||
t.plan(4)
|
||||
|
||||
// Create a string with multi-byte UTF-8 characters
|
||||
// Use Japanese characters that are 3 bytes each in UTF-8
|
||||
const multiByteString = 'あああ' // 3 characters, 9 bytes in UTF-8
|
||||
t.assert.strictEqual(multiByteString.length, 3) // 3 characters
|
||||
t.assert.strictEqual(Buffer.byteLength(multiByteString, 'utf8'), 9) // 9 bytes
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
// Add a custom text parser that returns the string as-is
|
||||
fastify.addContentTypeParser('text/plain', { parseAs: 'string' }, (req, body, done) => {
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
// Set body limit to 7 bytes - this should reject the string (9 bytes)
|
||||
// even though string.length (3) would be under any reasonable limit
|
||||
fastify.post('/test-utf8', {
|
||||
bodyLimit: 7
|
||||
}, (request, reply) => {
|
||||
reply.send({ body: request.body, length: request.body.length })
|
||||
})
|
||||
|
||||
await t.test('should reject body when byte length exceeds limit', async (t) => {
|
||||
const result = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/test-utf8',
|
||||
headers: { 'Content-Type': 'text/plain', 'Content-Length': null },
|
||||
payload: multiByteString
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.statusCode, 413)
|
||||
})
|
||||
|
||||
await t.test('should accept body when byte length is within limit', async (t) => {
|
||||
const smallString = 'あ' // 1 character, 3 bytes, under the 7 byte limit
|
||||
|
||||
const result = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/test-utf8',
|
||||
headers: { 'Content-Type': 'text/plain' },
|
||||
payload: smallString
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.statusCode, 200)
|
||||
t.assert.strictEqual(result.json().body, smallString)
|
||||
t.assert.strictEqual(result.json().length, 1) // 1 character
|
||||
})
|
||||
})
|
||||
74
node_modules/fastify/test/buffer.test.js
generated
vendored
74
node_modules/fastify/test/buffer.test.js
generated
vendored
@@ -1,74 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('Buffer test', async t => {
|
||||
const fastify = Fastify()
|
||||
fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, fastify.getDefaultJsonParser('error', 'ignore'))
|
||||
|
||||
fastify.delete('/', async (request) => {
|
||||
return request.body
|
||||
})
|
||||
|
||||
await test('should return 200 if the body is not empty', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'DELETE',
|
||||
url: '/',
|
||||
payload: Buffer.from('{"hello":"world"}'),
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ifError(response.error)
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.payload.toString(), '{"hello":"world"}')
|
||||
})
|
||||
|
||||
await test('should return 400 if the body is empty', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'DELETE',
|
||||
url: '/',
|
||||
payload: Buffer.alloc(0),
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ifError(response.error)
|
||||
t.assert.strictEqual(response.statusCode, 400)
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload.toString()), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await test('should return 400 if the body is invalid json', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'DELETE',
|
||||
url: '/',
|
||||
payload: Buffer.from(']'),
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ifError(response.error)
|
||||
t.assert.strictEqual(response.statusCode, 400)
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload.toString()), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_INVALID_JSON_BODY',
|
||||
message: 'Body is not valid JSON but content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
})
|
||||
109
node_modules/fastify/test/build-certificate.js
generated
vendored
109
node_modules/fastify/test/build-certificate.js
generated
vendored
@@ -1,109 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const os = require('node:os')
|
||||
const forge = require('node-forge')
|
||||
|
||||
// from self-cert module
|
||||
function selfCert (opts) {
|
||||
const options = opts || {}
|
||||
const log = opts.logger || require('abstract-logging')
|
||||
const now = new Date()
|
||||
|
||||
if (!options.attrs) options.attrs = {}
|
||||
if (!options.expires) {
|
||||
options.expires = new Date(
|
||||
now.getFullYear() + 5, now.getMonth() + 1, now.getDate()
|
||||
)
|
||||
}
|
||||
|
||||
log.debug('generating key pair')
|
||||
const keys = forge.pki.rsa.generateKeyPair(options.bits || 2048)
|
||||
log.debug('key pair generated')
|
||||
|
||||
log.debug('generating self-signed certificate')
|
||||
const cert = forge.pki.createCertificate()
|
||||
cert.publicKey = keys.publicKey
|
||||
cert.serialNumber = '01'
|
||||
cert.validity.notBefore = now
|
||||
cert.validity.notAfter = options.expires
|
||||
|
||||
const attrs = [
|
||||
{ name: 'commonName', value: options.attrs.commonName || os.hostname() },
|
||||
{ name: 'countryName', value: options.attrs.countryName || 'US' },
|
||||
{ name: 'stateOrProvinceName', value: options.attrs.stateName || 'Georgia' },
|
||||
{ name: 'localityName', value: options.attrs.locality || 'Atlanta' },
|
||||
{ name: 'organizationName', value: options.attrs.orgName || 'None' },
|
||||
{ shortName: 'OU', value: options.attrs.shortName || 'example' }
|
||||
]
|
||||
cert.setSubject(attrs)
|
||||
cert.setIssuer(attrs)
|
||||
|
||||
cert.setExtensions([
|
||||
{ name: 'basicConstraints', cA: true },
|
||||
{
|
||||
name: 'keyUsage',
|
||||
keyCertSign: true,
|
||||
digitalSignature: true,
|
||||
nonRepudiation: true,
|
||||
keyEncipherment: true,
|
||||
dataEncipherment: true
|
||||
},
|
||||
{
|
||||
name: 'extKeyUsage',
|
||||
serverAuth: true,
|
||||
clientAuth: true,
|
||||
codeSigning: true,
|
||||
emailProtection: true,
|
||||
timeStamping: true
|
||||
},
|
||||
{
|
||||
name: 'nsCertType',
|
||||
client: true,
|
||||
server: true,
|
||||
email: true,
|
||||
objsign: true,
|
||||
sslCA: true,
|
||||
emailCA: true,
|
||||
objCA: true
|
||||
},
|
||||
{ name: 'subjectKeyIdentifier' },
|
||||
{
|
||||
name: 'subjectAltName',
|
||||
altNames: [{ type: 6 /* URI */, value: 'DNS: ' + attrs[0].value }].concat((function () {
|
||||
const interfaces = os.networkInterfaces()
|
||||
|
||||
// fix citgm: skip invalid ips (aix72-ppc64)
|
||||
const ips = Object.values(interfaces).flat()
|
||||
.filter(i => !!forge.util.bytesFromIP(i.address))
|
||||
.map(i => ({ type: 7 /* IP */, ip: i.address }))
|
||||
|
||||
return ips
|
||||
}()))
|
||||
}
|
||||
])
|
||||
|
||||
cert.sign(keys.privateKey)
|
||||
log.debug('certificate generated')
|
||||
return {
|
||||
privateKey: forge.pki.privateKeyToPem(keys.privateKey),
|
||||
publicKey: forge.pki.publicKeyToPem(keys.publicKey),
|
||||
certificate: forge.pki.certificateToPem(cert)
|
||||
}
|
||||
}
|
||||
|
||||
function buildCertificate () {
|
||||
// "global" is used in here because "t.context" is only supported by "t.beforeEach" and "t.afterEach"
|
||||
// For the test case which execute this code which will be using `t.before` and it can reduce the
|
||||
// number of times executing it.
|
||||
if (!global.context || !global.context.cert || !global.context.key) {
|
||||
const certs = selfCert({
|
||||
expires: new Date(Date.now() + 86400000)
|
||||
})
|
||||
global.context = {
|
||||
cert: certs.certificate,
|
||||
key: certs.privateKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { buildCertificate }
|
||||
36
node_modules/fastify/test/build/error-serializer.test.js
generated
vendored
36
node_modules/fastify/test/build/error-serializer.test.js
generated
vendored
@@ -1,36 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const { loadESLint } = require('eslint')
|
||||
|
||||
const { code } = require('../../build/build-error-serializer')
|
||||
|
||||
function unifyLineBreak (str) {
|
||||
return str.toString().replace(/\r\n/g, '\n')
|
||||
}
|
||||
|
||||
test('check generated code syntax', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
// standard is a esm, we import it like this
|
||||
const Eslint = await loadESLint({ useFlatConfig: true })
|
||||
const eslint = new Eslint()
|
||||
const result = await eslint.lintText(code)
|
||||
|
||||
// if there are any invalid syntax
|
||||
// fatal count will be greater than 0
|
||||
t.assert.strictEqual(result[0].fatalErrorCount, 0)
|
||||
})
|
||||
|
||||
const isPrepublish = !!process.env.PREPUBLISH
|
||||
|
||||
test('ensure the current error serializer is latest', { skip: !isPrepublish }, async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const current = await fs.promises.readFile(path.resolve('lib/error-serializer.js'))
|
||||
|
||||
// line break should not be a problem depends on system
|
||||
t.assert.strictEqual(unifyLineBreak(current), unifyLineBreak(code))
|
||||
})
|
||||
14
node_modules/fastify/test/build/version.test.js
generated
vendored
14
node_modules/fastify/test/build/version.test.js
generated
vendored
@@ -1,14 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
|
||||
test('should be the same as package.json', t => {
|
||||
t.plan(1)
|
||||
|
||||
const json = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json')).toString('utf8'))
|
||||
|
||||
t.assert.strictEqual(fastify.version, json.version)
|
||||
})
|
||||
29
node_modules/fastify/test/bundler/README.md
generated
vendored
29
node_modules/fastify/test/bundler/README.md
generated
vendored
@@ -1,29 +0,0 @@
|
||||
# Bundlers test stack
|
||||
|
||||
In some cases, developers bundle their apps for several targets such as serverless applications.
|
||||
Even if it's not recommended by Fastify team; we need to ensure we do not break the build process.
|
||||
Please note this might result in features behaving differently, like the version handling check for plugins.
|
||||
|
||||
## Test bundlers
|
||||
|
||||
The bundler test stack has been defined separately from the rest of the Unit testing stack because it's not a
|
||||
part of the fastify lib itself. Note that the tests run in CI only on NodeJs LTS version.
|
||||
Developers do not need to install every bundler to run unit tests.
|
||||
|
||||
To run the bundler tests you will need to install the repository dependencies followed by the bundler
|
||||
stack dependencies. See:
|
||||
|
||||
```bash
|
||||
# path: root of repository /fastify
|
||||
npm i
|
||||
cd test/bundler/webpack
|
||||
npm i
|
||||
npm run test # test command runs bundle before of starting the test
|
||||
```
|
||||
|
||||
## Bundler test development
|
||||
|
||||
To not break the fastify unit testing stack please name test files like this `*-test.js` and not `*.test.js`,
|
||||
otherwise it will be targeted by the regular expression used for unit tests for fastify.
|
||||
Tests need to ensure the build process works and the fastify application can be run,
|
||||
no need to go in deep testing unless an issue is raised.
|
||||
32
node_modules/fastify/test/bundler/esbuild/bundler-test.js
generated
vendored
32
node_modules/fastify/test/bundler/esbuild/bundler-test.js
generated
vendored
@@ -1,32 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastifySuccess = require('./dist/success')
|
||||
const fastifyFailPlugin = require('./dist/failPlugin')
|
||||
|
||||
test('Bundled package should work', (t, done) => {
|
||||
t.plan(4)
|
||||
fastifySuccess.ready((err) => {
|
||||
t.assert.ifError(err)
|
||||
fastifySuccess.inject(
|
||||
{
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
},
|
||||
(error, res) => {
|
||||
t.assert.ifError(error)
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test('Bundled package should not work with bad plugin version', (t, done) => {
|
||||
t.plan(1)
|
||||
fastifyFailPlugin.ready((err) => {
|
||||
t.assert.match(err.message, /expected '9.x' fastify version/i)
|
||||
done()
|
||||
})
|
||||
})
|
||||
10
node_modules/fastify/test/bundler/esbuild/package.json
generated
vendored
10
node_modules/fastify/test/bundler/esbuild/package.json
generated
vendored
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"bundle": "esbuild success=src/index.js failPlugin=src/fail-plugin-version.js --bundle --outdir=dist --platform=node",
|
||||
"test": "npm run bundle && node bundler-test.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0"
|
||||
}
|
||||
}
|
||||
14
node_modules/fastify/test/bundler/esbuild/src/fail-plugin-version.js
generated
vendored
14
node_modules/fastify/test/bundler/esbuild/src/fail-plugin-version.js
generated
vendored
@@ -1,14 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fp = require('fastify-plugin')
|
||||
const fastify = require('../../../../')()
|
||||
|
||||
fastify.get('/', function (request, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.register(fp((instance, opts, done) => {
|
||||
done()
|
||||
}, { fastify: '9.x' }))
|
||||
|
||||
module.exports = fastify
|
||||
9
node_modules/fastify/test/bundler/esbuild/src/index.js
generated
vendored
9
node_modules/fastify/test/bundler/esbuild/src/index.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fastify = require('../../../../')()
|
||||
// Declare a route
|
||||
fastify.get('/', function (request, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
module.exports = fastify
|
||||
32
node_modules/fastify/test/bundler/webpack/bundler-test.js
generated
vendored
32
node_modules/fastify/test/bundler/webpack/bundler-test.js
generated
vendored
@@ -1,32 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastifySuccess = require('./dist/success')
|
||||
const fastifyFailPlugin = require('./dist/failPlugin')
|
||||
|
||||
test('Bundled package should work', (t, done) => {
|
||||
t.plan(4)
|
||||
fastifySuccess.ready((err) => {
|
||||
t.assert.ifError(err)
|
||||
fastifySuccess.inject(
|
||||
{
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
},
|
||||
(error, res) => {
|
||||
t.assert.ifError(error)
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
||||
done()
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test('Bundled package should not work with bad plugin version', (t, done) => {
|
||||
t.plan(1)
|
||||
fastifyFailPlugin.ready((err) => {
|
||||
t.assert.match(err.message, /expected '9.x' fastify version/i)
|
||||
done()
|
||||
})
|
||||
})
|
||||
11
node_modules/fastify/test/bundler/webpack/package.json
generated
vendored
11
node_modules/fastify/test/bundler/webpack/package.json
generated
vendored
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"version":"0.0.1",
|
||||
"scripts": {
|
||||
"bundle": "webpack",
|
||||
"test": "npm run bundle && node bundler-test.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^5.49.0",
|
||||
"webpack-cli": "^4.7.2"
|
||||
}
|
||||
}
|
||||
14
node_modules/fastify/test/bundler/webpack/src/fail-plugin-version.js
generated
vendored
14
node_modules/fastify/test/bundler/webpack/src/fail-plugin-version.js
generated
vendored
@@ -1,14 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fp = require('fastify-plugin')
|
||||
const fastify = require('../../../../')()
|
||||
|
||||
fastify.get('/', function (request, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.register(fp((instance, opts, done) => {
|
||||
done()
|
||||
}, { fastify: '9.x' }))
|
||||
|
||||
module.exports = fastify
|
||||
9
node_modules/fastify/test/bundler/webpack/src/index.js
generated
vendored
9
node_modules/fastify/test/bundler/webpack/src/index.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fastify = require('../../../../')()
|
||||
// Declare a route
|
||||
fastify.get('/', function (request, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
module.exports = fastify
|
||||
15
node_modules/fastify/test/bundler/webpack/webpack.config.js
generated
vendored
15
node_modules/fastify/test/bundler/webpack/webpack.config.js
generated
vendored
@@ -1,15 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const path = require('node:path')
|
||||
|
||||
module.exports = {
|
||||
entry: { success: './src/index.js', failPlugin: './src/fail-plugin-version.js' },
|
||||
target: 'node',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: '[name].js',
|
||||
library: {
|
||||
type: 'commonjs2'
|
||||
}
|
||||
}
|
||||
}
|
||||
102
node_modules/fastify/test/case-insensitive.test.js
generated
vendored
102
node_modules/fastify/test/case-insensitive.test.js
generated
vendored
@@ -1,102 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('case insensitive', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify({
|
||||
caseSensitive: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/foo', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`${fastifyServer}/FOO`)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), {
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
|
||||
test('case insensitive inject', async t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify({
|
||||
caseSensitive: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/foo', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: fastifyServer + '/FOO'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.statusCode, 200)
|
||||
t.assert.deepStrictEqual(result.json(), {
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
|
||||
test('case insensitive (parametric)', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify({
|
||||
caseSensitive: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/foo/:param', (req, reply) => {
|
||||
t.assert.strictEqual(req.params.param, 'bAr')
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`${fastifyServer}/FoO/bAr`, {
|
||||
method: 'GET'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), {
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
|
||||
test('case insensitive (wildcard)', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify({
|
||||
caseSensitive: false
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/foo/*', (req, reply) => {
|
||||
t.assert.strictEqual(req.params['*'], 'bAr/baZ')
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`${fastifyServer}/FoO/bAr/baZ`)
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), {
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
40
node_modules/fastify/test/chainable.test.js
generated
vendored
40
node_modules/fastify/test/chainable.test.js
generated
vendored
@@ -1,40 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('..')()
|
||||
|
||||
const noop = () => {}
|
||||
const opts = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test('chainable - get', t => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(fastify.get('/', opts, noop), fastify)
|
||||
})
|
||||
|
||||
test('chainable - post', t => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(fastify.post('/', opts, noop), fastify)
|
||||
})
|
||||
|
||||
test('chainable - route', t => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(fastify.route({
|
||||
method: 'GET',
|
||||
url: '/other',
|
||||
schema: opts.schema,
|
||||
handler: noop
|
||||
}), fastify)
|
||||
})
|
||||
219
node_modules/fastify/test/check.test.js
generated
vendored
219
node_modules/fastify/test/check.test.js
generated
vendored
@@ -1,219 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const { S } = require('fluent-json-schema')
|
||||
const Fastify = require('..')
|
||||
|
||||
const BadRequestSchema = S.object()
|
||||
.prop('statusCode', S.number())
|
||||
.prop('error', S.string())
|
||||
.prop('message', S.string())
|
||||
|
||||
const InternalServerErrorSchema = S.object()
|
||||
.prop('statusCode', S.number())
|
||||
.prop('error', S.string())
|
||||
.prop('message', S.string())
|
||||
|
||||
const NotFoundSchema = S.object()
|
||||
.prop('statusCode', S.number())
|
||||
.prop('error', S.string())
|
||||
.prop('message', S.string())
|
||||
|
||||
const options = {
|
||||
schema: {
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
},
|
||||
400: {
|
||||
description: 'Bad Request',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: BadRequestSchema.valueOf()
|
||||
}
|
||||
}
|
||||
},
|
||||
404: {
|
||||
description: 'Resource not found',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: NotFoundSchema.valueOf(),
|
||||
example: {
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: 'Not Found'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
500: {
|
||||
description: 'Internal Server Error',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: InternalServerErrorSchema.valueOf(),
|
||||
example: {
|
||||
message: 'Internal Server Error'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handler = (request, reply) => {
|
||||
if (request.body.id === '400') {
|
||||
return reply.status(400).send({
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: 'Custom message',
|
||||
extra: 'This should not be in the response'
|
||||
})
|
||||
}
|
||||
|
||||
if (request.body.id === '404') {
|
||||
return reply.status(404).send({
|
||||
statusCode: 404,
|
||||
error: 'Not Found',
|
||||
message: 'Custom Not Found',
|
||||
extra: 'This should not be in the response'
|
||||
})
|
||||
}
|
||||
|
||||
if (request.body.id === '500') {
|
||||
reply.status(500).send({
|
||||
statusCode: 500,
|
||||
error: 'Internal Server Error',
|
||||
message: 'Custom Internal Server Error',
|
||||
extra: 'This should not be in the response'
|
||||
})
|
||||
}
|
||||
|
||||
reply.send({
|
||||
id: request.body.id,
|
||||
extra: 'This should not be in the response'
|
||||
})
|
||||
}
|
||||
|
||||
test('serialize the response for a Bad Request error, as defined on the schema', async t => {
|
||||
const fastify = Fastify({})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', options, handler)
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: '12'
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 400)
|
||||
t.assert.deepStrictEqual(await result.json(), {
|
||||
statusCode: 400,
|
||||
error: 'Bad Request',
|
||||
message: 'body must be object'
|
||||
})
|
||||
})
|
||||
|
||||
// test('serialize the response for a Not Found error, as defined on the schema', t => {
|
||||
// const fastify = Fastify({})
|
||||
|
||||
// t.teardown(fastify.close.bind(fastify))
|
||||
|
||||
// fastify.post('/', options, handler)
|
||||
|
||||
// fastify.listen({ port: 0 }, err => {
|
||||
// t.error(err)
|
||||
|
||||
// const url = `http://localhost:${fastify.server.address().port}/`
|
||||
|
||||
// sget({
|
||||
// method: 'POST',
|
||||
// url,
|
||||
// json: true,
|
||||
// body: { id: '404' }
|
||||
// }, (err, response, body) => {
|
||||
// t.error(err)
|
||||
// t.equal(response.statusCode, 404)
|
||||
// t.same(body, {
|
||||
// statusCode: 404,
|
||||
// error: 'Not Found',
|
||||
// message: 'Custom Not Found'
|
||||
// })
|
||||
// t.end()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
|
||||
// test('serialize the response for a Internal Server Error error, as defined on the schema', t => {
|
||||
// const fastify = Fastify({})
|
||||
|
||||
// t.teardown(fastify.close.bind(fastify))
|
||||
|
||||
// fastify.post('/', options, handler)
|
||||
|
||||
// fastify.listen({ port: 0 }, err => {
|
||||
// t.error(err)
|
||||
|
||||
// const url = `http://localhost:${fastify.server.address().port}/`
|
||||
|
||||
// sget({
|
||||
// method: 'POST',
|
||||
// url,
|
||||
// json: true,
|
||||
// body: { id: '500' }
|
||||
// }, (err, response, body) => {
|
||||
// t.error(err)
|
||||
// t.equal(response.statusCode, 500)
|
||||
// t.same(body, {
|
||||
// statusCode: 500,
|
||||
// error: 'Internal Server Error',
|
||||
// message: 'Custom Internal Server Error'
|
||||
// })
|
||||
// t.end()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
|
||||
// test('serialize the success response, as defined on the schema', t => {
|
||||
// const fastify = Fastify({})
|
||||
|
||||
// t.teardown(fastify.close.bind(fastify))
|
||||
|
||||
// fastify.post('/', options, handler)
|
||||
|
||||
// fastify.listen({ port: 0 }, err => {
|
||||
// t.error(err)
|
||||
|
||||
// const url = `http://localhost:${fastify.server.address().port}/`
|
||||
|
||||
// sget({
|
||||
// method: 'POST',
|
||||
// url,
|
||||
// json: true,
|
||||
// body: { id: 'test' }
|
||||
// }, (err, response, body) => {
|
||||
// t.error(err)
|
||||
// t.equal(response.statusCode, 200)
|
||||
// t.same(body, {
|
||||
// id: 'test'
|
||||
// })
|
||||
// t.end()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
128
node_modules/fastify/test/child-logger-factory.test.js
generated
vendored
128
node_modules/fastify/test/child-logger-factory.test.js
generated
vendored
@@ -1,128 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('Should accept a custom childLoggerFactory function', (t, done) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.setChildLoggerFactory(function (logger, bindings, opts) {
|
||||
t.assert.ok(bindings.reqId)
|
||||
t.assert.ok(opts)
|
||||
this.log.debug(bindings, 'created child logger')
|
||||
return logger.child(bindings, opts)
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
req.log.info('log message')
|
||||
reply.send()
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: 'http://localhost:' + fastify.server.address().port
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should accept a custom childLoggerFactory function as option', (t, done) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify({
|
||||
childLoggerFactory: function (logger, bindings, opts) {
|
||||
t.ok(bindings.reqId)
|
||||
t.ok(opts)
|
||||
this.log.debug(bindings, 'created child logger')
|
||||
return logger.child(bindings, opts)
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
req.log.info('log message')
|
||||
reply.send()
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: 'http://localhost:' + fastify.server.address().port
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('req.log should be the instance returned by the factory', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.setChildLoggerFactory(function (logger, bindings, opts) {
|
||||
this.log.debug('using root logger')
|
||||
return this.log
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.strictEqual(req.log, fastify.log)
|
||||
req.log.info('log message')
|
||||
reply.send()
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: 'http://localhost:' + fastify.server.address().port
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('should throw error if invalid logger is returned', (t, done) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.setChildLoggerFactory(function () {
|
||||
this.log.debug('returning an invalid logger, expect error')
|
||||
return undefined
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send()
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.throws(() => {
|
||||
try {
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: 'http://localhost:' + fastify.server.address().port
|
||||
}, (err) => {
|
||||
t.assert.fail('request should have failed but did not')
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
} finally {
|
||||
done()
|
||||
}
|
||||
}, { code: 'FST_ERR_LOG_INVALID_LOGGER' })
|
||||
})
|
||||
})
|
||||
38
node_modules/fastify/test/client-timeout.test.js
generated
vendored
38
node_modules/fastify/test/client-timeout.test.js
generated
vendored
@@ -1,38 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('..')({ requestTimeout: 5, http: { connectionsCheckingInterval: 1000 } })
|
||||
const { connect } = require('node:net')
|
||||
|
||||
test('requestTimeout should return 408', (t, done) => {
|
||||
t.plan(1)
|
||||
|
||||
t.after(() => {
|
||||
fastify.close()
|
||||
})
|
||||
|
||||
fastify.post('/', async function (req, reply) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
return reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
let data = Buffer.alloc(0)
|
||||
const socket = connect(fastify.server.address().port)
|
||||
|
||||
socket.write('POST / HTTP/1.1\r\nHost: example.com\r\nConnection-Length: 1\r\n')
|
||||
|
||||
socket.on('data', c => (data = Buffer.concat([data, c])))
|
||||
socket.on('end', () => {
|
||||
t.assert.strictEqual(
|
||||
data.toString('utf-8'),
|
||||
'HTTP/1.1 408 Request Timeout\r\nContent-Length: 71\r\nContent-Type: application/json\r\n\r\n{"error":"Request Timeout","message":"Client Timeout","statusCode":408}'
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
78
node_modules/fastify/test/close-pipelining.test.js
generated
vendored
78
node_modules/fastify/test/close-pipelining.test.js
generated
vendored
@@ -1,78 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const { Client } = require('undici')
|
||||
|
||||
test('Should return 503 while closing - pipelining', async t => {
|
||||
const fastify = Fastify({
|
||||
return503OnClosing: true,
|
||||
forceCloseConnections: false
|
||||
})
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
// Simulate a delay to allow pipelining to kick in
|
||||
await new Promise(resolve => setTimeout(resolve, 5))
|
||||
reply.send({ hello: 'world' })
|
||||
fastify.close()
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const instance = new Client('http://localhost:' + fastify.server.address().port, {
|
||||
pipelining: 2
|
||||
})
|
||||
|
||||
const [firstRequest, secondRequest, thirdRequest] = await Promise.allSettled([
|
||||
instance.request({ path: '/', method: 'GET', blocking: false }),
|
||||
instance.request({ path: '/', method: 'GET', blocking: false }),
|
||||
instance.request({ path: '/', method: 'GET', blocking: false })
|
||||
])
|
||||
t.assert.strictEqual(firstRequest.status, 'fulfilled')
|
||||
t.assert.strictEqual(secondRequest.status, 'fulfilled')
|
||||
|
||||
t.assert.strictEqual(firstRequest.value.statusCode, 200)
|
||||
t.assert.strictEqual(secondRequest.value.statusCode, 200)
|
||||
|
||||
t.assert.strictEqual(thirdRequest.status, 'fulfilled')
|
||||
t.assert.strictEqual(thirdRequest.value.statusCode, 503)
|
||||
|
||||
await instance.close()
|
||||
})
|
||||
|
||||
test('Should close the socket abruptly - pipelining - return503OnClosing: false', async t => {
|
||||
// Since Node v20, we will always invoke server.closeIdleConnections()
|
||||
// therefore our socket will be closed
|
||||
const fastify = Fastify({
|
||||
return503OnClosing: false,
|
||||
forceCloseConnections: false
|
||||
})
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
// Simulate a delay to allow pipelining to kick in
|
||||
await new Promise(resolve => setTimeout(resolve, 5))
|
||||
reply.send({ hello: 'world' })
|
||||
fastify.close()
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const instance = new Client('http://localhost:' + fastify.server.address().port, {
|
||||
pipelining: 1
|
||||
})
|
||||
|
||||
const responses = await Promise.allSettled([
|
||||
instance.request({ path: '/', method: 'GET', blocking: false }),
|
||||
instance.request({ path: '/', method: 'GET', blocking: false }),
|
||||
instance.request({ path: '/', method: 'GET', blocking: false }),
|
||||
instance.request({ path: '/', method: 'GET', blocking: false })
|
||||
])
|
||||
|
||||
const fulfilled = responses.filter(r => r.status === 'fulfilled')
|
||||
const rejected = responses.filter(r => r.status === 'rejected')
|
||||
|
||||
t.assert.strictEqual(fulfilled.length, 1)
|
||||
t.assert.strictEqual(rejected.length, 3)
|
||||
|
||||
await instance.close()
|
||||
})
|
||||
706
node_modules/fastify/test/close.test.js
generated
vendored
706
node_modules/fastify/test/close.test.js
generated
vendored
@@ -1,706 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const net = require('node:net')
|
||||
const http = require('node:http')
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const { Client } = require('undici')
|
||||
const split = require('split2')
|
||||
const { sleep } = require('./helper')
|
||||
|
||||
test('close callback', (t, testDone) => {
|
||||
t.plan(7)
|
||||
const fastify = Fastify()
|
||||
fastify.addHook('onClose', onClose)
|
||||
function onClose (instance, done) {
|
||||
t.assert.ok(typeof fastify === typeof this)
|
||||
t.assert.ok(typeof fastify === typeof instance)
|
||||
t.assert.strictEqual(fastify, this)
|
||||
t.assert.strictEqual(fastify, instance)
|
||||
done()
|
||||
}
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.ok('close callback')
|
||||
testDone()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('inside register', (t, done) => {
|
||||
t.plan(5)
|
||||
const fastify = Fastify()
|
||||
fastify.register(function (f, opts, done) {
|
||||
f.addHook('onClose', onClose)
|
||||
function onClose (instance, done) {
|
||||
t.assert.ok(instance.prototype === fastify.prototype)
|
||||
t.assert.strictEqual(instance, f)
|
||||
done()
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.ok('close callback')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('close order', (t, done) => {
|
||||
t.plan(5)
|
||||
const fastify = Fastify()
|
||||
const order = [1, 2, 3]
|
||||
|
||||
fastify.register(function (f, opts, done) {
|
||||
f.addHook('onClose', (instance, done) => {
|
||||
t.assert.strictEqual(order.shift(), 1)
|
||||
done()
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.addHook('onClose', (instance, done) => {
|
||||
t.assert.strictEqual(order.shift(), 2)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(order.shift(), 3)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('close order - async', async t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
const order = [1, 2, 3]
|
||||
|
||||
fastify.register(function (f, opts, done) {
|
||||
f.addHook('onClose', async instance => {
|
||||
t.assert.strictEqual(order.shift(), 1)
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.addHook('onClose', () => {
|
||||
t.assert.strictEqual(order.shift(), 2)
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
await fastify.close()
|
||||
|
||||
t.assert.strictEqual(order.shift(), 3)
|
||||
})
|
||||
|
||||
test('should not throw an error if the server is not listening', (t, done) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
fastify.addHook('onClose', onClose)
|
||||
function onClose (instance, done) {
|
||||
t.assert.ok(instance.prototype === fastify.prototype)
|
||||
done()
|
||||
}
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onClose should keep the context', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
fastify.register(plugin)
|
||||
|
||||
function plugin (instance, opts, done) {
|
||||
instance.decorate('test', true)
|
||||
instance.addHook('onClose', onClose)
|
||||
t.assert.ok(instance.prototype === fastify.prototype)
|
||||
|
||||
function onClose (i, done) {
|
||||
t.assert.ok(i.test)
|
||||
t.assert.strictEqual(i, instance)
|
||||
done()
|
||||
}
|
||||
|
||||
done()
|
||||
}
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('Should return error while closing (promise) - injection', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onClose', (instance, done) => { done() })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
fastify.close()
|
||||
|
||||
process.nextTick(() => {
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}).catch(err => {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_REOPENED_CLOSE_SERVER')
|
||||
done()
|
||||
})
|
||||
}, 100)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should return error while closing (callback) - injection', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onClose', (instance, done) => {
|
||||
setTimeout(done, 150)
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
fastify.close()
|
||||
|
||||
setTimeout(() => {
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_REOPENED_CLOSE_SERVER')
|
||||
done()
|
||||
})
|
||||
}, 100)
|
||||
})
|
||||
})
|
||||
|
||||
test('Current opened connection should NOT continue to work after closing and return "connection: close" header - return503OnClosing: false', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify({
|
||||
return503OnClosing: false,
|
||||
forceCloseConnections: false
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
fastify.close()
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const port = fastify.server.address().port
|
||||
const client = net.createConnection({ port }, () => {
|
||||
client.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
|
||||
|
||||
client.on('error', function () {
|
||||
// Depending on the Operating System
|
||||
// the socket could error or not.
|
||||
// However, it will always be closed.
|
||||
})
|
||||
|
||||
client.on('close', function () {
|
||||
t.assert.ok(true)
|
||||
done()
|
||||
})
|
||||
|
||||
client.once('data', data => {
|
||||
t.assert.match(data.toString(), /Connection:\s*keep-alive/i)
|
||||
t.assert.match(data.toString(), /200 OK/i)
|
||||
|
||||
client.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Current opened connection should not accept new incoming connections', (t, done) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify({ forceCloseConnections: false })
|
||||
fastify.get('/', (req, reply) => {
|
||||
fastify.close()
|
||||
setTimeout(() => {
|
||||
reply.send({ hello: 'world' })
|
||||
}, 250)
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, async err => {
|
||||
t.assert.ifError(err)
|
||||
const instance = new Client('http://localhost:' + fastify.server.address().port)
|
||||
let response = await instance.request({ path: '/', method: 'GET' })
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
|
||||
response = await instance.request({ path: '/', method: 'GET' })
|
||||
t.assert.strictEqual(response.statusCode, 503)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('rejected incoming connections should be logged', (t, done) => {
|
||||
t.plan(2)
|
||||
const stream = split(JSON.parse)
|
||||
const fastify = Fastify({
|
||||
forceCloseConnections: false,
|
||||
logger: {
|
||||
stream,
|
||||
level: 'info'
|
||||
}
|
||||
})
|
||||
|
||||
const messages = []
|
||||
stream.on('data', message => {
|
||||
messages.push(message)
|
||||
})
|
||||
fastify.get('/', (req, reply) => {
|
||||
fastify.close()
|
||||
setTimeout(() => {
|
||||
reply.send({ hello: 'world' })
|
||||
}, 250)
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
const instance = new Client('http://localhost:' + fastify.server.address().port)
|
||||
// initial request to trigger close
|
||||
instance.request({ path: '/', method: 'GET' })
|
||||
// subsequent request should be rejected
|
||||
instance.request({ path: '/', method: 'GET' }).then(() => {
|
||||
t.assert.ok(messages.find(message => message.msg.includes('request aborted')))
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Cannot be reopened the closed server without listen callback', async t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
await fastify.close()
|
||||
|
||||
try {
|
||||
await fastify.listen({ port: 0 })
|
||||
} catch (err) {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_REOPENED_CLOSE_SERVER')
|
||||
}
|
||||
})
|
||||
|
||||
test('Cannot be reopened the closed server has listen callback', async t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
await fastify.close()
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
reject(err)
|
||||
})
|
||||
}).catch(err => {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_REOPENED_CLOSE_SERVER')
|
||||
t.assert.ok(err)
|
||||
})
|
||||
})
|
||||
|
||||
const server = http.createServer()
|
||||
const noSupport = typeof server.closeAllConnections !== 'function'
|
||||
|
||||
test('shutsdown while keep-alive connections are active (non-async, native)', { skip: noSupport }, (t, done) => {
|
||||
t.plan(5)
|
||||
|
||||
const timeoutTime = 2 * 60 * 1000
|
||||
const fastify = Fastify({ forceCloseConnections: true })
|
||||
|
||||
fastify.server.setTimeout(timeoutTime)
|
||||
fastify.server.keepAliveTimeout = timeoutTime
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, (err, address) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const client = new Client(
|
||||
'http://localhost:' + fastify.server.address().port,
|
||||
{ keepAliveTimeout: 1 * 60 * 1000 }
|
||||
)
|
||||
client.request({ path: '/', method: 'GET' }, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(client.closed, false)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
// Due to the nature of the way we reap these keep-alive connections,
|
||||
// there hasn't been enough time before the server fully closed in order
|
||||
// for the client to have seen the socket get destroyed. The mere fact
|
||||
// that we have reached this callback is enough indication that the
|
||||
// feature being tested works as designed.
|
||||
t.assert.strictEqual(client.closed, false)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('shutsdown while keep-alive connections are active (non-async, idle, native)', { skip: noSupport }, (t, done) => {
|
||||
t.plan(5)
|
||||
|
||||
const timeoutTime = 2 * 60 * 1000
|
||||
const fastify = Fastify({ forceCloseConnections: 'idle' })
|
||||
|
||||
fastify.server.setTimeout(timeoutTime)
|
||||
fastify.server.keepAliveTimeout = timeoutTime
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, (err, address) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const client = new Client(
|
||||
'http://localhost:' + fastify.server.address().port,
|
||||
{ keepAliveTimeout: 1 * 60 * 1000 }
|
||||
)
|
||||
client.request({ path: '/', method: 'GET' }, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(client.closed, false)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
// Due to the nature of the way we reap these keep-alive connections,
|
||||
// there hasn't been enough time before the server fully closed in order
|
||||
// for the client to have seen the socket get destroyed. The mere fact
|
||||
// that we have reached this callback is enough indication that the
|
||||
// feature being tested works as designed.
|
||||
t.assert.strictEqual(client.closed, false)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('triggers on-close hook in the right order with multiple bindings', async t => {
|
||||
const expectedOrder = [1, 2, 3]
|
||||
const order = []
|
||||
const fastify = Fastify()
|
||||
|
||||
t.plan(1)
|
||||
|
||||
// Follows LIFO
|
||||
fastify.addHook('onClose', () => {
|
||||
order.push(2)
|
||||
})
|
||||
|
||||
fastify.addHook('onClose', () => {
|
||||
order.push(1)
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
fastify.close(err => {
|
||||
order.push(3)
|
||||
t.assert.deepEqual(order, expectedOrder)
|
||||
|
||||
if (err) t.assert.ifError(err)
|
||||
else resolve()
|
||||
})
|
||||
}, 2000)
|
||||
})
|
||||
})
|
||||
|
||||
test('triggers on-close hook in the right order with multiple bindings (forceCloseConnections - idle)', { skip: noSupport }, async t => {
|
||||
const expectedPayload = { hello: 'world' }
|
||||
const timeoutTime = 2 * 60 * 1000
|
||||
const expectedOrder = [1, 2]
|
||||
const order = []
|
||||
const fastify = Fastify({ forceCloseConnections: 'idle' })
|
||||
|
||||
fastify.server.setTimeout(timeoutTime)
|
||||
fastify.server.keepAliveTimeout = timeoutTime
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000)
|
||||
})
|
||||
|
||||
return expectedPayload
|
||||
})
|
||||
|
||||
fastify.addHook('onClose', () => {
|
||||
order.push(1)
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
const addresses = fastify.addresses()
|
||||
const testPlan = (addresses.length * 2) + 1
|
||||
|
||||
t.plan(testPlan)
|
||||
|
||||
for (const addr of addresses) {
|
||||
const { family, address, port } = addr
|
||||
const host = family === 'IPv6' ? `[${address}]` : address
|
||||
const client = new Client(`http://${host}:${port}`, {
|
||||
keepAliveTimeout: 1 * 60 * 1000
|
||||
})
|
||||
|
||||
client.request({ path: '/', method: 'GET' })
|
||||
.then((res) => res.body.json(), err => t.assert.ifError(err))
|
||||
.then(json => {
|
||||
t.assert.deepEqual(json, expectedPayload, 'should payload match')
|
||||
t.assert.ok(!client.closed, 'should client not be closed')
|
||||
}, err => t.assert.ifError(err))
|
||||
}
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
fastify.close(err => {
|
||||
order.push(2)
|
||||
t.assert.deepEqual(order, expectedOrder)
|
||||
|
||||
if (err) t.assert.ifError(err)
|
||||
else resolve()
|
||||
})
|
||||
}, 2000)
|
||||
})
|
||||
})
|
||||
|
||||
test('triggers on-close hook in the right order with multiple bindings (forceCloseConnections - true)', { skip: noSupport }, async t => {
|
||||
const expectedPayload = { hello: 'world' }
|
||||
const timeoutTime = 2 * 60 * 1000
|
||||
const expectedOrder = [1, 2]
|
||||
const order = []
|
||||
const fastify = Fastify({ forceCloseConnections: true })
|
||||
|
||||
fastify.server.setTimeout(timeoutTime)
|
||||
fastify.server.keepAliveTimeout = timeoutTime
|
||||
|
||||
fastify.get('/', async (req, reply) => {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000)
|
||||
})
|
||||
|
||||
return expectedPayload
|
||||
})
|
||||
|
||||
fastify.addHook('onClose', () => {
|
||||
order.push(1)
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
const addresses = fastify.addresses()
|
||||
const testPlan = (addresses.length * 2) + 1
|
||||
|
||||
t.plan(testPlan)
|
||||
|
||||
for (const addr of addresses) {
|
||||
const { family, address, port } = addr
|
||||
const host = family === 'IPv6' ? `[${address}]` : address
|
||||
const client = new Client(`http://${host}:${port}`, {
|
||||
keepAliveTimeout: 1 * 60 * 1000
|
||||
})
|
||||
|
||||
client.request({ path: '/', method: 'GET' })
|
||||
.then((res) => res.body.json(), err => t.assert.ifError(err))
|
||||
.then(json => {
|
||||
t.assert.deepEqual(json, expectedPayload, 'should payload match')
|
||||
t.assert.ok(!client.closed, 'should client not be closed')
|
||||
}, err => t.assert.ifError(err))
|
||||
}
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
fastify.close(err => {
|
||||
order.push(2)
|
||||
t.assert.deepEqual(order, expectedOrder)
|
||||
|
||||
if (err) t.assert.ifError(err)
|
||||
else resolve()
|
||||
})
|
||||
}, 2000)
|
||||
})
|
||||
})
|
||||
|
||||
test('shutsdown while keep-alive connections are active (non-async, custom)', (t, done) => {
|
||||
t.plan(5)
|
||||
|
||||
const timeoutTime = 2 * 60 * 1000
|
||||
const fastify = Fastify({
|
||||
forceCloseConnections: true,
|
||||
serverFactory (handler) {
|
||||
const server = http.createServer(handler)
|
||||
|
||||
server.closeAllConnections = null
|
||||
|
||||
return server
|
||||
}
|
||||
})
|
||||
|
||||
fastify.server.setTimeout(timeoutTime)
|
||||
fastify.server.keepAliveTimeout = timeoutTime
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, (err, address) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const client = new Client(
|
||||
'http://localhost:' + fastify.server.address().port,
|
||||
{ keepAliveTimeout: 1 * 60 * 1000 }
|
||||
)
|
||||
client.request({ path: '/', method: 'GET' }, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(client.closed, false)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
// Due to the nature of the way we reap these keep-alive connections,
|
||||
// there hasn't been enough time before the server fully closed in order
|
||||
// for the client to have seen the socket get destroyed. The mere fact
|
||||
// that we have reached this callback is enough indication that the
|
||||
// feature being tested works as designed.
|
||||
t.assert.strictEqual(client.closed, false)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('preClose callback', (t, done) => {
|
||||
t.plan(5)
|
||||
const fastify = Fastify()
|
||||
fastify.addHook('onClose', onClose)
|
||||
let preCloseCalled = false
|
||||
function onClose (instance, done) {
|
||||
t.assert.strictEqual(preCloseCalled, true)
|
||||
done()
|
||||
}
|
||||
fastify.addHook('preClose', preClose)
|
||||
|
||||
function preClose (done) {
|
||||
t.assert.ok(typeof this === typeof fastify)
|
||||
preCloseCalled = true
|
||||
done()
|
||||
}
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.ok('close callback')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('preClose async', async t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
fastify.addHook('onClose', onClose)
|
||||
let preCloseCalled = false
|
||||
async function onClose () {
|
||||
t.assert.strictEqual(preCloseCalled, true)
|
||||
}
|
||||
fastify.addHook('preClose', preClose)
|
||||
|
||||
async function preClose () {
|
||||
preCloseCalled = true
|
||||
t.assert.ok(typeof this === typeof fastify)
|
||||
}
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('preClose execution order', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
const order = []
|
||||
fastify.addHook('onClose', onClose)
|
||||
function onClose (instance, done) {
|
||||
t.assert.deepStrictEqual(order, [1, 2, 3])
|
||||
done()
|
||||
}
|
||||
|
||||
fastify.addHook('preClose', (done) => {
|
||||
setTimeout(function () {
|
||||
order.push(1)
|
||||
done()
|
||||
}, 200)
|
||||
})
|
||||
|
||||
fastify.addHook('preClose', async () => {
|
||||
await sleep(100)
|
||||
order.push(2)
|
||||
})
|
||||
|
||||
fastify.addHook('preClose', (done) => {
|
||||
setTimeout(function () {
|
||||
order.push(3)
|
||||
done()
|
||||
}, 100)
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
fastify.close((err) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.ok('close callback')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
47
node_modules/fastify/test/conditional-pino.test.js
generated
vendored
47
node_modules/fastify/test/conditional-pino.test.js
generated
vendored
@@ -1,47 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
|
||||
test("pino is not require'd if logger is not passed", t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = require('..')
|
||||
|
||||
fastify()
|
||||
|
||||
t.assert.strictEqual(require.cache[require.resolve('pino')], undefined)
|
||||
})
|
||||
|
||||
test("pino is require'd if logger is passed", t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = require('..')
|
||||
|
||||
fastify({
|
||||
logger: true
|
||||
})
|
||||
|
||||
t.assert.notStrictEqual(require.cache[require.resolve('pino')], undefined)
|
||||
})
|
||||
|
||||
test("pino is require'd if loggerInstance is passed", t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = require('..')
|
||||
|
||||
const loggerInstance = {
|
||||
fatal: (msg) => { },
|
||||
error: (msg) => { },
|
||||
warn: (msg) => { },
|
||||
info: (msg) => { },
|
||||
debug: (msg) => { },
|
||||
trace: (msg) => { },
|
||||
child: () => loggerInstance
|
||||
}
|
||||
|
||||
fastify({
|
||||
loggerInstance
|
||||
})
|
||||
|
||||
t.assert.notStrictEqual(require.cache[require.resolve('pino')], undefined)
|
||||
})
|
||||
42
node_modules/fastify/test/connection-timeout.test.js
generated
vendored
42
node_modules/fastify/test/connection-timeout.test.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const Fastify = require('..')
|
||||
const http = require('node:http')
|
||||
const { test } = require('node:test')
|
||||
|
||||
test('connectionTimeout', async t => {
|
||||
t.plan(6)
|
||||
|
||||
try {
|
||||
Fastify({ connectionTimeout: 1.3 })
|
||||
t.assert.fail('option must be an integer')
|
||||
} catch (err) {
|
||||
t.assert.ok(err)
|
||||
}
|
||||
|
||||
try {
|
||||
Fastify({ connectionTimeout: [] })
|
||||
t.assert.fail('option must be an integer')
|
||||
} catch (err) {
|
||||
t.assert.ok(err)
|
||||
}
|
||||
|
||||
const httpServer = Fastify({ connectionTimeout: 1 }).server
|
||||
t.assert.strictEqual(httpServer.timeout, 1)
|
||||
|
||||
const httpsServer = Fastify({ connectionTimeout: 2, https: {} }).server
|
||||
t.assert.strictEqual(httpsServer.timeout, 2)
|
||||
|
||||
const http2Server = Fastify({ connectionTimeout: 3, http2: true }).server
|
||||
t.assert.strictEqual(http2Server.timeout, 3)
|
||||
|
||||
const serverFactory = (handler, _) => {
|
||||
const server = http.createServer((req, res) => {
|
||||
handler(req, res)
|
||||
})
|
||||
server.setTimeout(5)
|
||||
return server
|
||||
}
|
||||
const customServer = Fastify({ connectionTimeout: 4, serverFactory }).server
|
||||
t.assert.strictEqual(customServer.timeout, 5)
|
||||
})
|
||||
1138
node_modules/fastify/test/constrained-routes.test.js
generated
vendored
1138
node_modules/fastify/test/constrained-routes.test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
174
node_modules/fastify/test/content-length.test.js
generated
vendored
174
node_modules/fastify/test/content-length.test.js
generated
vendored
@@ -1,174 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('default 413 with bodyLimit option', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify({
|
||||
bodyLimit: 10
|
||||
})
|
||||
|
||||
fastify.post('/', function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
body: {
|
||||
text: '12345678901234567890123456789012345678901234567890'
|
||||
}
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 413)
|
||||
t.assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload), {
|
||||
error: 'Payload Too Large',
|
||||
code: 'FST_ERR_CTP_BODY_TOO_LARGE',
|
||||
message: 'Request body is too large',
|
||||
statusCode: 413
|
||||
})
|
||||
})
|
||||
|
||||
test('default 400 with wrong content-length', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: {
|
||||
'content-length': 20
|
||||
},
|
||||
body: {
|
||||
text: '12345678901234567890123456789012345678901234567890'
|
||||
}
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 400)
|
||||
t.assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_INVALID_CONTENT_LENGTH',
|
||||
message: 'Request body size did not match Content-Length',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
test('custom 413 with bodyLimit option', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify({
|
||||
bodyLimit: 10
|
||||
})
|
||||
|
||||
fastify.post('/', function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(function (err, request, reply) {
|
||||
reply
|
||||
.code(err.statusCode)
|
||||
.type('application/json; charset=utf-8')
|
||||
.send(err)
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
body: {
|
||||
text: '12345678901234567890123456789012345678901234567890'
|
||||
}
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 413)
|
||||
t.assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload), {
|
||||
error: 'Payload Too Large',
|
||||
code: 'FST_ERR_CTP_BODY_TOO_LARGE',
|
||||
message: 'Request body is too large',
|
||||
statusCode: 413
|
||||
})
|
||||
})
|
||||
|
||||
test('custom 400 with wrong content-length', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(function (err, request, reply) {
|
||||
reply
|
||||
.code(err.statusCode)
|
||||
.type('application/json; charset=utf-8')
|
||||
.send(err)
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: {
|
||||
'content-length': 20
|
||||
},
|
||||
body: {
|
||||
text: '12345678901234567890123456789012345678901234567890'
|
||||
}
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 400)
|
||||
t.assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8')
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_INVALID_CONTENT_LENGTH',
|
||||
message: 'Request body size did not match Content-Length',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
test('#2214 - wrong content-length', async (t) => {
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/', async () => {
|
||||
const error = new Error('MY_ERROR_MESSAGE')
|
||||
error.headers = {
|
||||
'content-length': 2
|
||||
}
|
||||
throw error
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/'
|
||||
})
|
||||
t.assert.strictEqual(response.headers['content-length'], '' + response.rawPayload.length)
|
||||
})
|
||||
|
||||
test('#2543 - wrong content-length with errorHandler', async (t) => {
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.setErrorHandler((_error, _request, reply) => {
|
||||
reply.code(500).send({ message: 'longer than 2 bytes' })
|
||||
})
|
||||
|
||||
fastify.get('/', async () => {
|
||||
const error = new Error('MY_ERROR_MESSAGE')
|
||||
error.headers = {
|
||||
'content-length': 2
|
||||
}
|
||||
throw error
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'GET',
|
||||
path: '/'
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 500)
|
||||
t.assert.strictEqual(response.headers['content-length'], '' + response.rawPayload.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(response.payload), { message: 'longer than 2 bytes' })
|
||||
})
|
||||
732
node_modules/fastify/test/content-parser.test.js
generated
vendored
732
node_modules/fastify/test/content-parser.test.js
generated
vendored
@@ -1,732 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const keys = require('../lib/symbols')
|
||||
const { FST_ERR_CTP_ALREADY_PRESENT, FST_ERR_CTP_INVALID_TYPE, FST_ERR_CTP_INVALID_MEDIA_TYPE } = require('../lib/errors')
|
||||
|
||||
const first = function (req, payload, done) {}
|
||||
const second = function (req, payload, done) {}
|
||||
const third = function (req, payload, done) {}
|
||||
|
||||
test('hasContentTypeParser', async t => {
|
||||
await t.test('should know about internal parsers', (t, done) => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.ok(fastify.hasContentTypeParser('application/json'))
|
||||
t.assert.ok(fastify.hasContentTypeParser('text/plain'))
|
||||
t.assert.ok(fastify.hasContentTypeParser(' text/plain '))
|
||||
t.assert.ok(!fastify.hasContentTypeParser('application/jsoff'))
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('should only work with string and RegExp', t => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.addContentTypeParser(/^image\/.*/, first)
|
||||
fastify.addContentTypeParser(/^application\/.+\+xml/, first)
|
||||
fastify.addContentTypeParser('image/gif', first)
|
||||
|
||||
t.assert.ok(fastify.hasContentTypeParser('application/json'))
|
||||
t.assert.ok(fastify.hasContentTypeParser(/^image\/.*/))
|
||||
t.assert.ok(fastify.hasContentTypeParser(/^application\/.+\+xml/))
|
||||
t.assert.ok(fastify.hasContentTypeParser('image/gif'))
|
||||
t.assert.ok(!fastify.hasContentTypeParser(/^image\/.+\+xml/))
|
||||
t.assert.ok(!fastify.hasContentTypeParser('image/png'))
|
||||
t.assert.ok(!fastify.hasContentTypeParser('*'))
|
||||
t.assert.throws(
|
||||
() => fastify.hasContentTypeParser(123),
|
||||
FST_ERR_CTP_INVALID_TYPE
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test('getParser', async t => {
|
||||
await t.test('should return matching parser', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser(/^image\/.*/, first)
|
||||
fastify.addContentTypeParser(/^application\/.+\+xml/, second)
|
||||
fastify.addContentTypeParser('text/html', third)
|
||||
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('application/t+xml').fn, second)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('image/png').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, third)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html; charset=utf-8').fn, third)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html ; charset=utf-8').fn, third)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/htmlINVALID')?.fn, undefined)
|
||||
})
|
||||
|
||||
await t.test('should return matching parser with caching /1', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('text/html', first)
|
||||
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 0)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html ').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html ').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
|
||||
})
|
||||
|
||||
await t.test('should return matching parser with caching /2', t => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('text/html', first)
|
||||
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 0)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/HTML').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('TEXT/html').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 2)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('TEXT/html').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 2)
|
||||
})
|
||||
|
||||
await t.test('should return matching parser with caching /3', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser(/^text\/html(;\s*charset=[^;]+)?$/, first)
|
||||
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 1)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html;charset=utf-8').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 2)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html;charset=utf-8').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].cache.size, 2)
|
||||
})
|
||||
|
||||
await t.test('should prefer content type parser with string value', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser(/^image\/.*/, first)
|
||||
fastify.addContentTypeParser('image/gif', second)
|
||||
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('image/gif').fn, second)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('image/png').fn, first)
|
||||
})
|
||||
|
||||
await t.test('should return parser that catches all if no other is set', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('*', first)
|
||||
fastify.addContentTypeParser(/^text\/.*/, second)
|
||||
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('image/gif').fn, first)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text/html').fn, second)
|
||||
t.assert.strictEqual(fastify[keys.kContentTypeParser].getParser('text').fn, first)
|
||||
})
|
||||
|
||||
await t.test('should return undefined if no matching parser exist', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser(/^weirdType\/.+/, first)
|
||||
fastify.addContentTypeParser('application/javascript', first)
|
||||
|
||||
t.assert.ok(!fastify[keys.kContentTypeParser].getParser('application/xml'))
|
||||
t.assert.ok(!fastify[keys.kContentTypeParser].getParser('weirdType/'))
|
||||
})
|
||||
})
|
||||
|
||||
test('existingParser', async t => {
|
||||
await t.test('returns always false for "*"', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser(/^image\/.*/, first)
|
||||
fastify.addContentTypeParser(/^application\/.+\+xml/, first)
|
||||
fastify.addContentTypeParser('text/html', first)
|
||||
|
||||
t.assert.ok(!fastify[keys.kContentTypeParser].existingParser('*'))
|
||||
|
||||
fastify.addContentTypeParser('*', first)
|
||||
|
||||
t.assert.ok(!fastify[keys.kContentTypeParser].existingParser('*'))
|
||||
})
|
||||
|
||||
await t.test('let you override the default parser once', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('application/json', first)
|
||||
fastify.addContentTypeParser('text/plain', first)
|
||||
|
||||
t.assert.throws(
|
||||
() => fastify.addContentTypeParser('application/json', first),
|
||||
FST_ERR_CTP_ALREADY_PRESENT
|
||||
)
|
||||
t.assert.throws(
|
||||
() => fastify.addContentTypeParser('text/plain', first),
|
||||
FST_ERR_CTP_ALREADY_PRESENT
|
||||
)
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
fastify.addContentTypeParser(/^image\/.*/, first)
|
||||
fastify.addContentTypeParser(/^application\/.+\+xml/, first)
|
||||
fastify.addContentTypeParser('text/html', first)
|
||||
|
||||
t.assert.ok(contentTypeParser.existingParser(/^image\/.*/))
|
||||
t.assert.ok(contentTypeParser.existingParser('text/html'))
|
||||
t.assert.ok(contentTypeParser.existingParser(/^application\/.+\+xml/))
|
||||
t.assert.ok(!contentTypeParser.existingParser('application/json'))
|
||||
t.assert.ok(!contentTypeParser.existingParser('text/plain'))
|
||||
t.assert.ok(!contentTypeParser.existingParser('image/png'))
|
||||
t.assert.ok(!contentTypeParser.existingParser(/^application\/.+\+json/))
|
||||
})
|
||||
|
||||
test('add', async t => {
|
||||
await t.test('should only accept string and RegExp', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
t.assert.ifError(contentTypeParser.add('test', {}, first))
|
||||
t.assert.ifError(contentTypeParser.add(/test/, {}, first))
|
||||
t.assert.throws(
|
||||
() => contentTypeParser.add({}, {}, first),
|
||||
FST_ERR_CTP_INVALID_TYPE,
|
||||
'The content type should be a string or a RegExp'
|
||||
)
|
||||
t.assert.throws(
|
||||
() => contentTypeParser.add(1, {}, first),
|
||||
FST_ERR_CTP_INVALID_TYPE,
|
||||
'The content type should be a string or a RegExp'
|
||||
)
|
||||
})
|
||||
|
||||
await t.test('should set "*" as parser that catches all', t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
contentTypeParser.add('*', {}, first)
|
||||
t.assert.strictEqual(contentTypeParser.customParsers.get('').fn, first)
|
||||
})
|
||||
|
||||
await t.test('should lowercase contentTypeParser name', async t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
fastify.addContentTypeParser('text/html', function (req, done) {
|
||||
done()
|
||||
})
|
||||
try {
|
||||
fastify.addContentTypeParser('TEXT/html', function (req, done) {
|
||||
done()
|
||||
})
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.message, FST_ERR_CTP_ALREADY_PRESENT('text/html').message)
|
||||
}
|
||||
})
|
||||
|
||||
await t.test('should trim contentTypeParser name', async t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
fastify.addContentTypeParser('text/html', function (req, done) {
|
||||
done()
|
||||
})
|
||||
try {
|
||||
fastify.addContentTypeParser(' text/html', function (req, done) {
|
||||
done()
|
||||
})
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.message, FST_ERR_CTP_ALREADY_PRESENT('text/html').message)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('non-Error thrown from content parser is properly handled', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
const throwable = 'test'
|
||||
const payload = 'error'
|
||||
|
||||
fastify.addContentTypeParser('text/test', (request, payload, done) => {
|
||||
done(throwable)
|
||||
})
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
})
|
||||
|
||||
fastify.setErrorHandler((err, req, res) => {
|
||||
t.assert.strictEqual(err, throwable)
|
||||
|
||||
res.send(payload)
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
headers: { 'Content-Type': 'text/test' },
|
||||
body: 'some text'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.payload, payload)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('Error thrown 415 from content type is null and make post request to server', (t, done) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
const errMsg = new FST_ERR_CTP_INVALID_MEDIA_TYPE(undefined).message
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
body: 'some text'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 415)
|
||||
t.assert.strictEqual(JSON.parse(res.body).message, errMsg)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('remove', async t => {
|
||||
await t.test('should remove default parser', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
t.assert.ok(contentTypeParser.remove('application/json'))
|
||||
t.assert.ok(!contentTypeParser.customParsers['application/json'])
|
||||
t.assert.ok(!contentTypeParser.parserList.find(parser => parser === 'application/json'))
|
||||
t.assert.ok(contentTypeParser.remove(' text/plain '))
|
||||
t.assert.ok(!contentTypeParser.customParsers['text/plain'])
|
||||
t.assert.ok(!contentTypeParser.parserList.find(parser => parser === 'text/plain'))
|
||||
})
|
||||
|
||||
await t.test('should remove RegExp parser', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.addContentTypeParser(/^text\/*/, first)
|
||||
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
t.assert.ok(contentTypeParser.remove(/^text\/*/))
|
||||
t.assert.ok(!contentTypeParser.customParsers[/^text\/*/])
|
||||
t.assert.ok(!contentTypeParser.parserRegExpList.find(parser => parser.toString() === /^text\/*/.toString()))
|
||||
})
|
||||
|
||||
await t.test('should throw an error if content type is neither string nor RegExp', t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
t.assert.throws(() => fastify[keys.kContentTypeParser].remove(12), FST_ERR_CTP_INVALID_TYPE)
|
||||
})
|
||||
|
||||
await t.test('should return false if content type does not exist', t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
t.assert.ok(!fastify[keys.kContentTypeParser].remove('image/png'))
|
||||
})
|
||||
|
||||
await t.test('should not remove any content type parser if content type does not exist', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
t.assert.ok(!contentTypeParser.remove('image/png'))
|
||||
t.assert.strictEqual(contentTypeParser.customParsers.size, 2)
|
||||
})
|
||||
})
|
||||
|
||||
test('remove all should remove all existing parsers and reset cache', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.addContentTypeParser('application/xml', first)
|
||||
fastify.addContentTypeParser(/^image\/.*/, first)
|
||||
|
||||
const contentTypeParser = fastify[keys.kContentTypeParser]
|
||||
|
||||
contentTypeParser.getParser('application/xml') // fill cache with one entry
|
||||
contentTypeParser.removeAll()
|
||||
|
||||
t.assert.strictEqual(contentTypeParser.cache.size, 0)
|
||||
t.assert.strictEqual(contentTypeParser.parserList.length, 0)
|
||||
t.assert.strictEqual(contentTypeParser.parserRegExpList.length, 0)
|
||||
t.assert.strictEqual(Object.keys(contentTypeParser.customParsers).length, 0)
|
||||
})
|
||||
|
||||
test('Safeguard against malicious content-type / 1', async t => {
|
||||
const badNames = Object.getOwnPropertyNames({}.__proto__) // eslint-disable-line
|
||||
t.plan(badNames.length)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
for (const prop of badNames) {
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': prop
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 415)
|
||||
}
|
||||
})
|
||||
|
||||
test('Safeguard against malicious content-type / 2', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': '\\u0063\\u006fnstructor'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 415)
|
||||
})
|
||||
|
||||
test('Safeguard against malicious content-type / 3', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'constructor; charset=utf-8'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 415)
|
||||
})
|
||||
|
||||
test('Safeguard against content-type spoofing - string', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser('text/plain', function (request, body, done) {
|
||||
t.assert.ok('should be called')
|
||||
done(null, body)
|
||||
})
|
||||
fastify.addContentTypeParser('application/json', function (request, body, done) {
|
||||
t.assert.fail('shouldn\'t be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'text/plain; content-type="application/json"'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('Warning against improper content-type - regexp', async t => {
|
||||
await t.test('improper regex - text plain', (t, done) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
process.on('warning', onWarning)
|
||||
function onWarning (warning) {
|
||||
t.assert.strictEqual(warning.name, 'FastifySecurity')
|
||||
t.assert.strictEqual(warning.code, 'FSTSEC001')
|
||||
done()
|
||||
}
|
||||
t.after(() => process.removeListener('warning', onWarning))
|
||||
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser(/text\/plain/, function (request, body, done) {
|
||||
done(null, body)
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('improper regex - application json', (t, done) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
process.on('warning', onWarning)
|
||||
function onWarning (warning) {
|
||||
t.assert.strictEqual(warning.name, 'FastifySecurity')
|
||||
t.assert.strictEqual(warning.code, 'FSTSEC001')
|
||||
done()
|
||||
}
|
||||
t.after(() => process.removeListener('warning', onWarning))
|
||||
|
||||
fastify.removeAllContentTypeParsers()
|
||||
|
||||
fastify.addContentTypeParser(/application\/json/, function (request, body, done) {
|
||||
done(null, body)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('content-type match parameters - string 1', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser('text/plain; charset=utf8', function (request, body, done) {
|
||||
t.assert.fail('shouldn\'t be called')
|
||||
done(null, body)
|
||||
})
|
||||
fastify.addContentTypeParser('application/json; charset=utf8', function (request, body, done) {
|
||||
t.assert.ok('should be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=utf8'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('content-type match parameters - regexp', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser(/application\/json; charset=utf8/, function (request, body, done) {
|
||||
t.assert.ok('should be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=utf8'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('content-type fail when parameters not match - string 1', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser('application/json; charset=utf8; foo=bar', function (request, body, done) {
|
||||
t.assert.fail('shouldn\'t be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=utf8'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 415)
|
||||
})
|
||||
|
||||
test('content-type fail when parameters not match - string 2', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser('application/json; charset=utf8; foo=bar', function (request, body, done) {
|
||||
t.assert.fail('shouldn\'t be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=utf8; foo=baz'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 415)
|
||||
})
|
||||
|
||||
test('content-type fail when parameters not match - regexp', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser(/application\/json; charset=utf8; foo=bar/, function (request, body, done) {
|
||||
t.assert.fail('shouldn\'t be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=utf8'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 415)
|
||||
})
|
||||
|
||||
// Refs: https://github.com/fastify/fastify/issues/4495
|
||||
test('content-type regexp list should be cloned when plugin override', async t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser(/^image\/.*/, { parseAs: 'buffer' }, (req, payload, done) => {
|
||||
done(null, payload)
|
||||
})
|
||||
|
||||
fastify.register(function plugin (fastify, options, done) {
|
||||
fastify.post('/', function (request, reply) {
|
||||
reply.type(request.headers['content-type']).send(request.body)
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
{
|
||||
const { payload, headers, statusCode } = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
payload: 'jpeg',
|
||||
headers: { 'content-type': 'image/jpeg' }
|
||||
})
|
||||
t.assert.strictEqual(statusCode, 200)
|
||||
t.assert.strictEqual(headers['content-type'], 'image/jpeg')
|
||||
t.assert.strictEqual(payload, 'jpeg')
|
||||
}
|
||||
|
||||
{
|
||||
const { payload, headers, statusCode } = await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
payload: 'png',
|
||||
headers: { 'content-type': 'image/png' }
|
||||
})
|
||||
t.assert.strictEqual(statusCode, 200)
|
||||
t.assert.strictEqual(headers['content-type'], 'image/png')
|
||||
t.assert.strictEqual(payload, 'png')
|
||||
}
|
||||
})
|
||||
|
||||
test('edge case content-type - ;', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser(';', function (request, body, done) {
|
||||
t.assert.fail('should not be called')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.post('/', async () => {
|
||||
return 'ok'
|
||||
})
|
||||
|
||||
await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'application/json; foo=bar; charset=utf8'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: {
|
||||
'content-type': 'image/jpeg'
|
||||
},
|
||||
body: ''
|
||||
})
|
||||
|
||||
t.assert.ok('end')
|
||||
})
|
||||
42
node_modules/fastify/test/content-type.test.js
generated
vendored
42
node_modules/fastify/test/content-type.test.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('should remove content-type for setErrorHandler', async t => {
|
||||
t.plan(8)
|
||||
let count = 0
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.setErrorHandler(function (error, request, reply) {
|
||||
t.assert.strictEqual(error.message, 'kaboom')
|
||||
t.assert.strictEqual(reply.hasHeader('content-type'), false)
|
||||
reply.code(400).send({ foo: 'bar' })
|
||||
})
|
||||
fastify.addHook('onSend', async function (request, reply, payload) {
|
||||
count++
|
||||
t.assert.strictEqual(typeof payload, 'string')
|
||||
switch (count) {
|
||||
case 1: {
|
||||
// should guess the correct content-type based on payload
|
||||
t.assert.strictEqual(reply.getHeader('content-type'), 'text/plain; charset=utf-8')
|
||||
throw Error('kaboom')
|
||||
}
|
||||
case 2: {
|
||||
// should guess the correct content-type based on payload
|
||||
t.assert.strictEqual(reply.getHeader('content-type'), 'application/json; charset=utf-8')
|
||||
return payload
|
||||
}
|
||||
default: {
|
||||
t.fail('should not reach')
|
||||
}
|
||||
}
|
||||
})
|
||||
fastify.get('/', function (request, reply) {
|
||||
reply.send('plain-text')
|
||||
})
|
||||
|
||||
const { statusCode, body } = await fastify.inject({ method: 'GET', path: '/' })
|
||||
t.assert.strictEqual(statusCode, 400)
|
||||
t.assert.strictEqual(body, JSON.stringify({ foo: 'bar' }))
|
||||
})
|
||||
164
node_modules/fastify/test/context-config.test.js
generated
vendored
164
node_modules/fastify/test/context-config.test.js
generated
vendored
@@ -1,164 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
|
||||
const { kRouteContext } = require('../lib/symbols')
|
||||
const Fastify = require('..')
|
||||
|
||||
const schema = {
|
||||
schema: { },
|
||||
config: {
|
||||
value1: 'foo',
|
||||
value2: true
|
||||
}
|
||||
}
|
||||
|
||||
function handler (req, reply) {
|
||||
reply.send(reply[kRouteContext].config)
|
||||
}
|
||||
|
||||
test('config', async t => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/get', {
|
||||
schema: schema.schema,
|
||||
config: Object.assign({}, schema.config)
|
||||
}, handler)
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/route',
|
||||
schema: schema.schema,
|
||||
handler,
|
||||
config: Object.assign({}, schema.config)
|
||||
})
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/no-config',
|
||||
schema: schema.schema,
|
||||
handler
|
||||
})
|
||||
|
||||
let response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/route'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), Object.assign({ url: '/route', method: 'GET' }, schema.config))
|
||||
|
||||
response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/route'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), Object.assign({ url: '/route', method: 'GET' }, schema.config))
|
||||
|
||||
response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/no-config'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), { url: '/no-config', method: 'GET' })
|
||||
})
|
||||
|
||||
test('config with exposeHeadRoutes', async t => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify({ exposeHeadRoutes: true })
|
||||
|
||||
fastify.get('/get', {
|
||||
schema: schema.schema,
|
||||
config: Object.assign({}, schema.config)
|
||||
}, handler)
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/route',
|
||||
schema: schema.schema,
|
||||
handler,
|
||||
config: Object.assign({}, schema.config)
|
||||
})
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/no-config',
|
||||
schema: schema.schema,
|
||||
handler
|
||||
})
|
||||
|
||||
let response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/get'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), Object.assign({ url: '/get', method: 'GET' }, schema.config))
|
||||
|
||||
response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/route'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), Object.assign({ url: '/route', method: 'GET' }, schema.config))
|
||||
|
||||
response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/no-config'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), { url: '/no-config', method: 'GET' })
|
||||
})
|
||||
|
||||
test('config without exposeHeadRoutes', async t => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify({ exposeHeadRoutes: false })
|
||||
|
||||
fastify.get('/get', {
|
||||
schema: schema.schema,
|
||||
config: Object.assign({}, schema.config)
|
||||
}, handler)
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/route',
|
||||
schema: schema.schema,
|
||||
handler,
|
||||
config: Object.assign({}, schema.config)
|
||||
})
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/no-config',
|
||||
schema: schema.schema,
|
||||
handler
|
||||
})
|
||||
|
||||
let response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/get'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), Object.assign({ url: '/get', method: 'GET' }, schema.config))
|
||||
|
||||
response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/route'
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), Object.assign({ url: '/route', method: 'GET' }, schema.config))
|
||||
|
||||
response = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/no-config'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.json(), { url: '/no-config', method: 'GET' })
|
||||
})
|
||||
118
node_modules/fastify/test/custom-http-server.test.js
generated
vendored
118
node_modules/fastify/test/custom-http-server.test.js
generated
vendored
@@ -1,118 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const http = require('node:http')
|
||||
const dns = require('node:dns').promises
|
||||
const Fastify = require('..')
|
||||
const { FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE } = require('../lib/errors')
|
||||
|
||||
async function setup () {
|
||||
const localAddresses = await dns.lookup('localhost', { all: true })
|
||||
|
||||
test('Should support a custom http server', { skip: localAddresses.length < 1 }, async t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify({
|
||||
serverFactory: (handler, opts) => {
|
||||
t.assert.ok(opts.serverFactory, 'it is called once for localhost')
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
req.custom = true
|
||||
handler(req, res)
|
||||
})
|
||||
|
||||
return server
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.raw.custom)
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
test('Should not allow forceCloseConnection=idle if the server does not support closeIdleConnections', t => {
|
||||
t.plan(1)
|
||||
|
||||
t.assert.throws(
|
||||
() => {
|
||||
Fastify({
|
||||
forceCloseConnections: 'idle',
|
||||
serverFactory (handler, opts) {
|
||||
return {
|
||||
on () {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE,
|
||||
"Cannot set forceCloseConnections to 'idle' as your HTTP server does not support closeIdleConnections method"
|
||||
)
|
||||
})
|
||||
|
||||
test('Should accept user defined serverFactory and ignore secondary server creation', async t => {
|
||||
const server = http.createServer(() => { })
|
||||
t.after(() => new Promise(resolve => server.close(resolve)))
|
||||
const app = Fastify({
|
||||
serverFactory: () => server
|
||||
})
|
||||
await t.assert.doesNotReject(async () => { await app.listen({ port: 0 }) })
|
||||
})
|
||||
|
||||
test('Should not call close on the server if it has not created it', async t => {
|
||||
const server = http.createServer()
|
||||
|
||||
const serverFactory = (handler, opts) => {
|
||||
server.on('request', handler)
|
||||
return server
|
||||
}
|
||||
|
||||
const fastify = Fastify({ serverFactory })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
server.listen(0)
|
||||
server.on('listening', resolve)
|
||||
server.on('error', reject)
|
||||
})
|
||||
|
||||
const address = server.address()
|
||||
t.assert.strictEqual(server.listening, true)
|
||||
await fastify.close()
|
||||
|
||||
t.assert.strictEqual(server.listening, true)
|
||||
t.assert.deepStrictEqual(server.address(), address)
|
||||
t.assert.deepStrictEqual(fastify.addresses(), [address])
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
server.close((err) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
t.assert.strictEqual(server.listening, false)
|
||||
t.assert.deepStrictEqual(server.address(), null)
|
||||
})
|
||||
}
|
||||
|
||||
setup()
|
||||
59
node_modules/fastify/test/custom-parser-async.test.js
generated
vendored
59
node_modules/fastify/test/custom-parser-async.test.js
generated
vendored
@@ -1,59 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('contentTypeParser should add a custom async parser', async t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.options('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/jsoff', async function (req, payload) {
|
||||
const res = await new Promise((resolve, reject) => resolve(payload))
|
||||
return res
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('in POST', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
},
|
||||
body: '{"hello":"world"}'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('in OPTIONS', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'OPTIONS',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
},
|
||||
body: '{"hello":"world"}'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
})
|
||||
701
node_modules/fastify/test/custom-parser.0.test.js
generated
vendored
701
node_modules/fastify/test/custom-parser.0.test.js
generated
vendored
@@ -1,701 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
const jsonParser = require('fast-json-body')
|
||||
const { plainTextParser } = require('./helper')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('contentTypeParser method should exist', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
t.assert.ok(fastify.addContentTypeParser)
|
||||
})
|
||||
|
||||
test('contentTypeParser should add a custom parser', async (t) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.options('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/jsoff', function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
await t.test('in POST', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('in OPTIONS', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'OPTIONS',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, JSON.stringify({ hello: 'world' }))
|
||||
})
|
||||
})
|
||||
|
||||
test('contentTypeParser should handle multiple custom parsers', async (t) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.post('/hello', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
function customParser (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
}
|
||||
|
||||
fastify.addContentTypeParser('application/jsoff', customParser)
|
||||
fastify.addContentTypeParser('application/ffosj', customParser)
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.deepStrictEqual(await result1.json(), { hello: 'world' })
|
||||
|
||||
const result2 = await fetch(fastifyServer + '/hello', {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/ffosj'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
|
||||
t.assert.deepStrictEqual(await result2.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
test('contentTypeParser should handle an array of custom contentTypes', async (t) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.post('/hello', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
function customParser (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
}
|
||||
|
||||
fastify.addContentTypeParser(['application/jsoff', 'application/ffosj'], customParser)
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.deepStrictEqual(await result1.json(), { hello: 'world' })
|
||||
|
||||
const result2 = await fetch(fastifyServer + '/hello', {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/ffosj'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.deepStrictEqual(await result2.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
test('contentTypeParser should handle errors', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/jsoff', function (req, payload, done) {
|
||||
done(new Error('kaboom!'), {})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 500)
|
||||
})
|
||||
|
||||
test('contentTypeParser should support encapsulation', (t, testDone) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register((instance, opts, done) => {
|
||||
instance.addContentTypeParser('application/jsoff', () => {})
|
||||
t.assert.ok(instance.hasContentTypeParser('application/jsoff'))
|
||||
|
||||
instance.register((instance, opts, done) => {
|
||||
instance.addContentTypeParser('application/ffosj', () => {})
|
||||
t.assert.ok(instance.hasContentTypeParser('application/jsoff'))
|
||||
t.assert.ok(instance.hasContentTypeParser('application/ffosj'))
|
||||
done()
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.ok(!fastify.hasContentTypeParser('application/jsoff'))
|
||||
t.assert.ok(!fastify.hasContentTypeParser('application/ffosj'))
|
||||
testDone()
|
||||
})
|
||||
})
|
||||
|
||||
test('contentTypeParser should support encapsulation, second try', async (t) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register((instance, opts, done) => {
|
||||
instance.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
instance.addContentTypeParser('application/jsoff', function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, JSON.stringify({ hello: 'world' }))
|
||||
})
|
||||
|
||||
test('contentTypeParser shouldn\'t support request with undefined "Content-Type"', async (t) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/jsoff', function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'unknown content type!',
|
||||
headers: {
|
||||
'Content-Type': undefined
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
})
|
||||
|
||||
test('the content type should be a string or RegExp', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser(null, () => {})
|
||||
t.assert.fail()
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_INVALID_TYPE')
|
||||
t.assert.strictEqual(err.message, 'The content type should be a string or a RegExp')
|
||||
}
|
||||
})
|
||||
|
||||
test('the content type cannot be an empty string', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser('', () => {})
|
||||
t.assert.fail()
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_EMPTY_TYPE')
|
||||
t.assert.strictEqual(err.message, 'The content type cannot be an empty string')
|
||||
}
|
||||
})
|
||||
|
||||
test('the content type handler should be a function', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser('aaa', null)
|
||||
t.assert.fail()
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_INVALID_HANDLER')
|
||||
t.assert.strictEqual(err.message, 'The content type handler should be a function')
|
||||
}
|
||||
})
|
||||
|
||||
test('catch all content type parser', async (t) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('*', function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.strictEqual(await result1.text(), 'hello')
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello',
|
||||
headers: {
|
||||
'Content-Type': 'very-weird-content-type'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.strictEqual(await result2.text(), 'hello')
|
||||
})
|
||||
|
||||
test('catch all content type parser should not interfere with other conte type parsers', async (t) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('*', function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data)
|
||||
})
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/jsoff', function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.deepStrictEqual(await result1.json(), { hello: 'world' })
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello',
|
||||
headers: {
|
||||
'Content-Type': 'very-weird-content-type'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.strictEqual(await result2.text(), 'hello')
|
||||
})
|
||||
|
||||
// Issue 492 https://github.com/fastify/fastify/issues/492
|
||||
test('\'*\' catch undefined Content-Type requests', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.addContentTypeParser('*', function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data)
|
||||
})
|
||||
})
|
||||
|
||||
fastify.post('/', (req, res) => {
|
||||
// Needed to avoid json stringify
|
||||
res.type('text/plain').send(req.body)
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const fileStream = fs.createReadStream(__filename)
|
||||
|
||||
const result = await fetch(fastifyServer + '/', {
|
||||
method: 'POST',
|
||||
body: fileStream,
|
||||
duplex: 'half'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), fs.readFileSync(__filename).toString())
|
||||
})
|
||||
|
||||
test('cannot add custom parser after binding', (t, testDone) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (req, res) => {
|
||||
res.type('text/plain').send(req.body)
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, function (err) {
|
||||
t.assert.ifError(err)
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser('*', () => {})
|
||||
t.assert.fail()
|
||||
} catch (e) {
|
||||
t.assert.ok(true)
|
||||
testDone()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('Can override the default json parser', async (t) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, '{"hello":"world"}')
|
||||
})
|
||||
|
||||
test('Can override the default plain text parser', async (t) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/plain', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
plainTextParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, 'hello world')
|
||||
})
|
||||
|
||||
test('Can override the default json parser in a plugin', async (t) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register((instance, opts, done) => {
|
||||
instance.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
instance.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, '{"hello":"world"}')
|
||||
})
|
||||
|
||||
test('Can\'t override the json parser multiple times', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_ALREADY_PRESENT')
|
||||
t.assert.strictEqual(err.message, 'Content type parser \'application/json\' already present.')
|
||||
}
|
||||
})
|
||||
|
||||
test('Can\'t override the plain text parser multiple times', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('text/plain', function (req, payload, done) {
|
||||
plainTextParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser('text/plain', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
plainTextParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_ALREADY_PRESENT')
|
||||
t.assert.strictEqual(err.message, 'Content type parser \'text/plain\' already present.')
|
||||
}
|
||||
})
|
||||
|
||||
test('Should get the body as string', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
|
||||
t.assert.ok('called')
|
||||
t.assert.ok(typeof body === 'string')
|
||||
try {
|
||||
const json = JSON.parse(body)
|
||||
done(null, json)
|
||||
} catch (err) {
|
||||
err.statusCode = 400
|
||||
done(err, undefined)
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, '{"hello":"world"}')
|
||||
})
|
||||
|
||||
test('Should return defined body with no custom parser defined and content type = \'text/plain\'', async (t) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(body, 'hello world')
|
||||
})
|
||||
|
||||
test('Should have typeof body object with no custom parser defined, no body defined and content type = \'text/plain\'', async (t) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), '')
|
||||
})
|
||||
301
node_modules/fastify/test/custom-parser.1.test.js
generated
vendored
301
node_modules/fastify/test/custom-parser.1.test.js
generated
vendored
@@ -1,301 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
const jsonParser = require('fast-json-body')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('Should have typeof body object with no custom parser defined, null body and content type = \'text/plain\'', async (t) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: null,
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), '')
|
||||
})
|
||||
|
||||
test('Should have typeof body object with no custom parser defined, undefined body and content type = \'text/plain\'', async (t) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: undefined,
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), '')
|
||||
})
|
||||
|
||||
test('Should get the body as string /1', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/plain', { parseAs: 'string' }, function (req, body, done) {
|
||||
t.assert.ok('called')
|
||||
t.assert.ok(typeof body === 'string')
|
||||
try {
|
||||
const plainText = body
|
||||
done(null, plainText)
|
||||
} catch (err) {
|
||||
err.statusCode = 400
|
||||
done(err, undefined)
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), 'hello world')
|
||||
})
|
||||
|
||||
test('Should get the body as string /2', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/plain/test', { parseAs: 'string' }, function (req, body, done) {
|
||||
t.assert.ok('called')
|
||||
t.assert.ok(typeof body === 'string')
|
||||
try {
|
||||
const plainText = body
|
||||
done(null, plainText)
|
||||
} catch (err) {
|
||||
err.statusCode = 400
|
||||
done(err, undefined)
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': ' text/plain/test '
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), 'hello world')
|
||||
})
|
||||
|
||||
test('Should get the body as buffer', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, function (req, body, done) {
|
||||
t.assert.ok('called')
|
||||
t.assert.ok(body instanceof Buffer)
|
||||
try {
|
||||
const json = JSON.parse(body)
|
||||
done(null, json)
|
||||
} catch (err) {
|
||||
err.statusCode = 400
|
||||
done(err, undefined)
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), '{"hello":"world"}')
|
||||
})
|
||||
|
||||
test('Should get the body as buffer', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/plain', { parseAs: 'buffer' }, function (req, body, done) {
|
||||
t.assert.ok('called')
|
||||
t.assert.ok(body instanceof Buffer)
|
||||
try {
|
||||
const plainText = body
|
||||
done(null, plainText)
|
||||
} catch (err) {
|
||||
err.statusCode = 400
|
||||
done(err, undefined)
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), 'hello world')
|
||||
})
|
||||
|
||||
test('Should parse empty bodies as a string', async (t) => {
|
||||
t.plan(8)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addContentTypeParser('text/plain', { parseAs: 'string' }, (req, body, done) => {
|
||||
t.assert.strictEqual(body, '')
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
fastify.route({
|
||||
method: ['POST', 'DELETE'],
|
||||
url: '/',
|
||||
handler (request, reply) {
|
||||
reply.send(request.body)
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const postResult = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(postResult.ok)
|
||||
t.assert.strictEqual(postResult.status, 200)
|
||||
t.assert.strictEqual(await postResult.text(), '')
|
||||
|
||||
const deleteResult = await fetch(fastifyServer, {
|
||||
method: 'DELETE',
|
||||
body: '',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
'Content-Length': '0'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(deleteResult.ok)
|
||||
t.assert.strictEqual(deleteResult.status, 200)
|
||||
t.assert.strictEqual(await deleteResult.text(), '')
|
||||
})
|
||||
|
||||
test('Should parse empty bodies as a buffer', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/plain', { parseAs: 'buffer' }, function (req, body, done) {
|
||||
t.assert.ok(body instanceof Buffer)
|
||||
t.assert.strictEqual(body.length, 0)
|
||||
done(null, body)
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual((await result.arrayBuffer()).byteLength, 0)
|
||||
})
|
||||
|
||||
test('The charset should not interfere with the content type handling', async (t) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), '{"hello":"world"}')
|
||||
})
|
||||
91
node_modules/fastify/test/custom-parser.2.test.js
generated
vendored
91
node_modules/fastify/test/custom-parser.2.test.js
generated
vendored
@@ -1,91 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('Wrong parseAs parameter', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
try {
|
||||
fastify.addContentTypeParser('application/json', { parseAs: 'fireworks' }, () => {})
|
||||
t.assert.fail('should throw')
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_CTP_INVALID_PARSE_TYPE')
|
||||
t.assert.strictEqual(err.message, "The body parser can only parse your data as 'string' or 'buffer', you asked 'fireworks' which is not supported.")
|
||||
}
|
||||
})
|
||||
|
||||
test('Should allow defining the bodyLimit per parser', async (t) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(
|
||||
'x/foo',
|
||||
{ parseAs: 'string', bodyLimit: 5 },
|
||||
function (req, body, done) {
|
||||
t.assert.fail('should not be invoked')
|
||||
done()
|
||||
}
|
||||
)
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '1234567890',
|
||||
headers: {
|
||||
'Content-Type': 'x/foo'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.deepStrictEqual(await result.json(), {
|
||||
statusCode: 413,
|
||||
code: 'FST_ERR_CTP_BODY_TOO_LARGE',
|
||||
error: 'Payload Too Large',
|
||||
message: 'Request body is too large'
|
||||
})
|
||||
})
|
||||
|
||||
test('route bodyLimit should take precedence over a custom parser bodyLimit', async (t) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', { bodyLimit: 5 }, (request, reply) => {
|
||||
reply.send(request.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(
|
||||
'x/foo',
|
||||
{ parseAs: 'string', bodyLimit: 100 },
|
||||
function (req, body, done) {
|
||||
t.assert.fail('should not be invoked')
|
||||
done()
|
||||
}
|
||||
)
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '1234567890',
|
||||
headers: { 'Content-Type': 'x/foo' }
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.deepStrictEqual(await result.json(), {
|
||||
statusCode: 413,
|
||||
code: 'FST_ERR_CTP_BODY_TOO_LARGE',
|
||||
error: 'Payload Too Large',
|
||||
message: 'Request body is too large'
|
||||
})
|
||||
})
|
||||
208
node_modules/fastify/test/custom-parser.3.test.js
generated
vendored
208
node_modules/fastify/test/custom-parser.3.test.js
generated
vendored
@@ -1,208 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const jsonParser = require('fast-json-body')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('should be able to use default parser for extra content type', async t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (request, reply) => {
|
||||
reply.send(request.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore'))
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'text/json'
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
t.assert.deepStrictEqual(await response.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
test('contentTypeParser should add a custom parser with RegExp value', async (t) => {
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.options('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/.*\+json$/, function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('in POST', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/vnd.test+json'
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(body.toString(), JSON.stringify({ hello: 'world' }))
|
||||
})
|
||||
|
||||
await t.test('in OPTIONS', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'OPTIONS',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'weird/content-type+json'
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(body.toString(), JSON.stringify({ hello: 'world' }))
|
||||
})
|
||||
})
|
||||
|
||||
test('contentTypeParser should add multiple custom parsers with RegExp values', async t => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/.*\+json$/, function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/.*\+xml$/, function (req, payload, done) {
|
||||
done(null, 'xml')
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/.*\+myExtension$/i, function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data + 'myExtension')
|
||||
})
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
{
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/vnd.hello+json'
|
||||
}
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.payload.toString(), '{"hello":"world"}')
|
||||
}
|
||||
|
||||
{
|
||||
const response = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
body: '{"hello":"world"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/test+xml'
|
||||
}
|
||||
})
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.payload.toString(), 'xml')
|
||||
}
|
||||
|
||||
await fastify.inject({
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
payload: 'abcdefg',
|
||||
headers: {
|
||||
'Content-Type': 'application/+myExtension'
|
||||
}
|
||||
}).then((response) => {
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.deepStrictEqual(response.payload.toString(), 'abcdefgmyExtension')
|
||||
}).catch((err) => {
|
||||
t.assert.ifError(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('catch all content type parser should not interfere with content type parser', async t => {
|
||||
t.plan(9)
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('*', function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data)
|
||||
})
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/^application\/.*/, function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('text/html', function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data + 'html')
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const assertions = [
|
||||
{ body: '{"myKey":"myValue"}', contentType: 'application/json', expected: JSON.stringify({ myKey: 'myValue' }) },
|
||||
{ body: 'body', contentType: 'very-weird-content-type', expected: 'body' },
|
||||
{ body: 'my text', contentType: 'text/html', expected: 'my texthtml' }
|
||||
]
|
||||
|
||||
for (const { body, contentType, expected } of assertions) {
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body,
|
||||
headers: {
|
||||
'Content-Type': contentType
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
t.assert.deepStrictEqual(await response.text(), expected)
|
||||
}
|
||||
})
|
||||
218
node_modules/fastify/test/custom-parser.4.test.js
generated
vendored
218
node_modules/fastify/test/custom-parser.4.test.js
generated
vendored
@@ -1,218 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
const jsonParser = require('fast-json-body')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('should prefer string content types over RegExp ones', async (t) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify()
|
||||
t.after(() => { fastify.close() })
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/^application\/.*/, function (req, payload, done) {
|
||||
let data = ''
|
||||
payload.on('data', chunk => { data += chunk })
|
||||
payload.on('end', () => {
|
||||
done(null, data)
|
||||
})
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"k1":"myValue", "k2": "myValue"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.equal(await result1.text(), JSON.stringify({ k1: 'myValue', k2: 'myValue' }))
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'javascript',
|
||||
headers: {
|
||||
'Content-Type': 'application/javascript'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.equal(await result2.text(), 'javascript')
|
||||
})
|
||||
|
||||
test('removeContentTypeParser should support arrays of content types to remove', async (t) => {
|
||||
t.plan(7)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.addContentTypeParser('application/xml', function (req, payload, done) {
|
||||
payload.on('data', () => {})
|
||||
payload.on('end', () => {
|
||||
done(null, 'xml')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.addContentTypeParser(/^image\/.*/, function (req, payload, done) {
|
||||
payload.on('data', () => {})
|
||||
payload.on('end', () => {
|
||||
done(null, 'image')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.removeContentTypeParser([/^image\/.*/, 'application/json'])
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result1 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '<?xml version="1.0">',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result1.ok)
|
||||
t.assert.strictEqual(result1.status, 200)
|
||||
t.assert.equal(await result1.text(), 'xml')
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '',
|
||||
headers: {
|
||||
'Content-Type': 'image/png'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result2.ok)
|
||||
t.assert.strictEqual(result2.status, 415)
|
||||
|
||||
const result3 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{test: "test"}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result3.ok)
|
||||
t.assert.strictEqual(result3.status, 415)
|
||||
})
|
||||
|
||||
test('removeContentTypeParser should support encapsulation', async (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.addContentTypeParser('application/xml', function (req, payload, done) {
|
||||
payload.on('data', () => {})
|
||||
payload.on('end', () => {
|
||||
done(null, 'xml')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.register(function (instance, options, done) {
|
||||
instance.removeContentTypeParser('application/xml')
|
||||
|
||||
instance.post('/encapsulated', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result1 = await fetch(fastifyServer + '/encapsulated', {
|
||||
method: 'POST',
|
||||
body: '<?xml version="1.0">',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result1.ok)
|
||||
t.assert.strictEqual(result1.status, 415)
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '<?xml version="1.0">',
|
||||
headers: {
|
||||
'Content-Type': 'application/xml'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.equal(await result2.text(), 'xml')
|
||||
})
|
||||
|
||||
test('removeAllContentTypeParsers should support encapsulation', async (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.register(function (instance, options, done) {
|
||||
instance.removeAllContentTypeParsers()
|
||||
|
||||
instance.post('/encapsulated', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result1 = await fetch(fastifyServer + '/encapsulated', {
|
||||
method: 'POST',
|
||||
body: '{}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result1.ok)
|
||||
t.assert.strictEqual(result1.status, 415)
|
||||
|
||||
const result2 = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: '{"test":1}',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result2.ok)
|
||||
t.assert.strictEqual(result2.status, 200)
|
||||
t.assert.equal(JSON.parse(await result2.text()).test, 1)
|
||||
})
|
||||
130
node_modules/fastify/test/custom-parser.5.test.js
generated
vendored
130
node_modules/fastify/test/custom-parser.5.test.js
generated
vendored
@@ -1,130 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
const jsonParser = require('fast-json-body')
|
||||
const { plainTextParser } = require('./helper')
|
||||
|
||||
process.removeAllListeners('warning')
|
||||
|
||||
test('cannot remove all content type parsers after binding', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
t.assert.throws(() => fastify.removeAllContentTypeParsers())
|
||||
})
|
||||
|
||||
test('cannot remove content type parsers after binding', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
t.assert.throws(() => fastify.removeContentTypeParser('application/json'))
|
||||
})
|
||||
|
||||
test('should be able to override the default json parser after removeAllContentTypeParsers', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.removeAllContentTypeParsers()
|
||||
|
||||
fastify.addContentTypeParser('application/json', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.text(), JSON.stringify({ hello: 'world' }))
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('should be able to override the default plain text parser after removeAllContentTypeParsers', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.removeAllContentTypeParsers()
|
||||
|
||||
fastify.addContentTypeParser('text/plain', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
plainTextParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(await result.text(), 'hello world')
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('should be able to add a custom content type parser after removeAllContentTypeParsers', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/', (req, reply) => {
|
||||
reply.send(req.body)
|
||||
})
|
||||
|
||||
fastify.removeAllContentTypeParsers()
|
||||
fastify.addContentTypeParser('application/jsoff', function (req, payload, done) {
|
||||
t.assert.ok('called')
|
||||
jsonParser(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/jsoff'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.text(), JSON.stringify({ hello: 'world' }))
|
||||
await fastify.close()
|
||||
})
|
||||
129
node_modules/fastify/test/custom-querystring-parser.test.js
generated
vendored
129
node_modules/fastify/test/custom-querystring-parser.test.js
generated
vendored
@@ -1,129 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const querystring = require('node:querystring')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('Custom querystring parser', async t => {
|
||||
t.plan(7)
|
||||
|
||||
const fastify = Fastify({
|
||||
querystringParser: function (str) {
|
||||
t.assert.strictEqual(str, 'foo=bar&baz=faz')
|
||||
return querystring.parse(str)
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.deepEqual(req.query, {
|
||||
foo: 'bar',
|
||||
baz: 'faz'
|
||||
})
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(`${fastifyServer}?foo=bar&baz=faz`)
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
|
||||
const injectResponse = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: `${fastifyServer}?foo=bar&baz=faz`
|
||||
})
|
||||
t.assert.strictEqual(injectResponse.statusCode, 200)
|
||||
})
|
||||
|
||||
test('Custom querystring parser should be called also if there is nothing to parse', async t => {
|
||||
t.plan(7)
|
||||
|
||||
const fastify = Fastify({
|
||||
querystringParser: function (str) {
|
||||
t.assert.strictEqual(str, '')
|
||||
return querystring.parse(str)
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.deepEqual(req.query, {})
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(fastifyServer)
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
|
||||
const injectResponse = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: fastifyServer
|
||||
})
|
||||
t.assert.strictEqual(injectResponse.statusCode, 200)
|
||||
})
|
||||
|
||||
test('Querystring without value', async t => {
|
||||
t.plan(7)
|
||||
|
||||
const fastify = Fastify({
|
||||
querystringParser: function (str) {
|
||||
t.assert.strictEqual(str, 'foo')
|
||||
return querystring.parse(str)
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.deepEqual(req.query, { foo: '' })
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const result = await fetch(`${fastifyServer}?foo`)
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
|
||||
const injectResponse = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: `${fastifyServer}?foo`
|
||||
})
|
||||
t.assert.strictEqual(injectResponse.statusCode, 200)
|
||||
})
|
||||
|
||||
test('Custom querystring parser should be a function', t => {
|
||||
t.plan(1)
|
||||
|
||||
try {
|
||||
Fastify({
|
||||
querystringParser: 10
|
||||
})
|
||||
t.assert.fail('Should throw')
|
||||
} catch (err) {
|
||||
t.assert.strictEqual(
|
||||
err.message,
|
||||
"querystringParser option should be a function, instead got 'number'"
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
test('Custom querystring parser should be a function', t => {
|
||||
t.plan(1)
|
||||
|
||||
try {
|
||||
Fastify({
|
||||
routerOptions: {
|
||||
querystringParser: 10
|
||||
}
|
||||
})
|
||||
t.fail('Should throw')
|
||||
} catch (err) {
|
||||
t.assert.equal(
|
||||
err.message,
|
||||
"querystringParser option should be a function, instead got 'number'"
|
||||
)
|
||||
}
|
||||
})
|
||||
30
node_modules/fastify/test/decorator-namespace.test._js_
generated
vendored
30
node_modules/fastify/test/decorator-namespace.test._js_
generated
vendored
@@ -1,30 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: 0 */
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
test('plugin namespace', async t => {
|
||||
t.plan(2)
|
||||
const app = Fastify()
|
||||
|
||||
await app.register(async function plugin (app, opts) {
|
||||
app.decorate('utility', function () {
|
||||
return 'utility'
|
||||
})
|
||||
|
||||
app.get('/', function (req, reply) {
|
||||
// ! here the plugin would use app.utility()
|
||||
// ! the plugin does not know about the namespace
|
||||
reply.send({ utility: app.utility() })
|
||||
})
|
||||
}, { namepace: 'foo' })
|
||||
|
||||
// ! but outside the plugin the decorator would be app.foo.utility()
|
||||
t.assert.ok(app.foo.utility)
|
||||
|
||||
const res = await app.inject('/')
|
||||
t.assert.deepStrictEqual(res.json(), { utility: 'utility' })
|
||||
})
|
||||
1330
node_modules/fastify/test/decorator.test.js
generated
vendored
1330
node_modules/fastify/test/decorator.test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
344
node_modules/fastify/test/delete.test.js
generated
vendored
344
node_modules/fastify/test/delete.test.js
generated
vendored
@@ -1,344 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('..')()
|
||||
|
||||
const schema = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const querySchema = {
|
||||
schema: {
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const paramsSchema = {
|
||||
schema: {
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
type: 'string'
|
||||
},
|
||||
test: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const headersSchema = {
|
||||
schema: {
|
||||
headers: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
'x-test': {
|
||||
type: 'number'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bodySchema = {
|
||||
schema: {
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
},
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test('shorthand - delete', (t, done) => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.delete('/', schema, function (req, reply) {
|
||||
reply.code(200).send({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
} finally {
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - delete params', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.delete('/params/:foo/:test', paramsSchema, function (req, reply) {
|
||||
reply.code(200).send(req.params)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - delete, querystring schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.delete('/query', querySchema, function (req, reply) {
|
||||
reply.send(req.query)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - get, headers schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.delete('/headers', headersSchema, function (req, reply) {
|
||||
reply.code(200).send(req.headers)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('missing schema - delete', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.delete('/missing', function (req, reply) {
|
||||
reply.code(200).send({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('body - delete', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.delete('/body', bodySchema, function (req, reply) {
|
||||
reply.send(req.body)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('delete tests', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await t.test('shorthand - request delete', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete params schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch(fastifyServer + '/params/world/123', {
|
||||
method: 'DELETE'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { foo: 'world', test: 123 })
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete params schema error', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch(fastifyServer + '/params/world/string', {
|
||||
method: 'DELETE'
|
||||
})
|
||||
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
t.assert.deepStrictEqual(await response.json(), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'params/test must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete headers schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch(fastifyServer + '/headers', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'x-test': '1'
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.strictEqual(JSON.parse(body)['x-test'], 1)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete headers schema error', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch(fastifyServer + '/headers', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'x-test': 'abc'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'headers/x-test must be number',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete querystring schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch(fastifyServer + '/query?hello=123', {
|
||||
method: 'DELETE'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 123 })
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete querystring schema error', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch(fastifyServer + '/query?hello=world', {
|
||||
method: 'DELETE'
|
||||
})
|
||||
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'querystring/hello must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('shorthand - request delete missing schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch(fastifyServer + '/missing', {
|
||||
method: 'DELETE'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('shorthand - delete with body', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch(fastifyServer + '/body', {
|
||||
method: 'DELETE',
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.json()
|
||||
t.assert.deepStrictEqual(body, { hello: 'world' })
|
||||
})
|
||||
})
|
||||
|
||||
test('shorthand - delete with application/json Content-Type header and null body', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = require('..')()
|
||||
fastify.delete('/', {}, (req, reply) => {
|
||||
t.assert.strictEqual(req.body, null)
|
||||
reply.send(req.body)
|
||||
})
|
||||
fastify.inject({
|
||||
method: 'DELETE',
|
||||
url: '/',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: 'null'
|
||||
}, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.strictEqual(response.payload.toString(), 'null')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/fastify/fastify/issues/936
|
||||
// Skip this test because this is an invalid request
|
||||
test('shorthand - delete with application/json Content-Type header and without body', { skip: 'https://github.com/fastify/fastify/pull/5419' }, t => {
|
||||
t.plan(4)
|
||||
const fastify = require('..')()
|
||||
fastify.delete('/', {}, (req, reply) => {
|
||||
t.assert.strictEqual(req.body, undefined)
|
||||
reply.send(req.body)
|
||||
})
|
||||
fastify.inject({
|
||||
method: 'DELETE',
|
||||
url: '/',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: null
|
||||
}, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
t.assert.strictEqual(response.payload.toString(), '')
|
||||
})
|
||||
})
|
||||
49
node_modules/fastify/test/diagnostics-channel/404.test.js
generated
vendored
49
node_modules/fastify/test/diagnostics-channel/404.test.js
generated
vendored
@@ -1,49 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel sync events fire in expected order', async t => {
|
||||
t.plan(9)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.fail('should not trigger error channel')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: function (req, reply) {
|
||||
reply.callNotFound()
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 404)
|
||||
})
|
||||
65
node_modules/fastify/test/diagnostics-channel/async-delay-request.test.js
generated
vendored
65
node_modules/fastify/test/diagnostics-channel/async-delay-request.test.js
generated
vendored
@@ -1,65 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel async events fire in expected order', async t => {
|
||||
t.plan(19)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
t.assert.strictEqual(msg.async, true)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:asyncStart', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 2)
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:asyncEnd', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 3)
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.fail('should not trigger error channel')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: async function (req, reply) {
|
||||
setImmediate(() => reply.send({ hello: 'world' }))
|
||||
return reply
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer + '/')
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
64
node_modules/fastify/test/diagnostics-channel/async-request.test.js
generated
vendored
64
node_modules/fastify/test/diagnostics-channel/async-request.test.js
generated
vendored
@@ -1,64 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel async events fire in expected order', async t => {
|
||||
t.plan(18)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:asyncStart', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 2)
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:asyncEnd', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 3)
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.fail('should not trigger error channel')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: async function (req, reply) {
|
||||
return { hello: 'world' }
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const response = await fetch(fastifyServer)
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
35
node_modules/fastify/test/diagnostics-channel/error-before-handler.test.js
generated
vendored
35
node_modules/fastify/test/diagnostics-channel/error-before-handler.test.js
generated
vendored
@@ -1,35 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const { test } = require('node:test')
|
||||
require('../../lib/hooks').onSendHookRunner = function Stub () {}
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
const symbols = require('../../lib/symbols.js')
|
||||
const { preHandlerCallback } = require('../../lib/handleRequest')[Symbol.for('internals')]
|
||||
|
||||
test('diagnostics channel handles an error before calling context handler', t => {
|
||||
t.plan(3)
|
||||
let callOrder = 0
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.strictEqual(msg.error.message, 'oh no')
|
||||
})
|
||||
|
||||
const error = new Error('oh no')
|
||||
const request = new Request()
|
||||
const reply = new Reply({}, request)
|
||||
request[symbols.kRouteContext] = {
|
||||
config: {
|
||||
url: '/foo',
|
||||
method: 'GET'
|
||||
}
|
||||
}
|
||||
|
||||
preHandlerCallback(error, request, reply)
|
||||
})
|
||||
53
node_modules/fastify/test/diagnostics-channel/error-request.test.js
generated
vendored
53
node_modules/fastify/test/diagnostics-channel/error-request.test.js
generated
vendored
@@ -1,53 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel events report on errors', async t => {
|
||||
t.plan(14)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(callOrder++, 2)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.ok(msg.error instanceof Error)
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.strictEqual(msg.error.message, 'borked')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: function (req, reply) {
|
||||
throw new Error('borked')
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 500)
|
||||
})
|
||||
39
node_modules/fastify/test/diagnostics-channel/error-status.test.js
generated
vendored
39
node_modules/fastify/test/diagnostics-channel/error-status.test.js
generated
vendored
@@ -1,39 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const statusCodes = require('node:http').STATUS_CODES
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
|
||||
test('Error.status property support', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
const err = new Error('winter is coming')
|
||||
err.status = 418
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.strictEqual(msg.error.message, 'winter is coming')
|
||||
})
|
||||
|
||||
fastify.get('/', () => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (error, res) => {
|
||||
t.assert.ifError(error)
|
||||
t.assert.strictEqual(res.statusCode, 418)
|
||||
t.assert.deepStrictEqual(
|
||||
{
|
||||
error: statusCodes['418'],
|
||||
message: err.message,
|
||||
statusCode: 418
|
||||
},
|
||||
JSON.parse(res.payload)
|
||||
)
|
||||
done()
|
||||
})
|
||||
})
|
||||
50
node_modules/fastify/test/diagnostics-channel/init.test.js
generated
vendored
50
node_modules/fastify/test/diagnostics-channel/init.test.js
generated
vendored
@@ -1,50 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const proxyquire = require('proxyquire')
|
||||
|
||||
test('diagnostics_channel when present and subscribers', t => {
|
||||
t.plan(3)
|
||||
|
||||
let fastifyInHook
|
||||
|
||||
const diagnostics = {
|
||||
channel (name) {
|
||||
t.assert.strictEqual(name, 'fastify.initialization')
|
||||
return {
|
||||
hasSubscribers: true,
|
||||
publish (event) {
|
||||
t.assert.ok(event.fastify)
|
||||
fastifyInHook = event.fastify
|
||||
}
|
||||
}
|
||||
},
|
||||
'@noCallThru': true
|
||||
}
|
||||
|
||||
const fastify = proxyquire('../../fastify', {
|
||||
'node:diagnostics_channel': diagnostics
|
||||
})()
|
||||
t.assert.strictEqual(fastifyInHook, fastify)
|
||||
})
|
||||
|
||||
test('diagnostics_channel when present and no subscribers', t => {
|
||||
t.plan(1)
|
||||
|
||||
const diagnostics = {
|
||||
channel (name) {
|
||||
t.assert.strictEqual(name, 'fastify.initialization')
|
||||
return {
|
||||
hasSubscribers: false,
|
||||
publish () {
|
||||
t.assert.fail('publish should not be called')
|
||||
}
|
||||
}
|
||||
},
|
||||
'@noCallThru': true
|
||||
}
|
||||
|
||||
proxyquire('../../fastify', {
|
||||
'node:diagnostics_channel': diagnostics
|
||||
})()
|
||||
})
|
||||
49
node_modules/fastify/test/diagnostics-channel/sync-delay-request.test.js
generated
vendored
49
node_modules/fastify/test/diagnostics-channel/sync-delay-request.test.js
generated
vendored
@@ -1,49 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel sync events fire in expected order', async t => {
|
||||
t.plan(10)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.fail('should not trigger error channel')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: function (req, reply) {
|
||||
setImmediate(() => reply.send({ hello: 'world' }))
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer + '/')
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
51
node_modules/fastify/test/diagnostics-channel/sync-request-reply.test.js
generated
vendored
51
node_modules/fastify/test/diagnostics-channel/sync-request-reply.test.js
generated
vendored
@@ -1,51 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel sync events fire in expected order', async t => {
|
||||
t.plan(10)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.fail('should not trigger error channel')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const response = await fetch(fastifyServer, {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
54
node_modules/fastify/test/diagnostics-channel/sync-request.test.js
generated
vendored
54
node_modules/fastify/test/diagnostics-channel/sync-request.test.js
generated
vendored
@@ -1,54 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const diagnostics = require('node:diagnostics_channel')
|
||||
const Fastify = require('../..')
|
||||
const Request = require('../../lib/request')
|
||||
const Reply = require('../../lib/reply')
|
||||
|
||||
test('diagnostics channel sync events fire in expected order', async t => {
|
||||
t.plan(13)
|
||||
let callOrder = 0
|
||||
let firstEncounteredMessage
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:start', (msg) => {
|
||||
t.assert.strictEqual(callOrder++, 0)
|
||||
firstEncounteredMessage = msg
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.ok(msg.route)
|
||||
t.assert.strictEqual(msg.route.url, '/:id')
|
||||
t.assert.strictEqual(msg.route.method, 'GET')
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:end', (msg) => {
|
||||
t.assert.ok(msg.request instanceof Request)
|
||||
t.assert.ok(msg.reply instanceof Reply)
|
||||
t.assert.strictEqual(callOrder++, 1)
|
||||
t.assert.strictEqual(msg, firstEncounteredMessage)
|
||||
})
|
||||
|
||||
diagnostics.subscribe('tracing:fastify.request.handler:error', (msg) => {
|
||||
t.assert.fail('should not trigger error channel')
|
||||
})
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/:id',
|
||||
handler: function (req, reply) {
|
||||
return { hello: 'world' }
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
const response = await fetch(fastifyServer + '/7', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
69
node_modules/fastify/test/encapsulated-child-logger-factory.test.js
generated
vendored
69
node_modules/fastify/test/encapsulated-child-logger-factory.test.js
generated
vendored
@@ -1,69 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const fp = require('fastify-plugin')
|
||||
|
||||
test('encapsulates an child logger factory', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.setChildLoggerFactory(function pluginFactory (logger, bindings, opts) {
|
||||
const child = logger.child(bindings, opts)
|
||||
child.customLog = function (message) {
|
||||
t.assert.strictEqual(message, 'custom')
|
||||
}
|
||||
return child
|
||||
})
|
||||
fastify.get('/encapsulated', async (req) => {
|
||||
req.log.customLog('custom')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.setChildLoggerFactory(function globalFactory (logger, bindings, opts) {
|
||||
const child = logger.child(bindings, opts)
|
||||
child.globalLog = function (message) {
|
||||
t.assert.strictEqual(message, 'global')
|
||||
}
|
||||
return child
|
||||
})
|
||||
fastify.get('/not-encapsulated', async (req) => {
|
||||
req.log.globalLog('global')
|
||||
})
|
||||
|
||||
const res1 = await fastify.inject('/encapsulated')
|
||||
t.assert.strictEqual(res1.statusCode, 200)
|
||||
|
||||
const res2 = await fastify.inject('/not-encapsulated')
|
||||
t.assert.strictEqual(res2.statusCode, 200)
|
||||
})
|
||||
|
||||
test('child logger factory set on root scope when using fastify-plugin', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(fp(async function (fastify) {
|
||||
// Using fastify-plugin, the factory should be set on the root scope
|
||||
fastify.setChildLoggerFactory(function pluginFactory (logger, bindings, opts) {
|
||||
const child = logger.child(bindings, opts)
|
||||
child.customLog = function (message) {
|
||||
t.assert.strictEqual(message, 'custom')
|
||||
}
|
||||
return child
|
||||
})
|
||||
fastify.get('/not-encapsulated-1', async (req) => {
|
||||
req.log.customLog('custom')
|
||||
})
|
||||
}))
|
||||
|
||||
fastify.get('/not-encapsulated-2', async (req) => {
|
||||
req.log.customLog('custom')
|
||||
})
|
||||
|
||||
const res1 = await fastify.inject('/not-encapsulated-1')
|
||||
t.assert.strictEqual(res1.statusCode, 200)
|
||||
|
||||
const res2 = await fastify.inject('/not-encapsulated-2')
|
||||
t.assert.strictEqual(res2.statusCode, 200)
|
||||
})
|
||||
237
node_modules/fastify/test/encapsulated-error-handler.test.js
generated
vendored
237
node_modules/fastify/test/encapsulated-error-handler.test.js
generated
vendored
@@ -1,237 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
// Because of how error handlers wrap things, following the control flow can be tricky
|
||||
// In this test file numbered comments indicate the order statements are expected to execute
|
||||
|
||||
test('encapsulates an asynchronous error handler', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.setErrorHandler(async function a (err) {
|
||||
// 3. the inner error handler catches the error, and throws a new error
|
||||
t.assert.strictEqual(err.message, 'from_endpoint')
|
||||
throw new Error('from_inner')
|
||||
})
|
||||
fastify.get('/encapsulated', async () => {
|
||||
// 2. the endpoint throws an error
|
||||
throw new Error('from_endpoint')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(async function b (err) {
|
||||
// 4. the outer error handler catches the error thrown by the inner error handler
|
||||
t.assert.strictEqual(err.message, 'from_inner')
|
||||
// 5. the outer error handler throws a new error
|
||||
throw new Error('from_outer')
|
||||
})
|
||||
|
||||
// 1. the endpoint is called
|
||||
const res = await fastify.inject('/encapsulated')
|
||||
// 6. the default error handler returns the error from the outer error handler
|
||||
t.assert.strictEqual(res.json().message, 'from_outer')
|
||||
})
|
||||
|
||||
// See discussion in https://github.com/fastify/fastify/pull/5222#discussion_r1432573655
|
||||
test('encapsulates a synchronous error handler', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.setErrorHandler(function a (err) {
|
||||
// 3. the inner error handler catches the error, and throws a new error
|
||||
t.assert.strictEqual(err.message, 'from_endpoint')
|
||||
throw new Error('from_inner')
|
||||
})
|
||||
fastify.get('/encapsulated', async () => {
|
||||
// 2. the endpoint throws an error
|
||||
throw new Error('from_endpoint')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(async function b (err) {
|
||||
// 4. the outer error handler catches the error thrown by the inner error handler
|
||||
t.assert.strictEqual(err.message, 'from_inner')
|
||||
// 5. the outer error handler throws a new error
|
||||
throw new Error('from_outer')
|
||||
})
|
||||
|
||||
// 1. the endpoint is called
|
||||
const res = await fastify.inject('/encapsulated')
|
||||
// 6. the default error handler returns the error from the outer error handler
|
||||
t.assert.strictEqual(res.json().message, 'from_outer')
|
||||
})
|
||||
|
||||
test('onError hook nested', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.setErrorHandler(async function a (err) {
|
||||
// 4. the inner error handler catches the error, and throws a new error
|
||||
t.assert.strictEqual(err.message, 'from_endpoint')
|
||||
throw new Error('from_inner')
|
||||
})
|
||||
fastify.get('/encapsulated', async () => {
|
||||
// 2. the endpoint throws an error
|
||||
throw new Error('from_endpoint')
|
||||
})
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(async function b (err) {
|
||||
// 5. the outer error handler catches the error thrown by the inner error handler
|
||||
t.assert.strictEqual(err.message, 'from_inner')
|
||||
// 6. the outer error handler throws a new error
|
||||
throw new Error('from_outer')
|
||||
})
|
||||
|
||||
fastify.addHook('onError', async function (request, reply, err) {
|
||||
// 3. the hook receives the error
|
||||
t.assert.strictEqual(err.message, 'from_endpoint')
|
||||
})
|
||||
|
||||
// 1. the endpoint is called
|
||||
const res = await fastify.inject('/encapsulated')
|
||||
// 7. the default error handler returns the error from the outer error handler
|
||||
t.assert.strictEqual(res.json().message, 'from_outer')
|
||||
})
|
||||
|
||||
// See https://github.com/fastify/fastify/issues/5220
|
||||
test('encapuslates an error handler, for errors thrown in hooks', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.setErrorHandler(function a (err) {
|
||||
// 3. the inner error handler catches the error, and throws a new error
|
||||
t.assert.strictEqual(err.message, 'from_hook')
|
||||
throw new Error('from_inner')
|
||||
})
|
||||
fastify.addHook('onRequest', async () => {
|
||||
// 2. the hook throws an error
|
||||
throw new Error('from_hook')
|
||||
})
|
||||
fastify.get('/encapsulated', async () => {})
|
||||
})
|
||||
|
||||
fastify.setErrorHandler(function b (err) {
|
||||
// 4. the outer error handler catches the error thrown by the inner error handler
|
||||
t.assert.strictEqual(err.message, 'from_inner')
|
||||
// 5. the outer error handler throws a new error
|
||||
throw new Error('from_outer')
|
||||
})
|
||||
|
||||
// 1. the endpoint is called
|
||||
const res = await fastify.inject('/encapsulated')
|
||||
// 6. the default error handler returns the error from the outer error handler
|
||||
t.assert.strictEqual(res.json().message, 'from_outer')
|
||||
})
|
||||
|
||||
// See https://github.com/fastify/fastify/issues/5220
|
||||
test('encapuslates many synchronous error handlers that rethrow errors', async t => {
|
||||
const DEPTH = 100
|
||||
t.plan(DEPTH + 2)
|
||||
|
||||
/**
|
||||
* This creates a very nested set of error handlers, that looks like:
|
||||
* plugin
|
||||
* - error handler
|
||||
* - plugin
|
||||
* - error handler
|
||||
* - plugin
|
||||
* ... {to DEPTH levels}
|
||||
* - plugin
|
||||
* - error handler
|
||||
* - GET /encapsulated
|
||||
*/
|
||||
const createNestedRoutes = (fastify, depth) => {
|
||||
if (depth < 0) {
|
||||
throw new Error('Expected depth >= 0')
|
||||
} else if (depth === 0) {
|
||||
fastify.setErrorHandler(function a (err) {
|
||||
// 3. innermost error handler catches the error, and throws a new error
|
||||
t.assert.strictEqual(err.message, 'from_route')
|
||||
throw new Error(`from_handler_${depth}`)
|
||||
})
|
||||
fastify.get('/encapsulated', async () => {
|
||||
// 2. the endpoint throws an error
|
||||
throw new Error('from_route')
|
||||
})
|
||||
} else {
|
||||
fastify.setErrorHandler(function d (err) {
|
||||
// 4 to {DEPTH+4}. error handlers each catch errors, and then throws a new error
|
||||
t.assert.strictEqual(err.message, `from_handler_${depth - 1}`)
|
||||
throw new Error(`from_handler_${depth}`)
|
||||
})
|
||||
|
||||
fastify.register(async function (fastify) {
|
||||
createNestedRoutes(fastify, depth - 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const fastify = Fastify()
|
||||
createNestedRoutes(fastify, DEPTH)
|
||||
|
||||
// 1. the endpoint is called
|
||||
const res = await fastify.inject('/encapsulated')
|
||||
// {DEPTH+5}. the default error handler returns the error from the outermost error handler
|
||||
t.assert.strictEqual(res.json().message, `from_handler_${DEPTH}`)
|
||||
})
|
||||
|
||||
// See https://github.com/fastify/fastify/issues/5220
|
||||
// This was not failing previously, but we want to make sure the behavior continues to work in the same way across async and sync handlers
|
||||
// Plus, the current setup is somewhat fragile to tweaks to wrapThenable as that's what retries (by calling res.send(err) again)
|
||||
test('encapuslates many asynchronous error handlers that rethrow errors', async t => {
|
||||
const DEPTH = 100
|
||||
t.plan(DEPTH + 2)
|
||||
|
||||
/**
|
||||
* This creates a very nested set of error handlers, that looks like:
|
||||
* plugin
|
||||
* - error handler
|
||||
* - plugin
|
||||
* - error handler
|
||||
* - plugin
|
||||
* ... {to DEPTH levels}
|
||||
* - plugin
|
||||
* - error handler
|
||||
* - GET /encapsulated
|
||||
*/
|
||||
const createNestedRoutes = (fastify, depth) => {
|
||||
if (depth < 0) {
|
||||
throw new Error('Expected depth >= 0')
|
||||
} else if (depth === 0) {
|
||||
fastify.setErrorHandler(async function a (err) {
|
||||
// 3. innermost error handler catches the error, and throws a new error
|
||||
t.assert.strictEqual(err.message, 'from_route')
|
||||
throw new Error(`from_handler_${depth}`)
|
||||
})
|
||||
fastify.get('/encapsulated', async () => {
|
||||
// 2. the endpoint throws an error
|
||||
throw new Error('from_route')
|
||||
})
|
||||
} else {
|
||||
fastify.setErrorHandler(async function m (err) {
|
||||
// 4 to {DEPTH+4}. error handlers each catch errors, and then throws a new error
|
||||
t.assert.strictEqual(err.message, `from_handler_${depth - 1}`)
|
||||
throw new Error(`from_handler_${depth}`)
|
||||
})
|
||||
|
||||
fastify.register(async function (fastify) {
|
||||
createNestedRoutes(fastify, depth - 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const fastify = Fastify()
|
||||
createNestedRoutes(fastify, DEPTH)
|
||||
|
||||
// 1. the endpoint is called
|
||||
const res = await fastify.inject('/encapsulated')
|
||||
// {DEPTH+5}. the default error handler returns the error from the outermost error handler
|
||||
t.assert.strictEqual(res.json().message, `from_handler_${DEPTH}`)
|
||||
})
|
||||
10
node_modules/fastify/test/esm/errorCodes.test.mjs
generated
vendored
10
node_modules/fastify/test/esm/errorCodes.test.mjs
generated
vendored
@@ -1,10 +0,0 @@
|
||||
import { errorCodes } from '../../fastify.js'
|
||||
import { test } from 'node:test'
|
||||
|
||||
test('errorCodes in ESM', async t => {
|
||||
// test a custom fastify error using errorCodes with ESM
|
||||
const customError = errorCodes.FST_ERR_VALIDATION('custom error message')
|
||||
t.assert.ok(typeof customError !== 'undefined')
|
||||
t.assert.ok(customError instanceof errorCodes.FST_ERR_VALIDATION)
|
||||
t.assert.strictEqual(customError.message, 'custom error message')
|
||||
})
|
||||
13
node_modules/fastify/test/esm/esm.test.mjs
generated
vendored
13
node_modules/fastify/test/esm/esm.test.mjs
generated
vendored
@@ -1,13 +0,0 @@
|
||||
import { test } from 'node:test'
|
||||
import Fastify from '../../fastify.js'
|
||||
|
||||
test('esm support', async t => {
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(import('./plugin.mjs'), { foo: 'bar' })
|
||||
fastify.register(import('./other.mjs'))
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
t.assert.strictEqual(fastify.foo, 'bar')
|
||||
})
|
||||
8
node_modules/fastify/test/esm/index.test.js
generated
vendored
8
node_modules/fastify/test/esm/index.test.js
generated
vendored
@@ -1,8 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
import('./named-exports.mjs')
|
||||
.catch(err => {
|
||||
process.nextTick(() => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
14
node_modules/fastify/test/esm/named-exports.mjs
generated
vendored
14
node_modules/fastify/test/esm/named-exports.mjs
generated
vendored
@@ -1,14 +0,0 @@
|
||||
import { test } from 'node:test'
|
||||
import { fastify } from '../../fastify.js'
|
||||
|
||||
// This test is executed in index.test.js
|
||||
test('named exports support', async t => {
|
||||
const app = fastify()
|
||||
|
||||
app.register(import('./plugin.mjs'), { foo: 'bar' })
|
||||
app.register(import('./other.mjs'))
|
||||
|
||||
await app.ready()
|
||||
|
||||
t.assert.strictEqual(app.foo, 'bar')
|
||||
})
|
||||
8
node_modules/fastify/test/esm/other.mjs
generated
vendored
8
node_modules/fastify/test/esm/other.mjs
generated
vendored
@@ -1,8 +0,0 @@
|
||||
// Imported in both index.test.js & esm.test.mjs
|
||||
import { strictEqual } from 'node:assert'
|
||||
|
||||
async function other (fastify, opts) {
|
||||
strictEqual(fastify.foo, 'bar')
|
||||
}
|
||||
|
||||
export default other
|
||||
8
node_modules/fastify/test/esm/plugin.mjs
generated
vendored
8
node_modules/fastify/test/esm/plugin.mjs
generated
vendored
@@ -1,8 +0,0 @@
|
||||
// Imported in both index.test.js & esm.test.mjs
|
||||
async function plugin (fastify, opts) {
|
||||
fastify.decorate('foo', opts.foo)
|
||||
}
|
||||
|
||||
plugin[Symbol.for('skip-override')] = true
|
||||
|
||||
export default plugin
|
||||
300
node_modules/fastify/test/fastify-instance.test.js
generated
vendored
300
node_modules/fastify/test/fastify-instance.test.js
generated
vendored
@@ -1,300 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const os = require('node:os')
|
||||
|
||||
const {
|
||||
kOptions,
|
||||
kErrorHandler,
|
||||
kChildLoggerFactory,
|
||||
kState
|
||||
} = require('../lib/symbols')
|
||||
|
||||
const isIPv6Missing = !Object.values(os.networkInterfaces()).flat().some(({ family }) => family === 'IPv6')
|
||||
|
||||
test('root fastify instance is an object', t => {
|
||||
t.plan(1)
|
||||
t.assert.strictEqual(typeof Fastify(), 'object')
|
||||
})
|
||||
|
||||
test('fastify instance should contains ajv options', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify({
|
||||
ajv: {
|
||||
customOptions: {
|
||||
nullable: false
|
||||
}
|
||||
}
|
||||
})
|
||||
t.assert.deepStrictEqual(fastify[kOptions].ajv, {
|
||||
customOptions: {
|
||||
nullable: false
|
||||
},
|
||||
plugins: []
|
||||
})
|
||||
})
|
||||
|
||||
test('fastify instance should contains ajv options.plugins nested arrays', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify({
|
||||
ajv: {
|
||||
customOptions: {
|
||||
nullable: false
|
||||
},
|
||||
plugins: [[]]
|
||||
}
|
||||
})
|
||||
t.assert.deepStrictEqual(fastify[kOptions].ajv, {
|
||||
customOptions: {
|
||||
nullable: false
|
||||
},
|
||||
plugins: [[]]
|
||||
})
|
||||
})
|
||||
|
||||
test('fastify instance get invalid ajv options', t => {
|
||||
t.plan(1)
|
||||
t.assert.throws(() => Fastify({
|
||||
ajv: {
|
||||
customOptions: 8
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
test('fastify instance get invalid ajv options.plugins', t => {
|
||||
t.plan(1)
|
||||
t.assert.throws(() => Fastify({
|
||||
ajv: {
|
||||
customOptions: {},
|
||||
plugins: 8
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
test('fastify instance should contain default errorHandler', t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
t.assert.ok(fastify[kErrorHandler].func instanceof Function)
|
||||
t.assert.deepStrictEqual(fastify.errorHandler, fastify[kErrorHandler].func)
|
||||
t.assert.deepStrictEqual(Object.getOwnPropertyDescriptor(fastify, 'errorHandler').set, undefined)
|
||||
})
|
||||
|
||||
test('errorHandler in plugin should be separate from the external one', async t => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register((instance, opts, done) => {
|
||||
const inPluginErrHandler = (_, __, reply) => {
|
||||
reply.send({ plugin: 'error-object' })
|
||||
}
|
||||
|
||||
instance.setErrorHandler(inPluginErrHandler)
|
||||
|
||||
t.assert.notDeepStrictEqual(instance.errorHandler, fastify.errorHandler)
|
||||
t.assert.strictEqual(instance.errorHandler.name, 'bound inPluginErrHandler')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
t.assert.ok(fastify[kErrorHandler].func instanceof Function)
|
||||
t.assert.deepStrictEqual(fastify.errorHandler, fastify[kErrorHandler].func)
|
||||
})
|
||||
|
||||
test('fastify instance should contain default childLoggerFactory', t => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
t.assert.ok(fastify[kChildLoggerFactory] instanceof Function)
|
||||
t.assert.deepStrictEqual(fastify.childLoggerFactory, fastify[kChildLoggerFactory])
|
||||
t.assert.deepStrictEqual(Object.getOwnPropertyDescriptor(fastify, 'childLoggerFactory').set, undefined)
|
||||
})
|
||||
|
||||
test('childLoggerFactory in plugin should be separate from the external one', async t => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register((instance, opts, done) => {
|
||||
const inPluginLoggerFactory = function (logger, bindings, opts) {
|
||||
return logger.child(bindings, opts)
|
||||
}
|
||||
|
||||
instance.setChildLoggerFactory(inPluginLoggerFactory)
|
||||
|
||||
t.assert.notDeepStrictEqual(instance.childLoggerFactory, fastify.childLoggerFactory)
|
||||
t.assert.strictEqual(instance.childLoggerFactory.name, 'inPluginLoggerFactory')
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
t.assert.ok(fastify[kChildLoggerFactory] instanceof Function)
|
||||
t.assert.deepStrictEqual(fastify.childLoggerFactory, fastify[kChildLoggerFactory])
|
||||
})
|
||||
|
||||
test('ready should resolve in order when called multiply times (promises only)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5]
|
||||
const result = []
|
||||
|
||||
const promises = [1, 2, 3, 4, 5]
|
||||
.map((id) => app.ready().then(() => result.push(id)))
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('ready should reject in order when called multiply times (promises only)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5]
|
||||
const result = []
|
||||
|
||||
app.register((instance, opts, done) => {
|
||||
setTimeout(() => done(new Error('test')), 500)
|
||||
})
|
||||
|
||||
const promises = [1, 2, 3, 4, 5]
|
||||
.map((id) => app.ready().catch(() => result.push(id)))
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('ready should reject in order when called multiply times (callbacks only)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5]
|
||||
const result = []
|
||||
|
||||
app.register((instance, opts, done) => {
|
||||
setTimeout(() => done(new Error('test')), 500)
|
||||
})
|
||||
|
||||
expectedOrder.map((id) => app.ready(() => result.push(id)))
|
||||
|
||||
await app.ready().catch(err => {
|
||||
t.assert.strictEqual(err.message, 'test')
|
||||
})
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('ready should resolve in order when called multiply times (callbacks only)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5]
|
||||
const result = []
|
||||
|
||||
expectedOrder.map((id) => app.ready(() => result.push(id)))
|
||||
|
||||
await app.ready()
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('ready should resolve in order when called multiply times (mixed)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5, 6]
|
||||
const result = []
|
||||
|
||||
for (const order of expectedOrder) {
|
||||
if (order % 2) {
|
||||
app.ready(() => result.push(order))
|
||||
} else {
|
||||
app.ready().then(() => result.push(order))
|
||||
}
|
||||
}
|
||||
|
||||
await app.ready()
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('ready should reject in order when called multiply times (mixed)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5, 6]
|
||||
const result = []
|
||||
|
||||
app.register((instance, opts, done) => {
|
||||
setTimeout(() => done(new Error('test')), 500)
|
||||
})
|
||||
|
||||
for (const order of expectedOrder) {
|
||||
if (order % 2) {
|
||||
app.ready(() => result.push(order))
|
||||
} else {
|
||||
app.ready().then(null, () => result.push(order))
|
||||
}
|
||||
}
|
||||
|
||||
await app.ready().catch(err => {
|
||||
t.assert.strictEqual(err.message, 'test')
|
||||
})
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('ready should resolve in order when called multiply times (mixed)', async (t) => {
|
||||
const app = Fastify()
|
||||
const expectedOrder = [1, 2, 3, 4, 5, 6]
|
||||
const result = []
|
||||
|
||||
for (const order of expectedOrder) {
|
||||
if (order % 2) {
|
||||
app.ready().then(() => result.push(order))
|
||||
} else {
|
||||
app.ready(() => result.push(order))
|
||||
}
|
||||
}
|
||||
|
||||
await app.ready()
|
||||
|
||||
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
||||
})
|
||||
|
||||
test('fastify instance should contains listeningOrigin property (with port and host)', async t => {
|
||||
t.plan(1)
|
||||
const port = 3000
|
||||
const host = '127.0.0.1'
|
||||
const fastify = Fastify()
|
||||
await fastify.listen({ port, host })
|
||||
t.assert.deepStrictEqual(fastify.listeningOrigin, `http://${host}:${port}`)
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('fastify instance should contains listeningOrigin property (with port and https)', async t => {
|
||||
t.plan(1)
|
||||
const port = 3000
|
||||
const host = '127.0.0.1'
|
||||
const fastify = Fastify({ https: {} })
|
||||
await fastify.listen({ port, host })
|
||||
t.assert.deepStrictEqual(fastify.listeningOrigin, `https://${host}:${port}`)
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('fastify instance should contains listeningOrigin property (unix socket)', { skip: os.platform() === 'win32' }, async t => {
|
||||
const fastify = Fastify()
|
||||
const path = `fastify.${Date.now()}.sock`
|
||||
await fastify.listen({ path })
|
||||
t.assert.deepStrictEqual(fastify.listeningOrigin, path)
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('fastify instance should contains listeningOrigin property (IPv6)', { skip: isIPv6Missing }, async t => {
|
||||
t.plan(1)
|
||||
const port = 3000
|
||||
const host = '::1'
|
||||
const fastify = Fastify()
|
||||
await fastify.listen({ port, host })
|
||||
t.assert.deepStrictEqual(fastify.listeningOrigin, `http://[::1]:${port}`)
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('fastify instance should ensure ready promise cleanup on ready', async t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
await fastify.ready()
|
||||
t.assert.strictEqual(fastify[kState].readyResolver, null)
|
||||
})
|
||||
152
node_modules/fastify/test/find-route.test.js
generated
vendored
152
node_modules/fastify/test/find-route.test.js
generated
vendored
@@ -1,152 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const fastifyPlugin = require('fastify-plugin')
|
||||
|
||||
test('findRoute should return null when route cannot be found due to a different method', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fastify.findRoute({
|
||||
method: 'POST',
|
||||
url: '/artists/:artistId'
|
||||
}), null)
|
||||
})
|
||||
|
||||
test('findRoute should return an immutable route to avoid leaking and runtime route modifications', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
||||
})
|
||||
|
||||
let route = fastify.findRoute({
|
||||
method: 'GET',
|
||||
url: '/artists/:artistId'
|
||||
})
|
||||
|
||||
route.params = {
|
||||
...route.params,
|
||||
id: ':id'
|
||||
}
|
||||
|
||||
route = fastify.findRoute({
|
||||
method: 'GET',
|
||||
url: '/artists/:artistId'
|
||||
})
|
||||
|
||||
t.assert.strictEqual(route.params.artistId, ':artistId')
|
||||
})
|
||||
|
||||
test('findRoute should return null when when url is not passed', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fastify.findRoute({
|
||||
method: 'POST'
|
||||
}), null)
|
||||
})
|
||||
|
||||
test('findRoute should return null when route cannot be found due to a different path', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fastify.findRoute({
|
||||
method: 'GET',
|
||||
url: '/books/:bookId'
|
||||
}), null)
|
||||
})
|
||||
|
||||
test('findRoute should return the route when found', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
const handler = (req, reply) => reply.send(typeof req.params.artistId)
|
||||
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler
|
||||
})
|
||||
|
||||
const route = fastify.findRoute({
|
||||
method: 'GET',
|
||||
url: '/artists/:artistId'
|
||||
})
|
||||
t.assert.strictEqual(route.params.artistId, ':artistId')
|
||||
})
|
||||
|
||||
test('findRoute should work correctly when used within plugins', (t, done) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
const handler = (req, reply) => reply.send(typeof req.params.artistId)
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler
|
||||
})
|
||||
|
||||
function validateRoutePlugin (instance, opts, done) {
|
||||
const validateParams = function () {
|
||||
return instance.findRoute({
|
||||
method: 'GET',
|
||||
url: '/artists/:artistId'
|
||||
}) !== null
|
||||
}
|
||||
instance.decorate('validateRoutes', { validateParams })
|
||||
done()
|
||||
}
|
||||
|
||||
fastify.register(fastifyPlugin(validateRoutePlugin))
|
||||
|
||||
fastify.ready(() => {
|
||||
t.assert.strictEqual(fastify.validateRoutes.validateParams(), true)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('findRoute should not expose store', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.get('/artists/:artistId', {
|
||||
schema: {
|
||||
params: { artistId: { type: 'integer' } }
|
||||
},
|
||||
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
||||
})
|
||||
|
||||
const route = fastify.findRoute({
|
||||
method: 'GET',
|
||||
url: '/artists/:artistId'
|
||||
})
|
||||
t.assert.strictEqual(route.store, undefined)
|
||||
})
|
||||
209
node_modules/fastify/test/fluent-schema.test.js
generated
vendored
209
node_modules/fastify/test/fluent-schema.test.js
generated
vendored
@@ -1,209 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
const S = require('fluent-json-schema')
|
||||
|
||||
test('use fluent-json-schema object', async (t) => {
|
||||
t.plan(10)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.post('/:id', {
|
||||
handler: (req, reply) => { reply.send({ name: 'a', surname: 'b', dateOfBirth: '01-01-2020' }) },
|
||||
schema: {
|
||||
params: S.object().prop('id', S.integer().minimum(42)),
|
||||
headers: S.object().prop('x-custom', S.string().format('email')),
|
||||
query: S.object().prop('surname', S.string().required()),
|
||||
body: S.object().prop('name', S.string().required()),
|
||||
response: {
|
||||
200: S.object()
|
||||
.prop('name', S.string())
|
||||
.prop('surname', S.string())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const res1 = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/1',
|
||||
headers: { 'x-custom': 'me@me.me' },
|
||||
query: { surname: 'bar' },
|
||||
payload: { name: 'foo' }
|
||||
})
|
||||
t.assert.strictEqual(res1.statusCode, 400)
|
||||
t.assert.deepStrictEqual(res1.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'params/id must be >= 42' })
|
||||
|
||||
// check header
|
||||
const res2 = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/42',
|
||||
headers: { 'x-custom': 'invalid' },
|
||||
query: { surname: 'bar' },
|
||||
payload: { name: 'foo' }
|
||||
})
|
||||
t.assert.strictEqual(res2.statusCode, 400)
|
||||
t.assert.deepStrictEqual(res2.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'headers/x-custom must match format "email"' })
|
||||
|
||||
// check query
|
||||
const res3 = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/42',
|
||||
headers: { 'x-custom': 'me@me.me' },
|
||||
query: { },
|
||||
payload: { name: 'foo' }
|
||||
})
|
||||
t.assert.strictEqual(res3.statusCode, 400)
|
||||
t.assert.deepStrictEqual(res3.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'querystring must have required property \'surname\'' })
|
||||
|
||||
// check body
|
||||
const res4 = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/42',
|
||||
headers: { 'x-custom': 'me@me.me' },
|
||||
query: { surname: 'bar' },
|
||||
payload: { name: [1, 2, 3] }
|
||||
})
|
||||
t.assert.strictEqual(res4.statusCode, 400)
|
||||
t.assert.deepStrictEqual(res4.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'body/name must be string' })
|
||||
|
||||
// check response
|
||||
const res5 = await fastify.inject({
|
||||
method: 'POST',
|
||||
url: '/42',
|
||||
headers: { 'x-custom': 'me@me.me' },
|
||||
query: { surname: 'bar' },
|
||||
payload: { name: 'foo' }
|
||||
})
|
||||
t.assert.strictEqual(res5.statusCode, 200)
|
||||
t.assert.deepStrictEqual(res5.json(), { name: 'a', surname: 'b' })
|
||||
})
|
||||
|
||||
test('use complex fluent-json-schema object', (t, done) => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
const addressSchema = S.object()
|
||||
.id('#address')
|
||||
.prop('line1').required()
|
||||
.prop('line2')
|
||||
.prop('country').required()
|
||||
.prop('city').required()
|
||||
.prop('zipcode').required()
|
||||
|
||||
const commonSchemas = S.object()
|
||||
.id('https://fastify/demo')
|
||||
.definition('addressSchema', addressSchema)
|
||||
|
||||
fastify.addSchema(commonSchemas)
|
||||
|
||||
const bodyJsonSchema = S.object()
|
||||
.prop('residence', S.ref('https://fastify/demo#address')).required()
|
||||
.prop('office', S.ref('https://fastify/demo#/definitions/addressSchema')).required()
|
||||
|
||||
fastify.post('/the/url', { schema: { body: bodyJsonSchema } }, () => { })
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('use fluent schema and plain JSON schema', (t, done) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
const addressSchema = S.object()
|
||||
.id('#address')
|
||||
.prop('line1').required()
|
||||
.prop('line2')
|
||||
.prop('country').required()
|
||||
.prop('city').required()
|
||||
.prop('zipcode').required()
|
||||
|
||||
const commonSchemas = S.object()
|
||||
.id('https://fastify/demo')
|
||||
.definition('addressSchema', addressSchema)
|
||||
|
||||
const sharedAddressSchema = {
|
||||
$id: 'sharedAddress',
|
||||
type: 'object',
|
||||
required: ['line1', 'country', 'city', 'zipcode'],
|
||||
properties: {
|
||||
line1: { type: 'string' },
|
||||
line2: { type: 'string' },
|
||||
country: { type: 'string' },
|
||||
city: { type: 'string' },
|
||||
zipcode: { type: 'string' }
|
||||
}
|
||||
}
|
||||
|
||||
fastify.addSchema(commonSchemas)
|
||||
fastify.addSchema(sharedAddressSchema)
|
||||
|
||||
const bodyJsonSchema = S.object()
|
||||
.prop('residence', S.ref('https://fastify/demo#address')).required()
|
||||
.prop('office', S.ref('https://fastify/demo#/definitions/addressSchema')).required()
|
||||
|
||||
fastify.post('/the/url', { schema: { body: bodyJsonSchema } }, () => { })
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('Should call valueOf internally', (t, done) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = new Fastify()
|
||||
|
||||
const addressSchema = S.object()
|
||||
.id('#address')
|
||||
.prop('line1').required()
|
||||
.prop('line2')
|
||||
.prop('country').required()
|
||||
.prop('city').required()
|
||||
.prop('zipcode').required()
|
||||
|
||||
const commonSchemas = S.object()
|
||||
.id('https://fastify/demo')
|
||||
.definition('addressSchema', addressSchema)
|
||||
|
||||
fastify.addSchema(commonSchemas)
|
||||
|
||||
fastify.route({
|
||||
method: 'POST',
|
||||
url: '/query',
|
||||
handler: () => {},
|
||||
schema: {
|
||||
query: S.object().prop('hello', S.string()).required(),
|
||||
body: S.object().prop('hello', S.string()).required(),
|
||||
params: S.object().prop('hello', S.string()).required(),
|
||||
headers: S.object().prop('hello', S.string()).required(),
|
||||
response: {
|
||||
200: S.object().prop('hello', S.string()).required(),
|
||||
201: S.object().prop('hello', S.string()).required()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fastify.route({
|
||||
method: 'POST',
|
||||
url: '/querystring',
|
||||
handler: () => {},
|
||||
schema: {
|
||||
querystring: S.object().prop('hello', S.string()).required(),
|
||||
body: S.object().prop('hello', S.string()).required(),
|
||||
params: S.object().prop('hello', S.string()).required(),
|
||||
headers: S.object().prop('hello', S.string()).required(),
|
||||
response: {
|
||||
200: S.object().prop('hello', S.string()).required(),
|
||||
201: S.object().prop('hello', S.string()).required()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
426
node_modules/fastify/test/genReqId.test.js
generated
vendored
426
node_modules/fastify/test/genReqId.test.js
generated
vendored
@@ -1,426 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { Readable } = require('node:stream')
|
||||
const { test } = require('node:test')
|
||||
const fp = require('fastify-plugin')
|
||||
const Fastify = require('..')
|
||||
|
||||
test('Should accept a custom genReqId function', (t, done) => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify({
|
||||
genReqId: function (req) {
|
||||
return 'a'
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: `http://localhost:${fastify.server.address().port}`
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'a')
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Custom genReqId function gets raw request as argument', (t, done) => {
|
||||
t.plan(9)
|
||||
|
||||
const REQUEST_ID = 'REQ-1234'
|
||||
|
||||
const fastify = Fastify({
|
||||
genReqId: function (req) {
|
||||
t.assert.strictEqual('id' in req, false)
|
||||
t.assert.strictEqual('raw' in req, false)
|
||||
t.assert.ok(req instanceof Readable)
|
||||
// http.IncomingMessage does have `rawHeaders` property, but FastifyRequest does not
|
||||
const index = req.rawHeaders.indexOf('x-request-id')
|
||||
const xReqId = req.rawHeaders[index + 1]
|
||||
t.assert.strictEqual(xReqId, REQUEST_ID)
|
||||
t.assert.strictEqual(req.headers['x-request-id'], REQUEST_ID)
|
||||
return xReqId
|
||||
}
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.strictEqual(req.id, REQUEST_ID)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-request-id': REQUEST_ID
|
||||
},
|
||||
url: `http://localhost:${fastify.server.address().port}`
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, REQUEST_ID)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should handle properly requestIdHeader option', t => {
|
||||
t.plan(4)
|
||||
|
||||
t.assert.strictEqual(Fastify({ requestIdHeader: '' }).initialConfig.requestIdHeader, false)
|
||||
t.assert.strictEqual(Fastify({ requestIdHeader: false }).initialConfig.requestIdHeader, false)
|
||||
t.assert.strictEqual(Fastify({ requestIdHeader: true }).initialConfig.requestIdHeader, 'request-id')
|
||||
t.assert.strictEqual(Fastify({ requestIdHeader: 'x-request-id' }).initialConfig.requestIdHeader, 'x-request-id')
|
||||
})
|
||||
|
||||
test('Should accept option to set genReqId with setGenReqId option', (t, done) => {
|
||||
t.plan(9)
|
||||
|
||||
const fastify = Fastify({
|
||||
genReqId: function (req) {
|
||||
return 'base'
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.register(function (instance, opts, next) {
|
||||
instance.setGenReqId(function (req) {
|
||||
return 'foo'
|
||||
})
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}, { prefix: 'foo' })
|
||||
|
||||
fastify.register(function (instance, opts, next) {
|
||||
instance.setGenReqId(function (req) {
|
||||
return 'bar'
|
||||
})
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}, { prefix: 'bar' })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
let pending = 3
|
||||
|
||||
function completed () {
|
||||
if (--pending === 0) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'base')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/foo'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'foo')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/bar'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'bar')
|
||||
completed()
|
||||
})
|
||||
})
|
||||
|
||||
test('Should encapsulate setGenReqId', (t, done) => {
|
||||
t.plan(12)
|
||||
|
||||
const fastify = Fastify({
|
||||
genReqId: function (req) {
|
||||
return 'base'
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
const bazInstance = function (instance, opts, next) {
|
||||
instance.register(barInstance, { prefix: 'baz' })
|
||||
|
||||
instance.setGenReqId(function (req) {
|
||||
return 'baz'
|
||||
})
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}
|
||||
|
||||
const barInstance = function (instance, opts, next) {
|
||||
instance.setGenReqId(function (req) {
|
||||
return 'bar'
|
||||
})
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}
|
||||
|
||||
const fooInstance = function (instance, opts, next) {
|
||||
instance.register(bazInstance, { prefix: 'baz' })
|
||||
instance.register(barInstance, { prefix: 'bar' })
|
||||
|
||||
instance.setGenReqId(function (req) {
|
||||
return 'foo'
|
||||
})
|
||||
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}
|
||||
|
||||
fastify.register(fooInstance, { prefix: 'foo' })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
let pending = 4
|
||||
|
||||
function completed () {
|
||||
if (--pending === 0) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'base')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/foo'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'foo')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/foo/bar'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'bar')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/foo/baz'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'baz')
|
||||
completed()
|
||||
})
|
||||
})
|
||||
|
||||
test('Should not alter parent of genReqId', (t, done) => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
const fooInstance = function (instance, opts, next) {
|
||||
instance.setGenReqId(function (req) {
|
||||
return 'foo'
|
||||
})
|
||||
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}
|
||||
|
||||
fastify.register(fooInstance, { prefix: 'foo' })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
let pending = 2
|
||||
|
||||
function completed () {
|
||||
if (--pending === 0) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'req-1')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/foo'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'foo')
|
||||
completed()
|
||||
})
|
||||
})
|
||||
|
||||
test('Should have child instance user parent genReqId', (t, done) => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify({
|
||||
genReqId: function (req) {
|
||||
return 'foo'
|
||||
}
|
||||
})
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const fooInstance = function (instance, opts, next) {
|
||||
instance.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
next()
|
||||
}
|
||||
|
||||
fastify.register(fooInstance, { prefix: 'foo' })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
let pending = 2
|
||||
|
||||
function completed () {
|
||||
if (--pending === 0) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'foo')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/foo'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'foo')
|
||||
completed()
|
||||
})
|
||||
})
|
||||
|
||||
test('genReqId set on root scope when using fastify-plugin', (t, done) => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.after(() => fastify.close())
|
||||
|
||||
fastify.register(fp(function (fastify, options, done) {
|
||||
fastify.setGenReqId(function (req) {
|
||||
return 'not-encapsulated'
|
||||
})
|
||||
fastify.get('/not-encapsulated-1', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
done()
|
||||
}))
|
||||
|
||||
fastify.get('/not-encapsulated-2', (req, reply) => {
|
||||
t.assert.ok(req.id)
|
||||
reply.send({ id: req.id })
|
||||
})
|
||||
|
||||
let pending = 2
|
||||
|
||||
function completed () {
|
||||
if (--pending === 0) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/not-encapsulated-1'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'not-encapsulated')
|
||||
completed()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/not-encapsulated-2'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
const payload = JSON.parse(res.payload)
|
||||
t.assert.strictEqual(payload.id, 'not-encapsulated')
|
||||
completed()
|
||||
})
|
||||
})
|
||||
45
node_modules/fastify/test/handler-context.test.js
generated
vendored
45
node_modules/fastify/test/handler-context.test.js
generated
vendored
@@ -1,45 +0,0 @@
|
||||
'use strict'
|
||||
const { test } = require('node:test')
|
||||
const { kRouteContext } = require('../lib/symbols')
|
||||
const fastify = require('..')
|
||||
|
||||
test('handlers receive correct `this` context', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
// simulate plugin that uses fastify-plugin
|
||||
const plugin = function (instance, opts, done) {
|
||||
instance.decorate('foo', 'foo')
|
||||
done()
|
||||
}
|
||||
plugin[Symbol.for('skip-override')] = true
|
||||
|
||||
const instance = fastify()
|
||||
instance.register(plugin)
|
||||
|
||||
instance.get('/', function (req, reply) {
|
||||
t.assert.ok(this.foo)
|
||||
t.assert.strictEqual(this.foo, 'foo')
|
||||
reply.send()
|
||||
})
|
||||
|
||||
await instance.inject('/')
|
||||
|
||||
t.assert.ok(instance.foo)
|
||||
t.assert.strictEqual(instance.foo, 'foo')
|
||||
})
|
||||
|
||||
test('handlers have access to the internal context', async (t) => {
|
||||
t.plan(5)
|
||||
|
||||
const instance = fastify()
|
||||
instance.get('/', { config: { foo: 'bar' } }, function (req, reply) {
|
||||
t.assert.ok(reply[kRouteContext])
|
||||
t.assert.ok(reply[kRouteContext].config)
|
||||
t.assert.ok(typeof reply[kRouteContext].config, Object)
|
||||
t.assert.ok(reply[kRouteContext].config.foo)
|
||||
t.assert.strictEqual(reply[kRouteContext].config.foo, 'bar')
|
||||
reply.send()
|
||||
})
|
||||
|
||||
await instance.inject('/')
|
||||
})
|
||||
88
node_modules/fastify/test/has-route.test.js
generated
vendored
88
node_modules/fastify/test/has-route.test.js
generated
vendored
@@ -1,88 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test, describe } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
describe('hasRoute', async t => {
|
||||
test('hasRoute - invalid options', t => {
|
||||
t.plan(3)
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({ }), false)
|
||||
t.assert.strictEqual(fastify.hasRoute({ method: 'GET' }), false)
|
||||
t.assert.strictEqual(fastify.hasRoute({ constraints: [] }), false)
|
||||
})
|
||||
|
||||
test('hasRoute - primitive method', t => {
|
||||
t.plan(2)
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}), true)
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({
|
||||
method: 'POST',
|
||||
url: '/'
|
||||
}), false)
|
||||
})
|
||||
|
||||
test('hasRoute - with constraints', t => {
|
||||
t.plan(2)
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
constraints: { version: '1.2.0' },
|
||||
handler: (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
constraints: { version: '1.2.0' }
|
||||
}), true)
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
constraints: { version: '1.3.0' }
|
||||
}), false)
|
||||
})
|
||||
|
||||
test('hasRoute - parametric route regexp with constraints', t => {
|
||||
t.plan(1)
|
||||
// parametric with regexp
|
||||
fastify.get('/example/:file(^\\d+).png', function (request, reply) { })
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({
|
||||
method: 'GET',
|
||||
url: '/example/:file(^\\d+).png'
|
||||
}), true)
|
||||
})
|
||||
|
||||
test('hasRoute - finds a route even if method is not uppercased', t => {
|
||||
t.plan(1)
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/equal',
|
||||
handler: function (req, reply) {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(fastify.hasRoute({
|
||||
method: 'get',
|
||||
url: '/equal'
|
||||
}), true)
|
||||
})
|
||||
})
|
||||
55
node_modules/fastify/test/header-overflow.test.js
generated
vendored
55
node_modules/fastify/test/header-overflow.test.js
generated
vendored
@@ -1,55 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('..')
|
||||
|
||||
const maxHeaderSize = 1024
|
||||
|
||||
test('Should return 431 if request header fields are too large', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify({ http: { maxHeaderSize } })
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: (_req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Large-Header': 'a'.repeat(maxHeaderSize)
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 431)
|
||||
|
||||
t.after(() => fastify.close())
|
||||
})
|
||||
|
||||
test('Should return 431 if URI is too long', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify({ http: { maxHeaderSize } })
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: (_req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`${fastifyServer}/${'a'.repeat(maxHeaderSize)}`)
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 431)
|
||||
|
||||
t.after(() => fastify.close())
|
||||
})
|
||||
496
node_modules/fastify/test/helper.js
generated
vendored
496
node_modules/fastify/test/helper.js
generated
vendored
@@ -1,496 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const dns = require('node:dns').promises
|
||||
const stream = require('node:stream')
|
||||
const { promisify } = require('node:util')
|
||||
const symbols = require('../lib/symbols')
|
||||
const { waitForCb } = require('./toolkit')
|
||||
const assert = require('node:assert')
|
||||
|
||||
module.exports.sleep = promisify(setTimeout)
|
||||
|
||||
/**
|
||||
* @param method HTTP request method
|
||||
* @param t node:test instance
|
||||
* @param isSetErrorHandler true: using setErrorHandler
|
||||
*/
|
||||
module.exports.payloadMethod = function (method, t, isSetErrorHandler = false) {
|
||||
const test = t.test
|
||||
const fastify = require('..')()
|
||||
|
||||
if (isSetErrorHandler) {
|
||||
fastify.setErrorHandler(function (err, request, reply) {
|
||||
assert.ok(request instanceof fastify[symbols.kRequest].parent)
|
||||
assert.strictEqual(typeof request, 'object')
|
||||
reply
|
||||
.code(err.statusCode)
|
||||
.type('application/json; charset=utf-8')
|
||||
.send(err)
|
||||
})
|
||||
}
|
||||
|
||||
const upMethod = method.toUpperCase()
|
||||
const loMethod = method.toLowerCase()
|
||||
|
||||
const schema = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test(`${upMethod} can be created`, t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify[loMethod]('/', schema, function (req, reply) {
|
||||
reply.code(200).send(req.body)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test(`${upMethod} without schema can be created`, t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify[loMethod]('/missing', function (req, reply) {
|
||||
reply.code(200).send(req.body)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test(`${upMethod} with body and querystring`, t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify[loMethod]('/with-query', function (req, reply) {
|
||||
req.body.hello = req.body.hello + req.query.foo
|
||||
reply.code(200).send(req.body)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test(`${upMethod} with bodyLimit option`, t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify[loMethod]('/with-limit', { bodyLimit: 1 }, function (req, reply) {
|
||||
reply.send(req.body)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
fastify.listen({ port: 0 }, function (err) {
|
||||
if (err) {
|
||||
t.assert.ifError(err)
|
||||
return
|
||||
}
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
test(`${upMethod} - correctly replies`, async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: upMethod,
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
test(`${upMethod} - correctly replies with very large body`, async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const largeString = 'world'.repeat(13200)
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: upMethod,
|
||||
body: JSON.stringify({ hello: largeString }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: largeString })
|
||||
})
|
||||
|
||||
test(`${upMethod} - correctly replies if the content type has the charset`, async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: upMethod,
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=utf-8'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.text(), JSON.stringify({ hello: 'world' }))
|
||||
})
|
||||
|
||||
test(`${upMethod} without schema - correctly replies`, async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port + '/missing', {
|
||||
method: upMethod,
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
|
||||
test(`${upMethod} with body and querystring - correctly replies`, async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port + '/with-query?foo=hello', {
|
||||
method: upMethod,
|
||||
body: JSON.stringify({ hello: 'world' }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'worldhello' })
|
||||
})
|
||||
|
||||
test(`${upMethod} with no body - correctly replies`, t => {
|
||||
t.plan(6)
|
||||
|
||||
const { stepIn, patience } = waitForCb({ steps: 2 })
|
||||
|
||||
fetch('http://localhost:' + fastify.server.address().port + '/missing', {
|
||||
method: upMethod,
|
||||
headers: { 'Content-Length': '0' }
|
||||
}).then(async (response) => {
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
t.assert.strictEqual(await response.text(), '')
|
||||
stepIn()
|
||||
})
|
||||
|
||||
// Must use inject to make a request without a Content-Length header
|
||||
fastify.inject({
|
||||
method: upMethod,
|
||||
url: '/missing'
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(res.statusCode, 200)
|
||||
t.assert.strictEqual(res.payload.toString(), '')
|
||||
stepIn()
|
||||
})
|
||||
|
||||
return patience
|
||||
})
|
||||
|
||||
test(`${upMethod} returns 415 - incorrect media type if body is not json`, async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port + '/missing', {
|
||||
method: upMethod,
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': undefined
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
})
|
||||
|
||||
if (loMethod === 'options') {
|
||||
test('OPTIONS returns 415 - should return 415 if Content-Type is not json or plain text', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const result = await fetch('http://localhost:' + fastify.server.address().port + '/missing', {
|
||||
method: upMethod,
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'text/xml'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
})
|
||||
}
|
||||
|
||||
test(`${upMethod} returns 400 - Bad Request`, t => {
|
||||
const isOptions = upMethod === 'OPTIONS'
|
||||
t.plan(isOptions ? 2 : 4)
|
||||
|
||||
const { stepIn, patience } = waitForCb({ steps: isOptions ? 1 : 2 })
|
||||
|
||||
fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: upMethod,
|
||||
body: 'hello world',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => {
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
stepIn()
|
||||
})
|
||||
|
||||
if (!isOptions) {
|
||||
fetch(`http://localhost:${fastify.server.address().port}`, {
|
||||
method: upMethod,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '0'
|
||||
}
|
||||
}).then((response) => {
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
stepIn()
|
||||
})
|
||||
}
|
||||
|
||||
return patience
|
||||
})
|
||||
|
||||
test(`${upMethod} returns 413 - Payload Too Large`, t => {
|
||||
const isOptions = upMethod === 'OPTIONS'
|
||||
t.plan(isOptions ? 3 : 5)
|
||||
|
||||
const { stepIn, patience } = waitForCb({ steps: isOptions ? 2 : 3 })
|
||||
|
||||
fetch(`http://localhost:${fastify.server.address().port}`, {
|
||||
method: upMethod,
|
||||
body: JSON.stringify({ w: 'w'.repeat(1024 * 1024 + 1) }),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => {
|
||||
t.assert.strictEqual(response.status, 413)
|
||||
stepIn()
|
||||
}).catch((err) => {
|
||||
// Handle EPIPE error - server closed connection after sending 413
|
||||
if (err.cause?.code === 'EPIPE' || err.message.includes('fetch failed')) {
|
||||
t.assert.ok(true, 'Expected EPIPE error due to server closing connection on 413')
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
stepIn()
|
||||
})
|
||||
|
||||
// Node errors for OPTIONS requests with a stream body and no Content-Length header
|
||||
if (!isOptions) {
|
||||
let chunk = Buffer.alloc(1024 * 1024 + 1, 0)
|
||||
const largeStream = new stream.Readable({
|
||||
read () {
|
||||
this.push(chunk)
|
||||
chunk = null
|
||||
}
|
||||
})
|
||||
fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: upMethod,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: largeStream,
|
||||
duplex: 'half'
|
||||
}).then((response) => {
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 413)
|
||||
stepIn()
|
||||
}).catch((err) => {
|
||||
// Handle EPIPE error - server closed connection after sending 413
|
||||
if (err.cause?.code === 'EPIPE' || err.message.includes('fetch failed')) {
|
||||
t.assert.ok(true, 'Expected EPIPE error due to server closing connection on 413')
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
stepIn()
|
||||
})
|
||||
}
|
||||
|
||||
fetch(`http://localhost:${fastify.server.address().port}/with-limit`, {
|
||||
method: upMethod,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({})
|
||||
}).then((response) => {
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 413)
|
||||
stepIn()
|
||||
})
|
||||
|
||||
return patience
|
||||
})
|
||||
|
||||
test(`${upMethod} should fail with empty body and application/json content-type`, t => {
|
||||
if (upMethod === 'OPTIONS') return
|
||||
|
||||
t.plan(12)
|
||||
|
||||
const { stepIn, patience } = waitForCb({ steps: 5 })
|
||||
|
||||
fastify.inject({
|
||||
method: `${upMethod}`,
|
||||
url: '/',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
fetch(`http://localhost:${fastify.server.address().port}`, {
|
||||
method: upMethod,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(async (res) => {
|
||||
t.assert.ok(!res.ok)
|
||||
t.assert.deepStrictEqual(await res.json(), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
stepIn()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: `${upMethod}`,
|
||||
url: '/',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
payload: null
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
stepIn()
|
||||
})
|
||||
|
||||
fetch(`http://localhost:${fastify.server.address().port}`, {
|
||||
method: upMethod,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: null
|
||||
}).then(async (res) => {
|
||||
t.assert.ok(!res.ok)
|
||||
t.assert.deepStrictEqual(await res.json(), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
stepIn()
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: `${upMethod}`,
|
||||
url: '/',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
payload: undefined
|
||||
}, (err, res) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
stepIn()
|
||||
})
|
||||
|
||||
fetch(`http://localhost:${fastify.server.address().port}`, {
|
||||
method: upMethod,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: undefined
|
||||
}).then(async (res) => {
|
||||
t.assert.ok(!res.ok)
|
||||
t.assert.deepStrictEqual(await res.json(), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_CTP_EMPTY_JSON_BODY',
|
||||
message: 'Body cannot be empty when content-type is set to \'application/json\'',
|
||||
statusCode: 400
|
||||
})
|
||||
stepIn()
|
||||
})
|
||||
|
||||
return patience
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function lookupToIp (lookup) {
|
||||
return lookup.family === 6 ? `[${lookup.address}]` : lookup.address
|
||||
}
|
||||
|
||||
module.exports.getLoopbackHost = async () => {
|
||||
const lookup = await dns.lookup('localhost')
|
||||
return [lookup.address, lookupToIp(lookup)]
|
||||
}
|
||||
|
||||
module.exports.plainTextParser = function (request, callback) {
|
||||
let body = ''
|
||||
request.setEncoding('utf8')
|
||||
request.on('error', onError)
|
||||
request.on('data', onData)
|
||||
request.on('end', onEnd)
|
||||
function onError (err) {
|
||||
callback(err, null)
|
||||
}
|
||||
function onData (chunk) {
|
||||
body += chunk
|
||||
}
|
||||
function onEnd () {
|
||||
callback(null, body)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.getServerUrl = function (app) {
|
||||
const { address, port } = app.server.address()
|
||||
return address === '::1'
|
||||
? `http://[${address}]:${port}`
|
||||
: `http://${address}:${port}`
|
||||
}
|
||||
1099
node_modules/fastify/test/hooks-async.test.js
generated
vendored
1099
node_modules/fastify/test/hooks-async.test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
1162
node_modules/fastify/test/hooks.on-listen.test.js
generated
vendored
1162
node_modules/fastify/test/hooks.on-listen.test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
421
node_modules/fastify/test/hooks.on-ready.test.js
generated
vendored
421
node_modules/fastify/test/hooks.on-ready.test.js
generated
vendored
@@ -1,421 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../fastify')
|
||||
const immediate = require('node:util').promisify(setImmediate)
|
||||
|
||||
test('onReady should be called in order', (t, done) => {
|
||||
t.plan(7)
|
||||
const fastify = Fastify()
|
||||
|
||||
let order = 0
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.strictEqual(order++, 0, 'called in root')
|
||||
t.assert.strictEqual(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.register(async (childOne, o) => {
|
||||
childOne.addHook('onReady', function (done) {
|
||||
t.assert.strictEqual(order++, 1, 'called in childOne')
|
||||
t.assert.strictEqual(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
|
||||
done()
|
||||
})
|
||||
|
||||
childOne.register(async (childTwo, o) => {
|
||||
childTwo.addHook('onReady', async function () {
|
||||
await immediate()
|
||||
t.assert.strictEqual(order++, 2, 'called in childTwo')
|
||||
t.assert.strictEqual(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady should be called once', async (t) => {
|
||||
const app = Fastify()
|
||||
let counter = 0
|
||||
|
||||
app.addHook('onReady', async function () {
|
||||
counter++
|
||||
})
|
||||
|
||||
const promises = [1, 2, 3, 4, 5].map((id) => app.ready().then(() => id))
|
||||
|
||||
const result = await Promise.race(promises)
|
||||
|
||||
t.assert.strictEqual(result, 1, 'Should resolve in order')
|
||||
t.assert.strictEqual(counter, 1, 'Should call onReady only once')
|
||||
})
|
||||
|
||||
test('async onReady should be called in order', async t => {
|
||||
t.plan(7)
|
||||
const fastify = Fastify()
|
||||
|
||||
let order = 0
|
||||
|
||||
fastify.addHook('onReady', async function () {
|
||||
await immediate()
|
||||
t.assert.strictEqual(order++, 0, 'called in root')
|
||||
t.assert.strictEqual(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
|
||||
})
|
||||
|
||||
fastify.register(async (childOne, o) => {
|
||||
childOne.addHook('onReady', async function () {
|
||||
await immediate()
|
||||
t.assert.strictEqual(order++, 1, 'called in childOne')
|
||||
t.assert.strictEqual(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
|
||||
})
|
||||
|
||||
childOne.register(async (childTwo, o) => {
|
||||
childTwo.addHook('onReady', async function () {
|
||||
await immediate()
|
||||
t.assert.strictEqual(order++, 2, 'called in childTwo')
|
||||
t.assert.strictEqual(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.ok('ready')
|
||||
})
|
||||
|
||||
test('mix ready and onReady', async t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
let order = 0
|
||||
|
||||
fastify.addHook('onReady', async function () {
|
||||
await immediate()
|
||||
order++
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.strictEqual(order, 1)
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.strictEqual(order, 1, 'ready hooks execute once')
|
||||
})
|
||||
|
||||
test('listen and onReady order', async t => {
|
||||
t.plan(9)
|
||||
|
||||
const fastify = Fastify()
|
||||
let order = 0
|
||||
|
||||
fastify.register((instance, opts, done) => {
|
||||
instance.ready(checkOrder.bind(null, 0))
|
||||
instance.addHook('onReady', checkOrder.bind(null, 4))
|
||||
|
||||
instance.register((subinstance, opts, done) => {
|
||||
subinstance.ready(checkOrder.bind(null, 1))
|
||||
subinstance.addHook('onReady', checkOrder.bind(null, 5))
|
||||
|
||||
subinstance.register((realSubInstance, opts, done) => {
|
||||
realSubInstance.ready(checkOrder.bind(null, 2))
|
||||
realSubInstance.addHook('onReady', checkOrder.bind(null, 6))
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.addHook('onReady', checkOrder.bind(null, 3))
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.ok('trigger the onReady')
|
||||
await fastify.listen({ port: 0 })
|
||||
t.assert.ok('do not trigger the onReady')
|
||||
|
||||
await fastify.close()
|
||||
|
||||
function checkOrder (shouldbe) {
|
||||
t.assert.strictEqual(order, shouldbe)
|
||||
order++
|
||||
}
|
||||
})
|
||||
|
||||
test('multiple ready calls', async t => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
let order = 0
|
||||
|
||||
fastify.register(async (instance, opts) => {
|
||||
instance.ready(checkOrder.bind(null, 1))
|
||||
instance.addHook('onReady', checkOrder.bind(null, 6))
|
||||
|
||||
await instance.register(async (subinstance, opts) => {
|
||||
subinstance.ready(checkOrder.bind(null, 2))
|
||||
subinstance.addHook('onReady', checkOrder.bind(null, 7))
|
||||
})
|
||||
|
||||
t.assert.strictEqual(order, 0, 'ready and hooks not triggered yet')
|
||||
order++
|
||||
})
|
||||
|
||||
fastify.addHook('onReady', checkOrder.bind(null, 3))
|
||||
fastify.addHook('onReady', checkOrder.bind(null, 4))
|
||||
fastify.addHook('onReady', checkOrder.bind(null, 5))
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.ok('trigger the onReady')
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.ok('do not trigger the onReady')
|
||||
|
||||
await fastify.ready()
|
||||
t.assert.ok('do not trigger the onReady')
|
||||
|
||||
function checkOrder (shouldbe) {
|
||||
t.assert.strictEqual(order, shouldbe)
|
||||
order++
|
||||
}
|
||||
})
|
||||
|
||||
test('onReady should manage error in sync', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in root')
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.register(async (childOne, o) => {
|
||||
childOne.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in childOne')
|
||||
done(new Error('FAIL ON READY'))
|
||||
})
|
||||
|
||||
childOne.register(async (childTwo, o) => {
|
||||
childTwo.addHook('onReady', async function () {
|
||||
t.assert.fail('should not be called')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.message, 'FAIL ON READY')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady should manage error in async', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in root')
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.register(async (childOne, o) => {
|
||||
childOne.addHook('onReady', async function () {
|
||||
t.assert.ok('called in childOne')
|
||||
throw new Error('FAIL ON READY')
|
||||
})
|
||||
|
||||
childOne.register(async (childTwo, o) => {
|
||||
childTwo.addHook('onReady', async function () {
|
||||
t.assert.fail('should not be called')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.message, 'FAIL ON READY')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady should manage sync error', (t, done) => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in root')
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.register(async (childOne, o) => {
|
||||
childOne.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in childOne')
|
||||
throw new Error('FAIL UNWANTED SYNC EXCEPTION')
|
||||
})
|
||||
|
||||
childOne.register(async (childTwo, o) => {
|
||||
childTwo.addHook('onReady', async function () {
|
||||
t.assert.fail('should not be called')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.message, 'FAIL UNWANTED SYNC EXCEPTION')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady can not add decorators or application hooks', (t, done) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in root')
|
||||
fastify.decorate('test', () => {})
|
||||
|
||||
fastify.addHook('onReady', async function () {
|
||||
t.assert.fail('it will be not called')
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.ok(this.hasDecorator('test'))
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ifError(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady cannot add lifecycle hooks', (t, done) => {
|
||||
t.plan(5)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onReady', function (done) {
|
||||
t.assert.ok('called in root')
|
||||
try {
|
||||
fastify.addHook('onRequest', (request, reply, done) => {})
|
||||
} catch (error) {
|
||||
t.assert.ok(error)
|
||||
t.assert.strictEqual(error.message, 'Root plugin has already booted')
|
||||
// TODO: look where the error pops up
|
||||
t.assert.strictEqual(error.code, 'AVV_ERR_ROOT_PLG_BOOTED')
|
||||
done(error)
|
||||
}
|
||||
})
|
||||
|
||||
fastify.addHook('onRequest', (request, reply, done) => {})
|
||||
fastify.get('/', async () => 'hello')
|
||||
|
||||
fastify.ready((err) => {
|
||||
t.assert.ok(err)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady throw loading error', t => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
try {
|
||||
fastify.addHook('onReady', async function (done) {})
|
||||
} catch (e) {
|
||||
t.assert.strictEqual(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')
|
||||
t.assert.ok(e.message === 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')
|
||||
}
|
||||
})
|
||||
|
||||
test('onReady does not call done', (t, done) => {
|
||||
t.plan(6)
|
||||
const fastify = Fastify({ pluginTimeout: 500 })
|
||||
|
||||
fastify.addHook('onReady', function someHookName (done) {
|
||||
t.assert.ok('called in root')
|
||||
// done() // don't call done to test timeout
|
||||
})
|
||||
|
||||
fastify.ready(err => {
|
||||
t.assert.ok(err)
|
||||
t.assert.strictEqual(err.message, 'A callback for \'onReady\' hook "someHookName" timed out. You may have forgotten to call \'done\' function or to resolve a Promise')
|
||||
t.assert.strictEqual(err.code, 'FST_ERR_HOOK_TIMEOUT')
|
||||
t.assert.ok(err.cause)
|
||||
t.assert.strictEqual(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('onReady execution order', (t, done) => {
|
||||
t.plan(3)
|
||||
const fastify = Fastify({ })
|
||||
|
||||
let i = 0
|
||||
fastify.ready(() => { i++; t.assert.strictEqual(i, 1) })
|
||||
fastify.ready(() => { i++; t.assert.strictEqual(i, 2) })
|
||||
fastify.ready(() => {
|
||||
i++
|
||||
t.assert.strictEqual(i, 3)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('ready return the server with callback', (t, done) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.ready((err, instance) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.deepStrictEqual(instance, fastify)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('ready return the server with Promise', async t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
|
||||
await fastify.ready()
|
||||
.then(instance => { t.assert.deepStrictEqual(instance, fastify) })
|
||||
.catch(err => { t.assert.fail(err) })
|
||||
})
|
||||
|
||||
test('ready return registered', async t => {
|
||||
t.plan(4)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register((one, opts, done) => {
|
||||
one.ready().then(itself => { t.assert.deepStrictEqual(itself, one) })
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.register((two, opts, done) => {
|
||||
two.ready().then(itself => { t.assert.deepStrictEqual(itself, two) })
|
||||
|
||||
two.register((twoDotOne, opts, done) => {
|
||||
twoDotOne.ready().then(itself => { t.assert.deepStrictEqual(itself, twoDotOne) })
|
||||
done()
|
||||
})
|
||||
done()
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
.then(instance => { t.assert.deepStrictEqual(instance, fastify) })
|
||||
.catch(err => { t.assert.fail(err) })
|
||||
})
|
||||
|
||||
test('do not crash with error in follow up onReady hook', async t => {
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onReady', async function () {
|
||||
})
|
||||
|
||||
fastify.addHook('onReady', function () {
|
||||
throw new Error('kaboom')
|
||||
})
|
||||
|
||||
await t.assert.rejects(fastify.ready())
|
||||
})
|
||||
3578
node_modules/fastify/test/hooks.test.js
generated
vendored
3578
node_modules/fastify/test/hooks.test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
35
node_modules/fastify/test/http-methods/copy.test.js
generated
vendored
35
node_modules/fastify/test/http-methods/copy.test.js
generated
vendored
@@ -1,35 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('COPY')
|
||||
|
||||
test('can be created - copy', async t => {
|
||||
t.plan(3)
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'COPY',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
reply.code(204).send()
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch(`${fastifyServer}/test.txt`, {
|
||||
method: 'COPY',
|
||||
headers: {
|
||||
Destination: '/test2.txt'
|
||||
}
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 204)
|
||||
})
|
||||
114
node_modules/fastify/test/http-methods/custom-http-methods.test.js
generated
vendored
114
node_modules/fastify/test/http-methods/custom-http-methods.test.js
generated
vendored
@@ -1,114 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const http = require('node:http')
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../../fastify')
|
||||
|
||||
function addEcho (fastify, method) {
|
||||
fastify.route({
|
||||
method,
|
||||
url: '/',
|
||||
handler: function (req, reply) {
|
||||
reply.send(req.body)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
test('missing method from http client', (t, done) => {
|
||||
t.plan(2)
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.listen({ port: 3000 }, (err) => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const port = fastify.server.address().port
|
||||
const req = http.request({
|
||||
port,
|
||||
method: 'REBIND',
|
||||
path: '/'
|
||||
}, (res) => {
|
||||
t.assert.strictEqual(res.statusCode, 404)
|
||||
fastify.close()
|
||||
done()
|
||||
})
|
||||
|
||||
req.end()
|
||||
})
|
||||
})
|
||||
|
||||
test('addHttpMethod increase the supported HTTP methods supported', (t, done) => {
|
||||
t.plan(8)
|
||||
const app = Fastify()
|
||||
|
||||
t.assert.throws(() => { addEcho(app, 'REBIND') }, /REBIND method is not supported./)
|
||||
t.assert.ok(!app.supportedMethods.includes('REBIND'))
|
||||
t.assert.ok(!app.rebind)
|
||||
|
||||
app.addHttpMethod('REBIND')
|
||||
t.assert.doesNotThrow(() => { addEcho(app, 'REBIND') }, 'REBIND method is supported.')
|
||||
t.assert.ok(app.supportedMethods.includes('REBIND'))
|
||||
t.assert.ok(app.rebind)
|
||||
|
||||
app.rebind('/foo', () => 'hello')
|
||||
|
||||
app.inject({
|
||||
method: 'REBIND',
|
||||
url: '/foo'
|
||||
}, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.strictEqual(response.payload, 'hello')
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('addHttpMethod adds a new custom method without body', t => {
|
||||
t.plan(3)
|
||||
const app = Fastify()
|
||||
|
||||
t.assert.throws(() => { addEcho(app, 'REBIND') }, /REBIND method is not supported./)
|
||||
|
||||
app.addHttpMethod('REBIND')
|
||||
t.assert.doesNotThrow(() => { addEcho(app, 'REBIND') }, 'REBIND method is supported.')
|
||||
|
||||
t.assert.throws(() => {
|
||||
app.route({
|
||||
url: '/',
|
||||
method: 'REBIND',
|
||||
schema: {
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { type: 'string' }
|
||||
}
|
||||
}
|
||||
},
|
||||
handler: function (req, reply) {
|
||||
reply.send(req.body)
|
||||
}
|
||||
})
|
||||
}, /Body validation schema for REBIND:\/ route is not supported!/)
|
||||
})
|
||||
|
||||
test('addHttpMethod adds a new custom method with body', (t, done) => {
|
||||
t.plan(3)
|
||||
const app = Fastify()
|
||||
|
||||
app.addHttpMethod('REBIND', { hasBody: true })
|
||||
t.assert.doesNotThrow(() => { addEcho(app, 'REBIND') }, 'REBIND method is supported.')
|
||||
|
||||
app.inject({
|
||||
method: 'REBIND',
|
||||
url: '/',
|
||||
payload: { hello: 'world' }
|
||||
}, (err, response) => {
|
||||
t.assert.ifError(err)
|
||||
t.assert.deepStrictEqual(response.json(), { hello: 'world' })
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
test('addHttpMethod rejects fake http method', t => {
|
||||
t.plan(1)
|
||||
const fastify = Fastify()
|
||||
t.assert.throws(() => { fastify.addHttpMethod('FOOO') }, /Provided method is invalid!/)
|
||||
})
|
||||
412
node_modules/fastify/test/http-methods/get.test.js
generated
vendored
412
node_modules/fastify/test/http-methods/get.test.js
generated
vendored
@@ -1,412 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const { Client } = require('undici')
|
||||
const fastify = require('../../fastify')()
|
||||
|
||||
const schema = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nullSchema = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'null'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const numberSchema = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'number'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const querySchema = {
|
||||
schema: {
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const paramsSchema = {
|
||||
schema: {
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
type: 'string'
|
||||
},
|
||||
test: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const headersSchema = {
|
||||
schema: {
|
||||
headers: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
'x-test': {
|
||||
type: 'number'
|
||||
},
|
||||
'Y-Test': {
|
||||
type: 'number'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test('shorthand - get', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/', schema, function (req, reply) {
|
||||
reply.code(200).send({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - get (return null)', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/null', nullSchema, function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - get params', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/params/:foo/:test', paramsSchema, function (req, reply) {
|
||||
reply.code(200).send(req.params)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - get, querystring schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/query', querySchema, function (req, reply) {
|
||||
reply.code(200).send(req.query)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - get, headers schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/headers', headersSchema, function (req, reply) {
|
||||
reply.code(200).send(req.headers)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('missing schema - get', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/missing', function (req, reply) {
|
||||
reply.code(200).send({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('custom serializer - get', t => {
|
||||
t.plan(1)
|
||||
|
||||
function customSerializer (data) {
|
||||
return JSON.stringify(data)
|
||||
}
|
||||
|
||||
try {
|
||||
fastify.get('/custom-serializer', numberSchema, function (req, reply) {
|
||||
reply.code(200).serializer(customSerializer).send({ hello: 'world' })
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('empty response', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/empty', function (req, reply) {
|
||||
reply.code(200).send()
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('send a falsy boolean', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/boolean', function (req, reply) {
|
||||
reply.code(200).send(false)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - get, set port', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/port', headersSchema, function (req, reply) {
|
||||
reply.code(200).send({ port: req.port })
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('get test', async t => {
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('shorthand - request get', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port, {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get params schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/params/world/123', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { foo: 'world', test: 123 })
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get params schema error', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/params/world/string', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'params/test must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get headers schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/headers', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-test': '1',
|
||||
'Y-Test': '3'
|
||||
}
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.json()
|
||||
t.assert.strictEqual(body['x-test'], 1)
|
||||
t.assert.strictEqual(body['y-test'], 3)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get headers schema error', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/headers', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-test': 'abc'
|
||||
}
|
||||
})
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'headers/x-test must be number',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get querystring schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/query?hello=123', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 123 })
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get querystring schema error', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/query?hello=world', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(!response.ok)
|
||||
t.assert.strictEqual(response.status, 400)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'querystring/hello must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get missing schema', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/missing', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('shorthand - custom serializer', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/custom-serializer', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('shorthand - empty response', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/empty', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.strictEqual(response.headers.get('content-length'), '0')
|
||||
t.assert.deepStrictEqual(body.toString(), '')
|
||||
})
|
||||
|
||||
await t.test('shorthand - send a falsy boolean', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/boolean', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(body.toString(), 'false')
|
||||
})
|
||||
|
||||
await t.test('shorthand - send null value', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const response = await fetch('http://localhost:' + fastify.server.address().port + '/null', {
|
||||
method: 'GET'
|
||||
})
|
||||
t.assert.ok(response.ok)
|
||||
t.assert.strictEqual(response.status, 200)
|
||||
const body = await response.text()
|
||||
t.assert.deepStrictEqual(body.toString(), 'null')
|
||||
})
|
||||
|
||||
await t.test('shorthand - request get headers - test fall back port', async t => {
|
||||
t.plan(2)
|
||||
|
||||
const instance = new Client('http://localhost:' + fastify.server.address().port)
|
||||
|
||||
const response = await instance.request({
|
||||
path: '/port',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: 'example.com'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(response.statusCode, 200)
|
||||
const body = JSON.parse(await response.body.text())
|
||||
t.assert.strictEqual(body.port, null)
|
||||
})
|
||||
})
|
||||
263
node_modules/fastify/test/http-methods/head.test.js
generated
vendored
263
node_modules/fastify/test/http-methods/head.test.js
generated
vendored
@@ -1,263 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
|
||||
const schema = {
|
||||
schema: {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'null'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const querySchema = {
|
||||
schema: {
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const paramsSchema = {
|
||||
schema: {
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
type: 'string'
|
||||
},
|
||||
test: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test('shorthand - head', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.head('/', schema, function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - custom head', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.head('/proxy/*', function (req, reply) {
|
||||
reply.headers({ 'x-foo': 'bar' })
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
|
||||
fastify.get('/proxy/*', function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - custom head with constraints', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.head('/proxy/*', { constraints: { version: '1.0.0' } }, function (req, reply) {
|
||||
reply.headers({ 'x-foo': 'bar' })
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
|
||||
fastify.get('/proxy/*', { constraints: { version: '1.0.0' } }, function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - should not reset a head route', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.get('/query1', function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
|
||||
fastify.put('/query1', function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - should set get and head route in the same api call', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: ['HEAD', 'GET'],
|
||||
url: '/query4',
|
||||
handler: function (req, reply) {
|
||||
reply.headers({ 'x-foo': 'bar' })
|
||||
reply.code(200).send(null)
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - head params', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.head('/params/:foo/:test', paramsSchema, function (req, reply) {
|
||||
reply.send(null)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('shorthand - head, querystring schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.head('/query', querySchema, function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('missing schema - head', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.head('/missing', function (req, reply) {
|
||||
reply.code(200).send(null)
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('head test', async t => {
|
||||
t.after(() => { fastify.close() })
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('shorthand - request head', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(fastifyServer, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head params schema', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/params/world/123`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head params schema error', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/params/world/string`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 400)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head querystring schema', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/query?hello=123`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head querystring schema error', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/query?hello=world`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 400)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head missing schema', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/missing`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head custom head', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/proxy/test`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.headers.get('x-foo'), 'bar')
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - request head custom head with constraints', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/proxy/test`, {
|
||||
method: 'HEAD',
|
||||
headers: {
|
||||
version: '1.0.0'
|
||||
}
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.headers.get('x-foo'), 'bar')
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - should not reset a head route', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/query1`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
|
||||
await t.test('shorthand - should set get and head route in the same api call', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/query4`, {
|
||||
method: 'HEAD'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.headers.get('x-foo'), 'bar')
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
})
|
||||
})
|
||||
108
node_modules/fastify/test/http-methods/lock.test.js
generated
vendored
108
node_modules/fastify/test/http-methods/lock.test.js
generated
vendored
@@ -1,108 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('LOCK', { hasBody: true })
|
||||
|
||||
const bodySample = `<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:lockinfo xmlns:D='DAV:'>
|
||||
<D:lockscope> <D:exclusive/> </D:lockscope>
|
||||
<D:locktype> <D:write/> </D:locktype>
|
||||
<D:owner>
|
||||
<D:href>http://example.org/~ejw/contact.html</D:href>
|
||||
</D:owner>
|
||||
</D:lockinfo> `
|
||||
|
||||
test('can be created - lock', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'LOCK',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
reply
|
||||
.code(200)
|
||||
.send(`<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:prop xmlns:D="DAV:">
|
||||
<D:lockdiscovery>
|
||||
<D:activelock>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
<D:lockscope>
|
||||
<D:exclusive/>
|
||||
</D:lockscope>
|
||||
<D:depth>infinity</D:depth>
|
||||
<D:owner>
|
||||
<D:href>http://example.org/~ejw/contact.html</D:href>
|
||||
</D:owner>
|
||||
<D:timeout>Second-604800</D:timeout>
|
||||
<D:locktoken>
|
||||
<D:href>urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4</:href>
|
||||
</D:locktoken>
|
||||
<D:lockroot>
|
||||
<D:href>http://example.com/workspace/webdav/proposal.oc</D:href>
|
||||
</D:lockroot>
|
||||
</D:activelock>
|
||||
</D:lockdiscovery>
|
||||
</D:prop>`
|
||||
)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('lock test', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => {
|
||||
fastify.close()
|
||||
})
|
||||
// the body test uses a text/plain content type instead of application/xml because it requires
|
||||
// a specific content type parser
|
||||
await t.test('request with body - lock', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'LOCK',
|
||||
headers: { 'content-type': 'text/plain' },
|
||||
body: bodySample
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request with body and no content type (415 error) - lock', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'LOCK',
|
||||
body: bodySample,
|
||||
headers: { 'content-type': undefined }
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request without body - lock', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'LOCK',
|
||||
headers: { 'content-type': 'text/plain' }
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
})
|
||||
143
node_modules/fastify/test/http-methods/mkcalendar.test.js
generated
vendored
143
node_modules/fastify/test/http-methods/mkcalendar.test.js
generated
vendored
@@ -1,143 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('MKCALENDAR', { hasBody: true })
|
||||
|
||||
const bodySample = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<B:mkcalendar xmlns:B="urn:ietf:params:xml:ns:caldav">
|
||||
<A:set xmlns:A="DAV:">
|
||||
<A:prop>
|
||||
<B:calendar-free-busy-set>
|
||||
<NO/>
|
||||
</B:calendar-free-busy-set>
|
||||
<E:calendar-order xmlns:E="http://apple.com/ns/ical/">0</E:calendar-order>
|
||||
<B:supported-calendar-component-set>
|
||||
<B:comp name="VEVENT"/>
|
||||
</B:supported-calendar-component-set>
|
||||
<A:displayname>CALENDAR_NAME</A:displayname>
|
||||
<B:calendar-timezone>BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
</B:calendar-timezone>
|
||||
</A:prop>
|
||||
</A:set>
|
||||
</B:mkcalendar>
|
||||
`
|
||||
|
||||
test('can be created - mkcalendar', (t) => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'MKCALENDAR',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
return reply.code(207).send(`<?xml version="1.0" encoding="utf-8"?>
|
||||
<D:multistatus xmlns:D="DAV:">
|
||||
<D:response xmlns:lp1="DAV:">
|
||||
<D:href>/</D:href>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<lp1:resourcetype>
|
||||
<D:collection/>
|
||||
</lp1:resourcetype>
|
||||
<lp1:creationdate>2022-04-13T12:35:30Z</lp1:creationdate>
|
||||
<lp1:getlastmodified>Wed, 13 Apr 2022 12:35:30 GMT</lp1:getlastmodified>
|
||||
<lp1:getetag>"e0-5dc8869b53ef1"</lp1:getetag>
|
||||
<D:supportedlock>
|
||||
<D:lockentry>
|
||||
<D:lockscope>
|
||||
<D:exclusive/>
|
||||
</D:lockscope>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
</D:lockentry>
|
||||
<D:lockentry>
|
||||
<D:lockscope>
|
||||
<D:shared/>
|
||||
</D:lockscope>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
</D:lockentry>
|
||||
</D:supportedlock>
|
||||
<D:lockdiscovery/>
|
||||
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 200 OK</D:status>
|
||||
</D:propstat>
|
||||
</D:response>
|
||||
</D:multistatus>`)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('mkcalendar test', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => {
|
||||
fastify.close()
|
||||
})
|
||||
|
||||
await t.test('request - mkcalendar', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/`, {
|
||||
method: 'MKCALENDAR'
|
||||
})
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request with other path - mkcalendar', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/test`, {
|
||||
method: 'MKCALENDAR'
|
||||
})
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
// the body test uses a text/plain content type instead of application/xml because it requires
|
||||
// a specific content type parser
|
||||
await t.test('request with body - mkcalendar', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test`, {
|
||||
method: 'MKCALENDAR',
|
||||
headers: { 'content-type': 'text/plain' },
|
||||
body: bodySample
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request with body and no content type (415 error) - mkcalendar', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test`, {
|
||||
method: 'MKCALENDAR',
|
||||
body: bodySample,
|
||||
headers: { 'content-type': undefined }
|
||||
})
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request without body - mkcalendar', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test`, {
|
||||
method: 'MKCALENDAR'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
})
|
||||
35
node_modules/fastify/test/http-methods/mkcol.test.js
generated
vendored
35
node_modules/fastify/test/http-methods/mkcol.test.js
generated
vendored
@@ -1,35 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../')()
|
||||
fastify.addHttpMethod('MKCOL')
|
||||
|
||||
test('can be created - mkcol', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'MKCOL',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
reply.code(201).send()
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('mkcol test', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await t.test('request - mkcol', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/test/`, {
|
||||
method: 'MKCOL'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 201)
|
||||
})
|
||||
})
|
||||
42
node_modules/fastify/test/http-methods/move.test.js
generated
vendored
42
node_modules/fastify/test/http-methods/move.test.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../')()
|
||||
fastify.addHttpMethod('MOVE')
|
||||
|
||||
test('shorthand - move', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'MOVE',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
const destination = req.headers.destination
|
||||
reply.code(201)
|
||||
.header('location', destination)
|
||||
.send()
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
test('move test', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await t.test('request - move', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test.txt`, {
|
||||
method: 'MOVE',
|
||||
headers: {
|
||||
Destination: '/test2.txt'
|
||||
}
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 201)
|
||||
t.assert.strictEqual(result.headers.get('location'), '/test2.txt')
|
||||
})
|
||||
})
|
||||
136
node_modules/fastify/test/http-methods/propfind.test.js
generated
vendored
136
node_modules/fastify/test/http-methods/propfind.test.js
generated
vendored
@@ -1,136 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../')()
|
||||
fastify.addHttpMethod('PROPFIND', { hasBody: true })
|
||||
|
||||
const bodySample = `<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:propfind xmlns:D="DAV:">
|
||||
<D:prop xmlns:R="http://ns.example.com/boxschema/">
|
||||
<R:bigbox/> <R:author/> <R:DingALing/> <R:Random/>
|
||||
</D:prop>
|
||||
</D:propfind>
|
||||
`
|
||||
|
||||
test('can be created - propfind', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'PROPFIND',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
return reply.code(207)
|
||||
.send(`<?xml version="1.0" encoding="utf-8"?>
|
||||
<D:multistatus xmlns:D="DAV:">
|
||||
<D:response xmlns:lp1="DAV:">
|
||||
<D:href>/</D:href>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<lp1:resourcetype>
|
||||
<D:collection/>
|
||||
</lp1:resourcetype>
|
||||
<lp1:creationdate>2022-04-13T12:35:30Z</lp1:creationdate>
|
||||
<lp1:getlastmodified>Wed, 13 Apr 2022 12:35:30 GMT</lp1:getlastmodified>
|
||||
<lp1:getetag>"e0-5dc8869b53ef1"</lp1:getetag>
|
||||
<D:supportedlock>
|
||||
<D:lockentry>
|
||||
<D:lockscope>
|
||||
<D:exclusive/>
|
||||
</D:lockscope>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
</D:lockentry>
|
||||
<D:lockentry>
|
||||
<D:lockscope>
|
||||
<D:shared/>
|
||||
</D:lockscope>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
</D:lockentry>
|
||||
</D:supportedlock>
|
||||
<D:lockdiscovery/>
|
||||
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 200 OK</D:status>
|
||||
</D:propstat>
|
||||
</D:response>
|
||||
</D:multistatus>`
|
||||
)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('propfind test', async t => {
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => {
|
||||
fastify.close()
|
||||
})
|
||||
|
||||
await t.test('request - propfind', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/`, {
|
||||
method: 'PROPFIND'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request with other path - propfind', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'PROPFIND'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
// the body test uses a text/plain content type instead of application/xml because it requires
|
||||
// a specific content type parser
|
||||
await t.test('request with body - propfind', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'PROPFIND',
|
||||
headers: { 'content-type': 'text/plain' },
|
||||
body: bodySample
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request with body and no content type (415 error) - propfind', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'PROPFIND',
|
||||
body: bodySample,
|
||||
headers: { 'content-type': '' }
|
||||
})
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request without body - propfind', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'PROPFIND'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
})
|
||||
105
node_modules/fastify/test/http-methods/proppatch.test.js
generated
vendored
105
node_modules/fastify/test/http-methods/proppatch.test.js
generated
vendored
@@ -1,105 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../')()
|
||||
fastify.addHttpMethod('PROPPATCH', { hasBody: true })
|
||||
|
||||
const bodySample = `<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:propertyupdate xmlns:D="DAV:"
|
||||
xmlns:Z="http://ns.example.com/standards/z39.50/">
|
||||
<D:set>
|
||||
<D:prop>
|
||||
<Z:Authors>
|
||||
<Z:Author>Jim Whitehead</Z:Author>
|
||||
<Z:Author>Roy Fielding</Z:Author>
|
||||
</Z:Authors>
|
||||
</D:prop>
|
||||
</D:set>
|
||||
<D:remove>
|
||||
<D:prop>
|
||||
<Z:Copyright-Owner/>
|
||||
</D:prop>
|
||||
</D:remove>
|
||||
</D:propertyupdate>`
|
||||
|
||||
test('shorthand - proppatch', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'PROPPATCH',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
reply
|
||||
.code(207)
|
||||
.send(`<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:multistatus xmlns:D="DAV:"
|
||||
xmlns:Z="http://ns.example.com/standards/z39.50/">
|
||||
<D:response>
|
||||
<D:href>http://www.example.com/bar.html</D:href>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<Z:Authors/>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 424 Failed Dependency</D:status>
|
||||
</D:propstat>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<Z:Copyright-Owner/>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 409 Conflict</D:status>
|
||||
</D:propstat>
|
||||
<D:responsedescription> Copyright Owner cannot be deleted or altered.</D:responsedescription>
|
||||
</D:response>
|
||||
</D:multistatus>`
|
||||
)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('proppatch test', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
// the body test uses a text/plain content type instead of application/xml because it requires
|
||||
// a specific content type parser
|
||||
await t.test('request with body - proppatch', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'PROPPATCH',
|
||||
headers: { 'content-type': 'text/plain' },
|
||||
body: bodySample
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request with body and no content type (415 error) - proppatch', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'PROPPATCH',
|
||||
body: bodySample,
|
||||
headers: { 'content-type': undefined }
|
||||
})
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
|
||||
await t.test('request without body - proppatch', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'PROPPATCH'
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
})
|
||||
})
|
||||
142
node_modules/fastify/test/http-methods/report.test.js
generated
vendored
142
node_modules/fastify/test/http-methods/report.test.js
generated
vendored
@@ -1,142 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('REPORT', { hasBody: true })
|
||||
|
||||
const bodySample = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<B:calendar-query xmlns:B="urn:ietf:params:xml:ns:caldav">
|
||||
<A:prop xmlns:A="DAV:">
|
||||
<A:getetag/>
|
||||
<A:getcontenttype/>
|
||||
</A:prop>
|
||||
<B:filter>
|
||||
<B:comp-filter name="VCALENDAR">
|
||||
<B:comp-filter name="VEVENT">
|
||||
<B:time-range start="20170215T000000Z"/>
|
||||
</B:comp-filter>
|
||||
</B:comp-filter>
|
||||
</B:filter>
|
||||
</B:calendar-query>
|
||||
`
|
||||
|
||||
test('can be created - report', (t) => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'REPORT',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
return reply.code(207).send(`<?xml version="1.0" encoding="utf-8"?>
|
||||
<D:multistatus xmlns:D="DAV:">
|
||||
<D:response xmlns:lp1="DAV:">
|
||||
<D:href>/</D:href>
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<lp1:resourcetype>
|
||||
<D:collection/>
|
||||
</lp1:resourcetype>
|
||||
<lp1:creationdate>2022-04-13T12:35:30Z</lp1:creationdate>
|
||||
<lp1:getlastmodified>Wed, 13 Apr 2022 12:35:30 GMT</lp1:getlastmodified>
|
||||
<lp1:getetag>"e0-5dc8869b53ef1"</lp1:getetag>
|
||||
<D:supportedlock>
|
||||
<D:lockentry>
|
||||
<D:lockscope>
|
||||
<D:exclusive/>
|
||||
</D:lockscope>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
</D:lockentry>
|
||||
<D:lockentry>
|
||||
<D:lockscope>
|
||||
<D:shared/>
|
||||
</D:lockscope>
|
||||
<D:locktype>
|
||||
<D:write/>
|
||||
</D:locktype>
|
||||
</D:lockentry>
|
||||
</D:supportedlock>
|
||||
<D:lockdiscovery/>
|
||||
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 200 OK</D:status>
|
||||
</D:propstat>
|
||||
</D:response>
|
||||
</D:multistatus>`)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('report test', async t => {
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => {
|
||||
fastify.close()
|
||||
})
|
||||
|
||||
await t.test('request - report', async (t) => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/`, {
|
||||
method: 'REPORT'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + (await result.text()).length)
|
||||
})
|
||||
|
||||
await t.test('request with other path - report', async (t) => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'REPORT'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + (await result.text()).length)
|
||||
})
|
||||
|
||||
// the body test uses a text/plain content type instead of application/xml because it requires
|
||||
// a specific content type parser
|
||||
await t.test('request with body - report', async (t) => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'REPORT',
|
||||
headers: { 'content-type': 'text/plain' },
|
||||
body: bodySample
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + (await result.text()).length)
|
||||
})
|
||||
|
||||
await t.test('request with body and no content type (415 error) - report', async (t) => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'REPORT',
|
||||
body: bodySample,
|
||||
headers: { 'content-type': '' }
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 415)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + (await result.text()).length)
|
||||
})
|
||||
|
||||
await t.test('request without body - report', async (t) => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`http://localhost:${fastify.server.address().port}/test`, {
|
||||
method: 'REPORT'
|
||||
})
|
||||
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 207)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + (await result.text()).length)
|
||||
})
|
||||
})
|
||||
233
node_modules/fastify/test/http-methods/search.test.js
generated
vendored
233
node_modules/fastify/test/http-methods/search.test.js
generated
vendored
@@ -1,233 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('SEARCH', { hasBody: true })
|
||||
|
||||
const schema = {
|
||||
response: {
|
||||
'2xx': {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const querySchema = {
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const paramsSchema = {
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
type: 'string'
|
||||
},
|
||||
test: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bodySchema = {
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: {
|
||||
type: 'string'
|
||||
},
|
||||
test: {
|
||||
type: 'integer'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test('search', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'SEARCH',
|
||||
url: '/',
|
||||
schema,
|
||||
handler: function (request, reply) {
|
||||
reply.code(200).send({ hello: 'world' })
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('search, params schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'SEARCH',
|
||||
url: '/params/:foo/:test',
|
||||
schema: paramsSchema,
|
||||
handler: function (request, reply) {
|
||||
reply.code(200).send(request.params)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('search, querystring schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'SEARCH',
|
||||
url: '/query',
|
||||
schema: querySchema,
|
||||
handler: function (request, reply) {
|
||||
reply.code(200).send(request.query)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('search, body schema', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'SEARCH',
|
||||
url: '/body',
|
||||
schema: bodySchema,
|
||||
handler: function (request, reply) {
|
||||
reply.code(200).send(request.body)
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('search test', async t => {
|
||||
await fastify.listen({ port: 0 })
|
||||
t.after(() => { fastify.close() })
|
||||
const url = `http://localhost:${fastify.server.address().port}`
|
||||
|
||||
await t.test('request - search', async t => {
|
||||
t.plan(4)
|
||||
const result = await fetch(url, {
|
||||
method: 'SEARCH'
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
||||
})
|
||||
|
||||
await t.test('request search params schema', async t => {
|
||||
t.plan(4)
|
||||
const result = await fetch(`${url}/params/world/123`, {
|
||||
method: 'SEARCH'
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { foo: 'world', test: 123 })
|
||||
})
|
||||
|
||||
await t.test('request search params schema error', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${url}/params/world/string`, {
|
||||
method: 'SEARCH'
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.status, 400)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'params/test must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('request search querystring schema', async t => {
|
||||
t.plan(4)
|
||||
const result = await fetch(`${url}/query?hello=123`, {
|
||||
method: 'SEARCH'
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), { hello: 123 })
|
||||
})
|
||||
|
||||
await t.test('request search querystring schema error', async t => {
|
||||
t.plan(3)
|
||||
const result = await fetch(`${url}/query?hello=world`, {
|
||||
method: 'SEARCH'
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.strictEqual(result.status, 400)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'querystring/hello must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
|
||||
await t.test('request search body schema', async t => {
|
||||
t.plan(4)
|
||||
const replyBody = { foo: 'bar', test: 5 }
|
||||
const result = await fetch(`${url}/body`, {
|
||||
method: 'SEARCH',
|
||||
body: JSON.stringify(replyBody),
|
||||
headers: { 'content-type': 'application/json' }
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), replyBody)
|
||||
})
|
||||
|
||||
await t.test('request search body schema error', async t => {
|
||||
t.plan(4)
|
||||
const result = await fetch(`${url}/body`, {
|
||||
method: 'SEARCH',
|
||||
body: JSON.stringify({ foo: 'bar', test: 'test' }),
|
||||
headers: { 'content-type': 'application/json' }
|
||||
})
|
||||
const body = await result.text()
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 400)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), {
|
||||
error: 'Bad Request',
|
||||
code: 'FST_ERR_VALIDATION',
|
||||
message: 'body/test must be integer',
|
||||
statusCode: 400
|
||||
})
|
||||
})
|
||||
})
|
||||
21
node_modules/fastify/test/http-methods/trace.test.js
generated
vendored
21
node_modules/fastify/test/http-methods/trace.test.js
generated
vendored
@@ -1,21 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('TRACE')
|
||||
|
||||
test('shorthand - trace', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'TRACE',
|
||||
url: '/',
|
||||
handler: function (request, reply) {
|
||||
reply.code(200).send('TRACE OK')
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
38
node_modules/fastify/test/http-methods/unlock.test.js
generated
vendored
38
node_modules/fastify/test/http-methods/unlock.test.js
generated
vendored
@@ -1,38 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const fastify = require('../../fastify')()
|
||||
fastify.addHttpMethod('UNLOCK')
|
||||
|
||||
test('can be created - unlock', t => {
|
||||
t.plan(1)
|
||||
try {
|
||||
fastify.route({
|
||||
method: 'UNLOCK',
|
||||
url: '*',
|
||||
handler: function (req, reply) {
|
||||
reply.code(204).send()
|
||||
}
|
||||
})
|
||||
t.assert.ok(true)
|
||||
} catch (e) {
|
||||
t.assert.fail()
|
||||
}
|
||||
})
|
||||
|
||||
test('unlock test', async t => {
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
await t.test('request - unlock', async t => {
|
||||
t.plan(2)
|
||||
const result = await fetch(`${fastifyServer}/test/a.txt`, {
|
||||
method: 'UNLOCK',
|
||||
headers: {
|
||||
'Lock-Token': 'urn:uuid:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7'
|
||||
}
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 204)
|
||||
})
|
||||
})
|
||||
182
node_modules/fastify/test/http2/closing.test.js
generated
vendored
182
node_modules/fastify/test/http2/closing.test.js
generated
vendored
@@ -1,182 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const http2 = require('node:http2')
|
||||
const { promisify } = require('node:util')
|
||||
const connect = promisify(http2.connect)
|
||||
const { once } = require('node:events')
|
||||
const { buildCertificate } = require('../build-certificate')
|
||||
const { getServerUrl } = require('../helper')
|
||||
|
||||
test.before(buildCertificate)
|
||||
|
||||
const isNode24OrGreater = Number(process.versions.node.split('.')[0]) >= 24
|
||||
|
||||
test('http/2 request while fastify closing Node <24', { skip: isNode24OrGreater }, (t, done) => {
|
||||
const fastify = Fastify({
|
||||
http2: true
|
||||
})
|
||||
t.assert.ok('http2 successfully loaded')
|
||||
|
||||
fastify.get('/', () => Promise.resolve({}))
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const url = getServerUrl(fastify)
|
||||
const session = http2.connect(url, function () {
|
||||
this.request({
|
||||
':method': 'GET',
|
||||
':path': '/'
|
||||
}).on('response', headers => {
|
||||
t.assert.strictEqual(headers[':status'], 503)
|
||||
done()
|
||||
this.destroy()
|
||||
}).on('error', () => {
|
||||
// Nothing to do here,
|
||||
// we are not interested in this error that might
|
||||
// happen or not
|
||||
})
|
||||
session.on('error', () => {
|
||||
// Nothing to do here,
|
||||
// we are not interested in this error that might
|
||||
// happen or not
|
||||
done()
|
||||
})
|
||||
fastify.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('http/2 request while fastify closing Node >=24', { skip: !isNode24OrGreater }, (t, done) => {
|
||||
const fastify = Fastify({
|
||||
http2: true
|
||||
})
|
||||
t.assert.ok('http2 successfully loaded')
|
||||
|
||||
fastify.get('/', () => Promise.resolve({}))
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
|
||||
const url = getServerUrl(fastify)
|
||||
const session = http2.connect(url, function () {
|
||||
session.on('error', () => {
|
||||
// Nothing to do here,
|
||||
// we are not interested in this error that might
|
||||
// happen or not
|
||||
})
|
||||
session.on('close', () => {
|
||||
done()
|
||||
})
|
||||
fastify.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('http/2 request while fastify closing - return503OnClosing: false', { skip: isNode24OrGreater }, (t, done) => {
|
||||
const fastify = Fastify({
|
||||
http2: true,
|
||||
return503OnClosing: false
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
fastify.get('/', () => Promise.resolve({}))
|
||||
|
||||
fastify.listen({ port: 0 }, err => {
|
||||
t.assert.ifError(err)
|
||||
const url = getServerUrl(fastify)
|
||||
const session = http2.connect(url, function () {
|
||||
this.request({
|
||||
':method': 'GET',
|
||||
':path': '/'
|
||||
}).on('response', headers => {
|
||||
t.assert.strictEqual(headers[':status'], 200)
|
||||
done()
|
||||
this.destroy()
|
||||
}).on('error', () => {
|
||||
// Nothing to do here,
|
||||
// we are not interested in this error that might
|
||||
// happen or not
|
||||
})
|
||||
fastify.close()
|
||||
})
|
||||
session.on('error', () => {
|
||||
// Nothing to do here,
|
||||
// we are not interested in this error that might
|
||||
// happen or not
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('http/2 closes successfully with async await', async t => {
|
||||
const fastify = Fastify({
|
||||
http2SessionTimeout: 100,
|
||||
http2: true
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const url = getServerUrl(fastify)
|
||||
const session = await connect(url)
|
||||
// An error might or might not happen, as it's OS dependent.
|
||||
session.on('error', () => {})
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('https/2 closes successfully with async await', async t => {
|
||||
const fastify = Fastify({
|
||||
http2SessionTimeout: 100,
|
||||
http2: true,
|
||||
https: {
|
||||
key: global.context.key,
|
||||
cert: global.context.cert
|
||||
}
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const url = getServerUrl(fastify)
|
||||
const session = await connect(url)
|
||||
// An error might or might not happen, as it's OS dependent.
|
||||
session.on('error', () => {})
|
||||
await fastify.close()
|
||||
})
|
||||
|
||||
test('http/2 server side session emits a timeout event', async t => {
|
||||
let _resolve
|
||||
const p = new Promise((resolve) => { _resolve = resolve })
|
||||
|
||||
const fastify = Fastify({
|
||||
http2SessionTimeout: 100,
|
||||
http2: true
|
||||
})
|
||||
|
||||
fastify.get('/', async (req) => {
|
||||
req.raw.stream.session.on('timeout', () => _resolve())
|
||||
return {}
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const url = getServerUrl(fastify)
|
||||
const session = await connect(url)
|
||||
const req = session.request({
|
||||
':method': 'GET',
|
||||
':path': '/'
|
||||
}).end()
|
||||
|
||||
const [headers] = await once(req, 'response')
|
||||
t.assert.strictEqual(headers[':status'], 200)
|
||||
req.resume()
|
||||
|
||||
// An error might or might not happen, as it's OS dependent.
|
||||
session.on('error', () => {})
|
||||
await p
|
||||
await fastify.close()
|
||||
})
|
||||
109
node_modules/fastify/test/http2/constraint.test.js
generated
vendored
109
node_modules/fastify/test/http2/constraint.test.js
generated
vendored
@@ -1,109 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const h2url = require('h2url')
|
||||
|
||||
const alpha = { res: 'alpha' }
|
||||
const beta = { res: 'beta' }
|
||||
|
||||
const { buildCertificate } = require('../build-certificate')
|
||||
test.before(buildCertificate)
|
||||
|
||||
test('A route supports host constraints under http2 protocol and secure connection', async (t) => {
|
||||
t.plan(5)
|
||||
|
||||
let fastify
|
||||
try {
|
||||
fastify = Fastify({
|
||||
http2: true,
|
||||
https: {
|
||||
key: global.context.key,
|
||||
cert: global.context.cert
|
||||
}
|
||||
})
|
||||
t.assert.ok(true, 'Key/cert successfully loaded')
|
||||
} catch (e) {
|
||||
t.assert.fail('Key/cert loading failed')
|
||||
}
|
||||
|
||||
const constrain = 'fastify.dev'
|
||||
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
handler: function (_, reply) {
|
||||
reply.code(200).send(alpha)
|
||||
}
|
||||
})
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/beta',
|
||||
constraints: { host: constrain },
|
||||
handler: function (_, reply) {
|
||||
reply.code(200).send(beta)
|
||||
}
|
||||
})
|
||||
fastify.route({
|
||||
method: 'GET',
|
||||
url: '/hostname_port',
|
||||
constraints: { host: constrain },
|
||||
handler: function (req, reply) {
|
||||
reply.code(200).send({ ...beta, hostname: req.hostname })
|
||||
}
|
||||
})
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('https get request - no constrain', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}`
|
||||
const res = await h2url.concat({ url })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(alpha).length)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), alpha)
|
||||
})
|
||||
|
||||
await t.test('https get request - constrain', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}/beta`
|
||||
const res = await h2url.concat({
|
||||
url,
|
||||
headers: {
|
||||
':authority': constrain
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(beta).length)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), beta)
|
||||
})
|
||||
|
||||
await t.test('https get request - constrain - not found', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}/beta`
|
||||
const res = await h2url.concat({
|
||||
url
|
||||
})
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 404)
|
||||
})
|
||||
await t.test('https get request - constrain - verify hostname and port from request', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}/hostname_port`
|
||||
const res = await h2url.concat({
|
||||
url,
|
||||
headers: {
|
||||
':authority': constrain
|
||||
}
|
||||
})
|
||||
const body = JSON.parse(res.body)
|
||||
t.assert.strictEqual(body.hostname, constrain)
|
||||
})
|
||||
})
|
||||
34
node_modules/fastify/test/http2/head.test.js
generated
vendored
34
node_modules/fastify/test/http2/head.test.js
generated
vendored
@@ -1,34 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const h2url = require('h2url')
|
||||
const msg = { hello: 'world' }
|
||||
|
||||
test('http2 HEAD test', async (t) => {
|
||||
let fastify
|
||||
try {
|
||||
fastify = Fastify({
|
||||
http2: true
|
||||
})
|
||||
t.assert.ok(true, 'http2 successfully loaded')
|
||||
} catch (e) {
|
||||
t.assert.fail('http2 loading failed')
|
||||
}
|
||||
|
||||
fastify.all('/', function (req, reply) {
|
||||
reply.code(200).send(msg)
|
||||
})
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('http HEAD request', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const url = `http://localhost:${fastify.server.address().port}`
|
||||
const res = await h2url.concat({ url, method: 'HEAD' })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
})
|
||||
})
|
||||
68
node_modules/fastify/test/http2/plain.test.js
generated
vendored
68
node_modules/fastify/test/http2/plain.test.js
generated
vendored
@@ -1,68 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const h2url = require('h2url')
|
||||
const msg = { hello: 'world' }
|
||||
|
||||
test('http2 plain test', async t => {
|
||||
let fastify
|
||||
try {
|
||||
fastify = Fastify({
|
||||
http2: true
|
||||
})
|
||||
t.assert.ok(true, 'http2 successfully loaded')
|
||||
} catch (e) {
|
||||
t.assert.fail('http2 loading failed')
|
||||
}
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.code(200).send(msg)
|
||||
})
|
||||
|
||||
fastify.get('/host', function (req, reply) {
|
||||
reply.code(200).send(req.host)
|
||||
})
|
||||
|
||||
fastify.get('/hostname_port', function (req, reply) {
|
||||
reply.code(200).send({ hostname: req.hostname, port: req.port })
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('http get request', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const url = `http://localhost:${fastify.server.address().port}`
|
||||
const res = await h2url.concat({ url })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(msg).length)
|
||||
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), msg)
|
||||
})
|
||||
|
||||
await t.test('http host', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const host = `localhost:${fastify.server.address().port}`
|
||||
|
||||
const url = `http://${host}/host`
|
||||
const res = await h2url.concat({ url })
|
||||
|
||||
t.assert.strictEqual(res.body, host)
|
||||
})
|
||||
await t.test('http hostname and port', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const host = `localhost:${fastify.server.address().port}`
|
||||
|
||||
const url = `http://${host}/hostname_port`
|
||||
const res = await h2url.concat({ url })
|
||||
|
||||
t.assert.strictEqual(JSON.parse(res.body).hostname, host.split(':')[0])
|
||||
t.assert.strictEqual(JSON.parse(res.body).port, parseInt(host.split(':')[1]))
|
||||
})
|
||||
})
|
||||
113
node_modules/fastify/test/http2/secure-with-fallback.test.js
generated
vendored
113
node_modules/fastify/test/http2/secure-with-fallback.test.js
generated
vendored
@@ -1,113 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const h2url = require('h2url')
|
||||
const msg = { hello: 'world' }
|
||||
|
||||
const { buildCertificate } = require('../build-certificate')
|
||||
const { Agent } = require('undici')
|
||||
test.before(buildCertificate)
|
||||
|
||||
test('secure with fallback', async (t) => {
|
||||
t.plan(6)
|
||||
|
||||
let fastify
|
||||
try {
|
||||
fastify = Fastify({
|
||||
http2: true,
|
||||
https: {
|
||||
allowHTTP1: true,
|
||||
key: global.context.key,
|
||||
cert: global.context.cert
|
||||
}
|
||||
})
|
||||
t.assert.ok(true, 'Key/cert successfully loaded')
|
||||
} catch (e) {
|
||||
t.assert.fail('Key/cert loading failed')
|
||||
}
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.code(200).send(msg)
|
||||
})
|
||||
|
||||
fastify.post('/', function (req, reply) {
|
||||
reply.code(200).send(req.body)
|
||||
})
|
||||
|
||||
fastify.get('/error', async function (req, reply) {
|
||||
throw new Error('kaboom')
|
||||
})
|
||||
|
||||
t.after(() => fastify.close())
|
||||
|
||||
const fastifyServer = await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('https get error', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const url = `${fastifyServer}/error`
|
||||
const res = await h2url.concat({ url })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 500)
|
||||
})
|
||||
|
||||
await t.test('https post', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const res = await h2url.concat({
|
||||
url: fastifyServer,
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ hello: 'http2' }),
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), { hello: 'http2' })
|
||||
})
|
||||
|
||||
await t.test('https get request', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const res = await h2url.concat({ url: fastifyServer })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(msg).length)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), msg)
|
||||
})
|
||||
|
||||
await t.test('http1 get request', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const result = await fetch(fastifyServer, {
|
||||
dispatcher: new Agent({
|
||||
connect: {
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const body = await result.text()
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
||||
t.assert.deepStrictEqual(JSON.parse(body), msg)
|
||||
})
|
||||
|
||||
await t.test('http1 get error', async t => {
|
||||
t.plan(2)
|
||||
|
||||
const result = await fetch(`${fastifyServer}/error`, {
|
||||
dispatcher: new Agent({
|
||||
connect: {
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.assert.ok(!result.ok)
|
||||
t.assert.strictEqual(result.status, 500)
|
||||
})
|
||||
})
|
||||
67
node_modules/fastify/test/http2/secure.test.js
generated
vendored
67
node_modules/fastify/test/http2/secure.test.js
generated
vendored
@@ -1,67 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const h2url = require('h2url')
|
||||
const msg = { hello: 'world' }
|
||||
|
||||
const { buildCertificate } = require('../build-certificate')
|
||||
test.before(buildCertificate)
|
||||
|
||||
test('secure', async (t) => {
|
||||
t.plan(4)
|
||||
|
||||
let fastify
|
||||
try {
|
||||
fastify = Fastify({
|
||||
http2: true,
|
||||
https: {
|
||||
key: global.context.key,
|
||||
cert: global.context.cert
|
||||
}
|
||||
})
|
||||
t.assert.ok(true, 'Key/cert successfully loaded')
|
||||
} catch (e) {
|
||||
t.assert.fail('Key/cert loading failed')
|
||||
}
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.code(200).send(msg)
|
||||
})
|
||||
fastify.get('/proto', function (req, reply) {
|
||||
reply.code(200).send({ proto: req.protocol })
|
||||
})
|
||||
fastify.get('/hostname_port', function (req, reply) {
|
||||
reply.code(200).send({ hostname: req.hostname, port: req.port })
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('https get request', async (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}`
|
||||
const res = await h2url.concat({ url })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 200)
|
||||
t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(msg).length)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), msg)
|
||||
})
|
||||
|
||||
await t.test('https get request without trust proxy - protocol', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}/proto`
|
||||
t.assert.deepStrictEqual(JSON.parse((await h2url.concat({ url })).body), { proto: 'https' })
|
||||
t.assert.deepStrictEqual(JSON.parse((await h2url.concat({ url, headers: { 'X-Forwarded-Proto': 'lorem' } })).body), { proto: 'https' })
|
||||
})
|
||||
await t.test('https get request - test hostname and port', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const url = `https://localhost:${fastify.server.address().port}/hostname_port`
|
||||
const parsedbody = JSON.parse((await h2url.concat({ url })).body)
|
||||
t.assert.strictEqual(parsedbody.hostname, 'localhost')
|
||||
t.assert.strictEqual(parsedbody.port, fastify.server.address().port)
|
||||
})
|
||||
})
|
||||
34
node_modules/fastify/test/http2/unknown-http-method.test.js
generated
vendored
34
node_modules/fastify/test/http2/unknown-http-method.test.js
generated
vendored
@@ -1,34 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const h2url = require('h2url')
|
||||
const msg = { hello: 'world' }
|
||||
|
||||
test('http2 unknown http method', async t => {
|
||||
const fastify = Fastify({
|
||||
http2: true
|
||||
})
|
||||
|
||||
fastify.get('/', function (req, reply) {
|
||||
reply.code(200).send(msg)
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
await t.test('http UNKNOWN_METHOD request', async (t) => {
|
||||
t.plan(2)
|
||||
|
||||
const url = `http://localhost:${fastify.server.address().port}`
|
||||
const res = await h2url.concat({ url, method: 'UNKNOWN_METHOD' })
|
||||
|
||||
t.assert.strictEqual(res.headers[':status'], 404)
|
||||
t.assert.deepStrictEqual(JSON.parse(res.body), {
|
||||
statusCode: 404,
|
||||
code: 'FST_ERR_NOT_FOUND',
|
||||
error: 'Not Found',
|
||||
message: 'Not Found'
|
||||
})
|
||||
})
|
||||
})
|
||||
58
node_modules/fastify/test/https/custom-https-server.test.js
generated
vendored
58
node_modules/fastify/test/https/custom-https-server.test.js
generated
vendored
@@ -1,58 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const Fastify = require('../..')
|
||||
const https = require('node:https')
|
||||
const dns = require('node:dns').promises
|
||||
const { buildCertificate } = require('../build-certificate')
|
||||
const { Agent } = require('undici')
|
||||
|
||||
async function setup () {
|
||||
await buildCertificate()
|
||||
|
||||
const localAddresses = await dns.lookup('localhost', { all: true })
|
||||
|
||||
test('Should support a custom https server', { skip: localAddresses.length < 1 }, async t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify({
|
||||
serverFactory: (handler, opts) => {
|
||||
t.assert.ok(opts.serverFactory, 'it is called once for localhost')
|
||||
|
||||
const options = {
|
||||
key: global.context.key,
|
||||
cert: global.context.cert
|
||||
}
|
||||
|
||||
const server = https.createServer(options, (req, res) => {
|
||||
req.custom = true
|
||||
handler(req, res)
|
||||
})
|
||||
|
||||
return server
|
||||
}
|
||||
})
|
||||
|
||||
t.after(() => { fastify.close() })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
t.assert.ok(req.raw.custom)
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 0 })
|
||||
|
||||
const result = await fetch('https://localhost:' + fastify.server.address().port, {
|
||||
dispatcher: new Agent({
|
||||
connect: {
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
})
|
||||
})
|
||||
t.assert.ok(result.ok)
|
||||
t.assert.strictEqual(result.status, 200)
|
||||
t.assert.deepStrictEqual(await result.json(), { hello: 'world' })
|
||||
})
|
||||
}
|
||||
|
||||
setup()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user