fastify 5.11.2 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/SPONSORS.md +1 -0
- package/docs/Guides/Serverless.md +34 -2
- package/docs/Reference/Encapsulation.md +31 -2
- package/docs/Reference/Errors.md +76 -3
- package/docs/Reference/Reply.md +14 -0
- package/docs/Reference/Request.md +18 -6
- package/docs/Reference/Routes.md +13 -0
- package/fastify.js +1 -1
- package/lib/content-type-parser.js +4 -0
- package/lib/content-type.js +4 -1
- package/lib/decorate.js +1 -1
- package/lib/log-controller.js +1 -1
- package/lib/reply.js +18 -4
- package/package.json +2 -3
- package/test/content-parser.test.js +48 -18
- package/test/content-type.test.js +4 -0
- package/test/decorator-instance-properties.test.js +49 -0
- package/test/helper.js +73 -1
- package/test/hooks-async.test.js +1 -2
- package/test/hooks.test.js +1 -2
- package/test/internals/reply.test.js +76 -1
- package/test/listen.1.test.js +17 -52
- package/test/listen.5.test.js +6 -9
- package/test/logger/instantiation.test.js +1 -1
- package/test/logger/logging.test.js +1 -1
- package/test/logger/request.test.js +1 -1
- package/test/logger/response.test.js +1 -1
- package/test/plugin.4.test.js +5 -4
- package/test/reply-media-type.test.js +131 -0
- package/test/reply-trailers.test.js +92 -4
- package/test/route-prefix.test.js +1 -1
- package/test/route.6.test.js +4 -11
- package/test/schema-feature.test.js +36 -65
- package/test/schema-serialization.test.js +1 -1
- package/test/schema-special-usage.test.js +1 -1
- package/test/schema-validation.test.js +1 -1
- package/test/stream.2.test.js +1 -1
- package/types/logger.d.ts +1 -1
- package/.pi/bash-confirm-whitelist.json +0 -180
- package/test/toolkit.js +0 -63
package/test/helper.js
CHANGED
|
@@ -4,11 +4,42 @@ const dns = require('node:dns').promises
|
|
|
4
4
|
const stream = require('node:stream')
|
|
5
5
|
const { promisify } = require('node:util')
|
|
6
6
|
const symbols = require('../lib/symbols')
|
|
7
|
-
const { waitForCb } = require('./toolkit')
|
|
8
7
|
const assert = require('node:assert')
|
|
9
8
|
|
|
10
9
|
module.exports.sleep = promisify(setTimeout)
|
|
11
10
|
|
|
11
|
+
function waitForCb (options) {
|
|
12
|
+
let count = null
|
|
13
|
+
let done = false
|
|
14
|
+
let iResolve
|
|
15
|
+
let iReject
|
|
16
|
+
|
|
17
|
+
function stepIn () {
|
|
18
|
+
if (done) {
|
|
19
|
+
iReject(new Error('Unexpected done call'))
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (--count) {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
done = true
|
|
28
|
+
iResolve()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const patience = new Promise((resolve, reject) => {
|
|
32
|
+
iResolve = resolve
|
|
33
|
+
iReject = reject
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
count = options.steps || 1
|
|
37
|
+
done = false
|
|
38
|
+
|
|
39
|
+
return { stepIn, patience }
|
|
40
|
+
}
|
|
41
|
+
module.exports.waitForCb = waitForCb
|
|
42
|
+
|
|
12
43
|
/**
|
|
13
44
|
* @param method HTTP request method
|
|
14
45
|
* @param t node:test instance
|
|
@@ -494,3 +525,44 @@ module.exports.getServerUrl = function (app) {
|
|
|
494
525
|
? `http://[${address}]:${port}`
|
|
495
526
|
: `http://${address}:${port}`
|
|
496
527
|
}
|
|
528
|
+
|
|
529
|
+
module.exports.partialDeepStrictEqual = function partialDeepStrictEqual (actual, expected) {
|
|
530
|
+
if (typeof expected !== 'object' || expected === null) {
|
|
531
|
+
return actual === expected
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (typeof actual !== 'object' || actual === null) {
|
|
535
|
+
return false
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (Array.isArray(expected)) {
|
|
539
|
+
if (!Array.isArray(actual)) return false
|
|
540
|
+
if (expected.length > actual.length) return false
|
|
541
|
+
|
|
542
|
+
for (let i = 0; i < expected.length; i++) {
|
|
543
|
+
if (!partialDeepStrictEqual(actual[i], expected[i])) {
|
|
544
|
+
return false
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return true
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
for (const key of Object.keys(expected)) {
|
|
551
|
+
if (!(key in actual)) return false
|
|
552
|
+
if (!partialDeepStrictEqual(actual[key], expected[key])) {
|
|
553
|
+
return false
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return true
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
module.exports.assertNoWarning = function (t) {
|
|
561
|
+
function doNotWarn () {
|
|
562
|
+
t.assert.fail('no warning')
|
|
563
|
+
}
|
|
564
|
+
process.on('warning', doNotWarn)
|
|
565
|
+
t.after(() => {
|
|
566
|
+
process.off('warning', doNotWarn)
|
|
567
|
+
})
|
|
568
|
+
}
|
package/test/hooks-async.test.js
CHANGED
|
@@ -4,8 +4,7 @@ const { Readable } = require('node:stream')
|
|
|
4
4
|
const { test, describe } = require('node:test')
|
|
5
5
|
const Fastify = require('../fastify')
|
|
6
6
|
const fs = require('node:fs')
|
|
7
|
-
const { sleep } = require('./helper')
|
|
8
|
-
const { waitForCb } = require('./toolkit')
|
|
7
|
+
const { sleep, waitForCb } = require('./helper')
|
|
9
8
|
|
|
10
9
|
process.removeAllListeners('warning')
|
|
11
10
|
|
package/test/hooks.test.js
CHANGED
|
@@ -10,8 +10,7 @@ const symbols = require('../lib/symbols.js')
|
|
|
10
10
|
const payload = { hello: 'world' }
|
|
11
11
|
const proxyquire = require('proxyquire')
|
|
12
12
|
const { connect } = require('node:net')
|
|
13
|
-
const { sleep } = require('./helper')
|
|
14
|
-
const { waitForCb } = require('./toolkit.js')
|
|
13
|
+
const { sleep, waitForCb } = require('./helper')
|
|
15
14
|
const { fetch } = require('undici')
|
|
16
15
|
|
|
17
16
|
process.removeAllListeners('warning')
|
|
@@ -34,7 +34,7 @@ const doGet = async function (url) {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
test('Once called, Reply should return an object with methods', t => {
|
|
37
|
-
t.plan(
|
|
37
|
+
t.plan(16)
|
|
38
38
|
const response = { res: 'res' }
|
|
39
39
|
const context = {
|
|
40
40
|
config: { onSend: [] },
|
|
@@ -49,6 +49,7 @@ test('Once called, Reply should return an object with methods', t => {
|
|
|
49
49
|
t.assert.strictEqual(typeof reply[kReplyErrorHandlerCalled], 'boolean')
|
|
50
50
|
t.assert.strictEqual(typeof reply.send, 'function')
|
|
51
51
|
t.assert.strictEqual(typeof reply.code, 'function')
|
|
52
|
+
t.assert.strictEqual(typeof reply.mediaType, 'string')
|
|
52
53
|
t.assert.strictEqual(typeof reply.status, 'function')
|
|
53
54
|
t.assert.strictEqual(typeof reply.header, 'function')
|
|
54
55
|
t.assert.strictEqual(typeof reply.serialize, 'function')
|
|
@@ -1114,6 +1115,80 @@ test('reply.removeHeader can remove the value', async t => {
|
|
|
1114
1115
|
await fetch(`${fastifyServer}/headers`)
|
|
1115
1116
|
})
|
|
1116
1117
|
|
|
1118
|
+
test('reply.removeHeader removes raw headers', async t => {
|
|
1119
|
+
t.plan(9)
|
|
1120
|
+
|
|
1121
|
+
const fastify = require('../../')()
|
|
1122
|
+
|
|
1123
|
+
t.after(() => fastify.close())
|
|
1124
|
+
|
|
1125
|
+
fastify.get('/headers', function (req, reply) {
|
|
1126
|
+
reply.raw.setHeader('X-Foo', 'raw')
|
|
1127
|
+
t.assert.strictEqual(reply.getHeader('x-foo'), 'raw')
|
|
1128
|
+
t.assert.strictEqual(reply.getHeaders()['x-foo'], 'raw')
|
|
1129
|
+
t.assert.strictEqual(reply.hasHeader('x-foo'), true)
|
|
1130
|
+
|
|
1131
|
+
t.assert.strictEqual(reply.removeHeader('x-FoO'), reply)
|
|
1132
|
+
t.assert.strictEqual(reply.getHeader('x-foo'), undefined)
|
|
1133
|
+
t.assert.strictEqual(Object.hasOwn(reply.getHeaders(), 'x-foo'), false)
|
|
1134
|
+
t.assert.strictEqual(reply.hasHeader('x-foo'), false)
|
|
1135
|
+
t.assert.strictEqual(reply.removeHeader('X-FOO'), reply)
|
|
1136
|
+
|
|
1137
|
+
reply.send()
|
|
1138
|
+
})
|
|
1139
|
+
|
|
1140
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
1141
|
+
const response = await fetch(`${fastifyServer}/headers`)
|
|
1142
|
+
t.assert.strictEqual(response.headers.get('x-foo'), null)
|
|
1143
|
+
})
|
|
1144
|
+
|
|
1145
|
+
test('reply.removeHeader removes layered headers', async t => {
|
|
1146
|
+
t.plan(7)
|
|
1147
|
+
|
|
1148
|
+
const fastify = require('../../')()
|
|
1149
|
+
|
|
1150
|
+
t.after(() => fastify.close())
|
|
1151
|
+
|
|
1152
|
+
fastify.get('/headers', function (req, reply) {
|
|
1153
|
+
reply.raw.setHeader('x-foo', 'raw')
|
|
1154
|
+
reply.header('x-foo', 'fastify')
|
|
1155
|
+
t.assert.strictEqual(reply.getHeader('x-foo'), 'fastify')
|
|
1156
|
+
t.assert.strictEqual(reply.getHeaders()['x-foo'], 'fastify')
|
|
1157
|
+
|
|
1158
|
+
t.assert.strictEqual(reply.removeHeader('x-foo'), reply)
|
|
1159
|
+
t.assert.strictEqual(reply.getHeader('x-foo'), undefined)
|
|
1160
|
+
t.assert.strictEqual(Object.hasOwn(reply.getHeaders(), 'x-foo'), false)
|
|
1161
|
+
t.assert.strictEqual(reply.hasHeader('x-foo'), false)
|
|
1162
|
+
|
|
1163
|
+
reply.send()
|
|
1164
|
+
})
|
|
1165
|
+
|
|
1166
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
1167
|
+
const response = await fetch(`${fastifyServer}/headers`)
|
|
1168
|
+
t.assert.strictEqual(response.headers.get('x-foo'), null)
|
|
1169
|
+
})
|
|
1170
|
+
|
|
1171
|
+
test('reply.removeHeader does not throw after headers are sent', async t => {
|
|
1172
|
+
t.plan(3)
|
|
1173
|
+
|
|
1174
|
+
const fastify = require('../../')()
|
|
1175
|
+
|
|
1176
|
+
t.after(() => fastify.close())
|
|
1177
|
+
|
|
1178
|
+
fastify.get('/headers', function (req, reply) {
|
|
1179
|
+
reply.hijack()
|
|
1180
|
+
reply.raw.setHeader('x-foo', 'raw')
|
|
1181
|
+
reply.raw.flushHeaders()
|
|
1182
|
+
t.assert.strictEqual(reply.raw.headersSent, true)
|
|
1183
|
+
t.assert.doesNotThrow(() => reply.removeHeader('x-foo'))
|
|
1184
|
+
reply.raw.end()
|
|
1185
|
+
})
|
|
1186
|
+
|
|
1187
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
1188
|
+
const response = await fetch(`${fastifyServer}/headers`)
|
|
1189
|
+
t.assert.strictEqual(response.headers.get('x-foo'), 'raw')
|
|
1190
|
+
})
|
|
1191
|
+
|
|
1117
1192
|
test('reply.header can reset the value', async t => {
|
|
1118
1193
|
t.plan(1)
|
|
1119
1194
|
|
package/test/listen.1.test.js
CHANGED
|
@@ -4,6 +4,7 @@ const { networkInterfaces } = require('node:os')
|
|
|
4
4
|
const { test, before } = require('node:test')
|
|
5
5
|
const Fastify = require('..')
|
|
6
6
|
const helper = require('./helper')
|
|
7
|
+
const { assertNoWarning } = require('./helper')
|
|
7
8
|
|
|
8
9
|
let localhost
|
|
9
10
|
let localhostForURL
|
|
@@ -13,33 +14,22 @@ before(async function () {
|
|
|
13
14
|
})
|
|
14
15
|
|
|
15
16
|
test('listen works without arguments', async t => {
|
|
16
|
-
|
|
17
|
-
t.assert.fail('should not be deprecated')
|
|
18
|
-
}
|
|
19
|
-
process.on('warning', doNotWarn)
|
|
17
|
+
assertNoWarning(t)
|
|
20
18
|
|
|
21
19
|
const fastify = Fastify()
|
|
22
|
-
|
|
23
|
-
fastify.close()
|
|
24
|
-
process.removeListener('warning', doNotWarn)
|
|
25
|
-
})
|
|
20
|
+
|
|
26
21
|
await fastify.listen()
|
|
27
22
|
const address = fastify.server.address()
|
|
28
23
|
t.assert.strictEqual(address.address, localhost)
|
|
29
24
|
t.assert.ok(address.port > 0)
|
|
25
|
+
await fastify.close()
|
|
30
26
|
})
|
|
31
27
|
|
|
32
28
|
test('Async/await listen with arguments', async t => {
|
|
33
|
-
|
|
34
|
-
t.assert.fail('should not be deprecated')
|
|
35
|
-
}
|
|
36
|
-
process.on('warning', doNotWarn)
|
|
29
|
+
assertNoWarning(t)
|
|
37
30
|
|
|
38
31
|
const fastify = Fastify()
|
|
39
|
-
|
|
40
|
-
fastify.close()
|
|
41
|
-
process.removeListener('warning', doNotWarn)
|
|
42
|
-
})
|
|
32
|
+
|
|
43
33
|
const addr = await fastify.listen({ port: 0, host: '0.0.0.0' })
|
|
44
34
|
const address = fastify.server.address()
|
|
45
35
|
const { protocol, hostname, port, pathname } = new URL(addr)
|
|
@@ -55,39 +45,27 @@ test('Async/await listen with arguments', async t => {
|
|
|
55
45
|
family: 'IPv4',
|
|
56
46
|
port: address.port
|
|
57
47
|
})
|
|
48
|
+
await fastify.close()
|
|
58
49
|
})
|
|
59
50
|
|
|
60
51
|
test('listen accepts a callback', (t, done) => {
|
|
61
52
|
t.plan(2)
|
|
62
|
-
|
|
63
|
-
t.assert.fail('should not be deprecated')
|
|
64
|
-
}
|
|
65
|
-
process.on('warning', doNotWarn)
|
|
53
|
+
assertNoWarning(t)
|
|
66
54
|
|
|
67
55
|
const fastify = Fastify()
|
|
68
|
-
|
|
69
|
-
fastify.close()
|
|
70
|
-
process.removeListener('warning', doNotWarn)
|
|
71
|
-
})
|
|
56
|
+
|
|
72
57
|
fastify.listen({ port: 0 }, (err) => {
|
|
73
58
|
t.assert.ifError(err)
|
|
74
59
|
t.assert.strictEqual(fastify.server.address().address, localhost)
|
|
75
|
-
done
|
|
60
|
+
fastify.close(done)
|
|
76
61
|
})
|
|
77
62
|
})
|
|
78
63
|
|
|
79
64
|
test('listen accepts options and a callback', (t, done) => {
|
|
80
65
|
t.plan(1)
|
|
81
|
-
|
|
82
|
-
t.assert.fail('should not be deprecated')
|
|
83
|
-
}
|
|
84
|
-
process.on('warning', doNotWarn)
|
|
66
|
+
assertNoWarning(t)
|
|
85
67
|
|
|
86
68
|
const fastify = Fastify()
|
|
87
|
-
t.after(() => {
|
|
88
|
-
fastify.close()
|
|
89
|
-
process.removeListener('warning', doNotWarn)
|
|
90
|
-
})
|
|
91
69
|
fastify.listen({
|
|
92
70
|
port: 0,
|
|
93
71
|
host: 'localhost',
|
|
@@ -98,7 +76,7 @@ test('listen accepts options and a callback', (t, done) => {
|
|
|
98
76
|
ipv6Only: false
|
|
99
77
|
}, (err) => {
|
|
100
78
|
t.assert.ifError(err)
|
|
101
|
-
done
|
|
79
|
+
fastify.close(done)
|
|
102
80
|
})
|
|
103
81
|
})
|
|
104
82
|
|
|
@@ -118,37 +96,24 @@ test('listen after Promise.resolve()', (t, done) => {
|
|
|
118
96
|
})
|
|
119
97
|
|
|
120
98
|
test('listen works with undefined host', async t => {
|
|
121
|
-
|
|
122
|
-
t.assert.fail('should not be deprecated')
|
|
123
|
-
}
|
|
124
|
-
process.on('warning', doNotWarn)
|
|
99
|
+
assertNoWarning(t)
|
|
125
100
|
|
|
126
101
|
const fastify = Fastify()
|
|
127
|
-
t.after(() => fastify.close())
|
|
128
|
-
t.after(() => {
|
|
129
|
-
fastify.close()
|
|
130
|
-
process.removeListener('warning', doNotWarn)
|
|
131
|
-
})
|
|
132
102
|
await fastify.listen({ host: undefined, port: 0 })
|
|
133
103
|
const address = fastify.server.address()
|
|
134
104
|
t.assert.strictEqual(address.address, localhost)
|
|
135
105
|
t.assert.ok(address.port > 0)
|
|
106
|
+
await fastify.close()
|
|
136
107
|
})
|
|
137
108
|
|
|
138
109
|
test('listen works with null host', async t => {
|
|
139
|
-
|
|
140
|
-
t.fail('should not be deprecated')
|
|
141
|
-
}
|
|
142
|
-
process.on('warning', doNotWarn)
|
|
110
|
+
assertNoWarning(t)
|
|
143
111
|
|
|
144
112
|
const fastify = Fastify()
|
|
145
|
-
|
|
146
|
-
t.after(() => {
|
|
147
|
-
fastify.close()
|
|
148
|
-
process.removeListener('warning', doNotWarn)
|
|
149
|
-
})
|
|
113
|
+
|
|
150
114
|
await fastify.listen({ host: null, port: 0 })
|
|
151
115
|
const address = fastify.server.address()
|
|
152
116
|
t.assert.strictEqual(address.address, localhost)
|
|
153
117
|
t.assert.ok(address.port > 0)
|
|
118
|
+
await fastify.close()
|
|
154
119
|
})
|
package/test/listen.5.test.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const net = require('node:net')
|
|
5
|
-
const Fastify = require('../fastify')
|
|
6
5
|
const { once } = require('node:events')
|
|
6
|
+
const { spyWarning } = require('process-warning')
|
|
7
|
+
const Fastify = require('../fastify')
|
|
7
8
|
const { FSTWRN003 } = require('../lib/warnings.js')
|
|
8
9
|
|
|
9
10
|
function createDeferredPromise () {
|
|
@@ -102,21 +103,17 @@ test('same port conflict and success should not fire callback multiple times - p
|
|
|
102
103
|
test('should emit a warning when using async callback', (t, done) => {
|
|
103
104
|
t.plan(2)
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
function onWarning (warning) {
|
|
107
|
-
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
108
|
-
t.assert.strictEqual(warning.code, FSTWRN003.code)
|
|
109
|
-
}
|
|
110
|
-
|
|
106
|
+
const spyData = spyWarning(FSTWRN003)
|
|
111
107
|
const fastify = Fastify()
|
|
112
108
|
|
|
113
109
|
t.after(async () => {
|
|
114
110
|
await fastify.close()
|
|
115
|
-
|
|
116
|
-
FSTWRN003.emitted = false
|
|
111
|
+
spyData.restore()
|
|
117
112
|
})
|
|
118
113
|
|
|
119
114
|
fastify.listen({ port: 0 }, async function doNotUseAsyncCallback () {
|
|
115
|
+
t.assert.deepStrictEqual(spyData.calls, [{ arguments: ['listen method'], result: true }])
|
|
116
|
+
t.assert.strictEqual(spyData.callCount(), 1)
|
|
120
117
|
done()
|
|
121
118
|
})
|
|
122
119
|
})
|
|
@@ -14,7 +14,7 @@ const helper = require('../helper')
|
|
|
14
14
|
const { FST_ERR_LOG_INVALID_LOGGER } = require('../../lib/errors')
|
|
15
15
|
const { once, on } = stream
|
|
16
16
|
const { createTempFile, request } = require('./logger-test-utils')
|
|
17
|
-
const { partialDeepStrictEqual } = require('../
|
|
17
|
+
const { partialDeepStrictEqual } = require('../helper')
|
|
18
18
|
|
|
19
19
|
t.test('logger instantiation', { timeout: 60000 }, async (t) => {
|
|
20
20
|
let localhost
|
|
@@ -11,7 +11,7 @@ const { LogController } = require('../../lib/log-controller')
|
|
|
11
11
|
const helper = require('../helper')
|
|
12
12
|
const { once, on } = stream
|
|
13
13
|
const { request } = require('./logger-test-utils')
|
|
14
|
-
const { partialDeepStrictEqual } = require('../
|
|
14
|
+
const { partialDeepStrictEqual } = require('../helper')
|
|
15
15
|
|
|
16
16
|
t.test('logging', { timeout: 60000 }, async (t) => {
|
|
17
17
|
let localhost
|
|
@@ -9,7 +9,7 @@ const Fastify = require('../../fastify')
|
|
|
9
9
|
const helper = require('../helper')
|
|
10
10
|
const { on } = stream
|
|
11
11
|
const { request } = require('./logger-test-utils')
|
|
12
|
-
const { partialDeepStrictEqual } = require('../
|
|
12
|
+
const { partialDeepStrictEqual } = require('../helper')
|
|
13
13
|
|
|
14
14
|
t.test('request', { timeout: 60000 }, async (t) => {
|
|
15
15
|
let localhost
|
|
@@ -7,7 +7,7 @@ const split = require('split2')
|
|
|
7
7
|
const pino = require('pino')
|
|
8
8
|
|
|
9
9
|
const Fastify = require('../../fastify')
|
|
10
|
-
const { partialDeepStrictEqual } = require('../
|
|
10
|
+
const { partialDeepStrictEqual } = require('../helper')
|
|
11
11
|
const { on } = stream
|
|
12
12
|
|
|
13
13
|
t.test('response serialization', { timeout: 60000 }, async (t) => {
|
package/test/plugin.4.test.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { test, describe } = require('node:test')
|
|
4
4
|
const Fastify = require('../fastify')
|
|
5
5
|
const fp = require('fastify-plugin')
|
|
6
|
-
const fakeTimer = require('@sinonjs/fake-timers')
|
|
7
6
|
const { FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER } = require('../lib/errors')
|
|
8
7
|
|
|
9
8
|
test('pluginTimeout', (t, testDone) => {
|
|
@@ -46,12 +45,14 @@ test('pluginTimeout - named function', (t, testDone) => {
|
|
|
46
45
|
|
|
47
46
|
test('pluginTimeout default', (t, testDone) => {
|
|
48
47
|
t.plan(5)
|
|
49
|
-
|
|
48
|
+
t.mock.timers.enable({
|
|
49
|
+
apis: ['setTimeout', 'Date']
|
|
50
|
+
})
|
|
50
51
|
|
|
51
52
|
const fastify = Fastify()
|
|
52
53
|
fastify.register(function (app, opts, done) {
|
|
53
54
|
// default time elapsed without calling done
|
|
54
|
-
|
|
55
|
+
t.mock.timers.tick(10000)
|
|
55
56
|
})
|
|
56
57
|
|
|
57
58
|
fastify.ready((err) => {
|
|
@@ -64,7 +65,7 @@ test('pluginTimeout default', (t, testDone) => {
|
|
|
64
65
|
testDone()
|
|
65
66
|
})
|
|
66
67
|
|
|
67
|
-
t.after(
|
|
68
|
+
t.after(() => t.mock.timers.reset())
|
|
68
69
|
})
|
|
69
70
|
|
|
70
71
|
test('plugin metadata - version', (t, testDone) => {
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('node:test')
|
|
4
|
+
const Fastify = require('..')
|
|
5
|
+
|
|
6
|
+
test('reply.mediaType should match the content-type header', async (t) => {
|
|
7
|
+
t.plan(2)
|
|
8
|
+
|
|
9
|
+
const fastify = Fastify()
|
|
10
|
+
|
|
11
|
+
fastify.get('/', (request, reply) => {
|
|
12
|
+
reply.type('application/json')
|
|
13
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
14
|
+
reply.send({ mediaType: reply.mediaType })
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const response = await fastify.inject({
|
|
18
|
+
method: 'GET',
|
|
19
|
+
url: '/'
|
|
20
|
+
})
|
|
21
|
+
const body = await response.json()
|
|
22
|
+
t.assert.strictEqual(body.mediaType, 'application/json')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('reply.mediaType should strip the charset parameter', async (t) => {
|
|
26
|
+
t.plan(2)
|
|
27
|
+
|
|
28
|
+
const fastify = Fastify()
|
|
29
|
+
|
|
30
|
+
fastify.get('/', (request, reply) => {
|
|
31
|
+
reply.header('content-type', 'application/json; charset=utf-8')
|
|
32
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
33
|
+
reply.send({ mediaType: reply.mediaType })
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const response = await fastify.inject({
|
|
37
|
+
method: 'GET',
|
|
38
|
+
url: '/'
|
|
39
|
+
})
|
|
40
|
+
const body = await response.json()
|
|
41
|
+
t.assert.strictEqual(body.mediaType, 'application/json')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('reply.mediaType should strip the space', async (t) => {
|
|
45
|
+
t.plan(2)
|
|
46
|
+
|
|
47
|
+
const fastify = Fastify()
|
|
48
|
+
|
|
49
|
+
fastify.get('/', (request, reply) => {
|
|
50
|
+
reply.header('content-type', ' application/json ; charset=utf-8')
|
|
51
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
52
|
+
reply.send({ mediaType: reply.mediaType })
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const response = await fastify.inject({
|
|
56
|
+
method: 'GET',
|
|
57
|
+
url: '/'
|
|
58
|
+
})
|
|
59
|
+
const body = await response.json()
|
|
60
|
+
t.assert.strictEqual(body.mediaType, 'application/json')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('reply.mediaType is undefined when content-type is not set', async (t) => {
|
|
64
|
+
t.plan(2)
|
|
65
|
+
|
|
66
|
+
const fastify = Fastify()
|
|
67
|
+
|
|
68
|
+
fastify.get('/', (request, reply) => {
|
|
69
|
+
t.assert.strictEqual(reply.mediaType, undefined)
|
|
70
|
+
reply.send({ mediaType: reply.mediaType })
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const response = await fastify.inject({
|
|
74
|
+
method: 'GET',
|
|
75
|
+
url: '/'
|
|
76
|
+
})
|
|
77
|
+
const body = await response.json()
|
|
78
|
+
t.assert.strictEqual(body.mediaType, undefined)
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('reply.mediaType supported in hooks', async (t) => {
|
|
82
|
+
t.plan(5)
|
|
83
|
+
|
|
84
|
+
const fastify = Fastify()
|
|
85
|
+
|
|
86
|
+
fastify.get('/', {
|
|
87
|
+
preHandler: (request, reply, done) => {
|
|
88
|
+
reply.type('application/json')
|
|
89
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
90
|
+
done()
|
|
91
|
+
},
|
|
92
|
+
preSerialization: (request, reply, payload, done) => {
|
|
93
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
94
|
+
done(null, payload)
|
|
95
|
+
},
|
|
96
|
+
onSend: (request, reply, payload, done) => {
|
|
97
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
98
|
+
done(null, payload)
|
|
99
|
+
}
|
|
100
|
+
}, (request, reply) => {
|
|
101
|
+
t.assert.strictEqual(reply.mediaType, 'application/json')
|
|
102
|
+
reply.send({ mediaType: reply.mediaType })
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const response = await fastify.inject({
|
|
106
|
+
method: 'GET',
|
|
107
|
+
url: '/'
|
|
108
|
+
})
|
|
109
|
+
const body = await response.json()
|
|
110
|
+
t.assert.strictEqual(body.mediaType, 'application/json')
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
test('reply.mediaType should reflect the last type set', async (t) => {
|
|
114
|
+
t.plan(2)
|
|
115
|
+
|
|
116
|
+
const fastify = Fastify()
|
|
117
|
+
|
|
118
|
+
fastify.get('/', (request, reply) => {
|
|
119
|
+
reply.type('application/json')
|
|
120
|
+
reply.type('text/plain')
|
|
121
|
+
t.assert.strictEqual(reply.mediaType, 'text/plain')
|
|
122
|
+
reply.send(`mediaType = ${reply.mediaType}`)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const response = await fastify.inject({
|
|
126
|
+
method: 'GET',
|
|
127
|
+
url: '/'
|
|
128
|
+
})
|
|
129
|
+
const body = response.body
|
|
130
|
+
t.assert.strictEqual(body, 'mediaType = text/plain')
|
|
131
|
+
})
|