fastify 5.3.2 → 5.4.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 +2 -0
- package/build/build-validation.js +2 -1
- package/docs/Guides/Delay-Accepting-Requests.md +3 -3
- package/docs/Guides/Ecosystem.md +16 -7
- package/docs/Guides/Serverless.md +28 -69
- package/docs/Reference/ContentTypeParser.md +1 -1
- package/docs/Reference/Errors.md +2 -4
- package/docs/Reference/Hooks.md +14 -14
- package/docs/Reference/Logging.md +3 -3
- package/docs/Reference/Middleware.md +1 -1
- package/docs/Reference/Reply.md +8 -8
- package/docs/Reference/Request.md +1 -1
- package/docs/Reference/Routes.md +3 -3
- package/docs/Reference/Server.md +40 -10
- package/docs/Reference/Validation-and-Serialization.md +1 -1
- package/eslint.config.js +17 -9
- package/fastify.d.ts +2 -1
- package/fastify.js +20 -4
- package/lib/configValidator.js +1 -1
- package/lib/decorate.js +2 -2
- package/lib/errors.js +6 -8
- package/lib/logger-factory.js +1 -1
- package/lib/logger-pino.js +2 -2
- package/lib/pluginOverride.js +3 -1
- package/lib/reply.js +9 -13
- package/lib/request.js +4 -11
- package/lib/server.js +30 -51
- package/lib/symbols.js +1 -0
- package/lib/warnings.js +8 -0
- package/package.json +11 -7
- package/test/404s.test.js +226 -325
- package/test/allow-unsafe-regex.test.js +19 -48
- package/test/als.test.js +28 -40
- package/test/async-await.test.js +11 -2
- package/test/body-limit.test.js +41 -65
- package/test/build-certificate.js +1 -1
- package/test/close-pipelining.test.js +5 -4
- package/test/custom-parser-async.test.js +17 -22
- package/test/decorator-namespace.test._js_ +3 -4
- package/test/decorator.test.js +422 -341
- package/test/diagnostics-channel/async-delay-request.test.js +7 -16
- package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
- package/test/helper.js +108 -70
- package/test/hooks-async.test.js +248 -218
- package/test/hooks.on-listen.test.js +255 -239
- package/test/hooks.on-ready.test.js +110 -92
- package/test/hooks.test.js +910 -769
- package/test/http-methods/lock.test.js +31 -31
- package/test/http-methods/mkcol.test.js +5 -9
- package/test/http-methods/proppatch.test.js +23 -29
- package/test/http-methods/report.test.js +44 -69
- package/test/http-methods/search.test.js +67 -82
- package/test/http2/closing.test.js +38 -20
- package/test/http2/secure-with-fallback.test.js +28 -27
- package/test/https/https.test.js +56 -53
- package/test/inject.test.js +114 -97
- package/test/input-validation.js +63 -53
- package/test/internals/errors.test.js +0 -10
- package/test/internals/handle-request.test.js +49 -66
- package/test/internals/hooks.test.js +17 -0
- package/test/issue-4959.test.js +14 -5
- package/test/listen.4.test.js +31 -43
- package/test/logger/response.test.js +19 -20
- package/test/nullable-validation.test.js +33 -46
- package/test/options.error-handler.test.js +1 -1
- package/test/options.test.js +1 -1
- package/test/output-validation.test.js +49 -72
- package/test/patch.error-handler.test.js +1 -1
- package/test/patch.test.js +1 -1
- package/test/plugin.1.test.js +71 -60
- package/test/plugin.2.test.js +104 -86
- package/test/plugin.3.test.js +56 -35
- package/test/plugin.4.test.js +124 -119
- package/test/promises.test.js +36 -30
- package/test/proto-poisoning.test.js +78 -97
- package/test/put.error-handler.test.js +1 -1
- package/test/put.test.js +1 -1
- package/test/reply-error.test.js +169 -148
- package/test/reply-trailers.test.js +119 -108
- package/test/request-error.test.js +0 -46
- package/test/route-hooks.test.js +112 -92
- package/test/route-prefix.test.js +194 -133
- package/test/schema-feature.test.js +309 -238
- package/test/schema-serialization.test.js +177 -154
- package/test/schema-special-usage.test.js +165 -132
- package/test/schema-validation.test.js +278 -199
- package/test/set-error-handler.test.js +58 -1
- package/test/skip-reply-send.test.js +64 -69
- package/test/stream.1.test.js +30 -27
- package/test/stream.2.test.js +20 -10
- package/test/stream.3.test.js +37 -31
- package/test/trust-proxy.test.js +32 -58
- package/test/types/errors.test-d.ts +0 -1
- package/test/types/fastify.test-d.ts +3 -0
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/register.test-d.ts +1 -1
- package/test/types/request.test-d.ts +1 -0
- package/test/url-rewriting.test.js +45 -62
- package/test/use-semicolon-delimiter.test.js +1 -1
- package/types/errors.d.ts +0 -1
- package/types/request.d.ts +1 -0
- package/.taprc +0 -7
- package/test/http2/missing-http2-module.test.js +0 -17
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Joi = require('joi')
|
|
5
5
|
const yup = require('yup')
|
|
6
6
|
const AJV = require('ajv')
|
|
@@ -8,8 +8,10 @@ const S = require('fluent-json-schema')
|
|
|
8
8
|
const Fastify = require('..')
|
|
9
9
|
const ajvMergePatch = require('ajv-merge-patch')
|
|
10
10
|
const ajvErrors = require('ajv-errors')
|
|
11
|
+
const proxyquire = require('proxyquire')
|
|
12
|
+
const { waitForCb } = require('./toolkit')
|
|
11
13
|
|
|
12
|
-
test('Ajv plugins array parameter', t => {
|
|
14
|
+
test('Ajv plugins array parameter', (t, testDone) => {
|
|
13
15
|
t.plan(3)
|
|
14
16
|
const fastify = Fastify({
|
|
15
17
|
ajv: {
|
|
@@ -50,13 +52,14 @@ test('Ajv plugins array parameter', t => {
|
|
|
50
52
|
url: '/',
|
|
51
53
|
payload: { foo: 99 }
|
|
52
54
|
}, (err, res) => {
|
|
53
|
-
t.
|
|
54
|
-
t.
|
|
55
|
-
t.
|
|
55
|
+
t.assert.ifError(err)
|
|
56
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
57
|
+
t.assert.strictEqual(res.json().message, 'body/foo should be <= 10@@@@should be multipleOf 2')
|
|
58
|
+
testDone()
|
|
56
59
|
})
|
|
57
60
|
})
|
|
58
61
|
|
|
59
|
-
test('Should handle root $merge keywords in header', t => {
|
|
62
|
+
test('Should handle root $merge keywords in header', (t, testDone) => {
|
|
60
63
|
t.plan(5)
|
|
61
64
|
const fastify = Fastify({
|
|
62
65
|
ajv: {
|
|
@@ -86,14 +89,14 @@ test('Should handle root $merge keywords in header', t => {
|
|
|
86
89
|
})
|
|
87
90
|
|
|
88
91
|
fastify.ready(err => {
|
|
89
|
-
t.
|
|
92
|
+
t.assert.ifError(err)
|
|
90
93
|
|
|
91
94
|
fastify.inject({
|
|
92
95
|
method: 'GET',
|
|
93
96
|
url: '/'
|
|
94
97
|
}, (err, res) => {
|
|
95
|
-
t.
|
|
96
|
-
t.
|
|
98
|
+
t.assert.ifError(err)
|
|
99
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
97
100
|
})
|
|
98
101
|
|
|
99
102
|
fastify.inject({
|
|
@@ -101,13 +104,14 @@ test('Should handle root $merge keywords in header', t => {
|
|
|
101
104
|
url: '/',
|
|
102
105
|
headers: { q: 'foo' }
|
|
103
106
|
}, (err, res) => {
|
|
104
|
-
t.
|
|
105
|
-
t.
|
|
107
|
+
t.assert.ifError(err)
|
|
108
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
109
|
+
testDone()
|
|
106
110
|
})
|
|
107
111
|
})
|
|
108
112
|
})
|
|
109
113
|
|
|
110
|
-
test('Should handle root $patch keywords in header', t => {
|
|
114
|
+
test('Should handle root $patch keywords in header', (t, testDone) => {
|
|
111
115
|
t.plan(5)
|
|
112
116
|
const fastify = Fastify({
|
|
113
117
|
ajv: {
|
|
@@ -143,7 +147,7 @@ test('Should handle root $patch keywords in header', t => {
|
|
|
143
147
|
})
|
|
144
148
|
|
|
145
149
|
fastify.ready(err => {
|
|
146
|
-
t.
|
|
150
|
+
t.assert.ifError(err)
|
|
147
151
|
|
|
148
152
|
fastify.inject({
|
|
149
153
|
method: 'GET',
|
|
@@ -152,8 +156,8 @@ test('Should handle root $patch keywords in header', t => {
|
|
|
152
156
|
q: 'foo'
|
|
153
157
|
}
|
|
154
158
|
}, (err, res) => {
|
|
155
|
-
t.
|
|
156
|
-
t.
|
|
159
|
+
t.assert.ifError(err)
|
|
160
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
157
161
|
})
|
|
158
162
|
|
|
159
163
|
fastify.inject({
|
|
@@ -161,13 +165,14 @@ test('Should handle root $patch keywords in header', t => {
|
|
|
161
165
|
url: '/',
|
|
162
166
|
headers: { q: 10 }
|
|
163
167
|
}, (err, res) => {
|
|
164
|
-
t.
|
|
165
|
-
t.
|
|
168
|
+
t.assert.ifError(err)
|
|
169
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
170
|
+
testDone()
|
|
166
171
|
})
|
|
167
172
|
})
|
|
168
173
|
})
|
|
169
174
|
|
|
170
|
-
test('Should handle $merge keywords in body', t => {
|
|
175
|
+
test('Should handle $merge keywords in body', (t, testDone) => {
|
|
171
176
|
t.plan(5)
|
|
172
177
|
const fastify = Fastify({
|
|
173
178
|
ajv: {
|
|
@@ -197,14 +202,14 @@ test('Should handle $merge keywords in body', t => {
|
|
|
197
202
|
})
|
|
198
203
|
|
|
199
204
|
fastify.ready(err => {
|
|
200
|
-
t.
|
|
205
|
+
t.assert.ifError(err)
|
|
201
206
|
|
|
202
207
|
fastify.inject({
|
|
203
208
|
method: 'POST',
|
|
204
209
|
url: '/'
|
|
205
210
|
}, (err, res) => {
|
|
206
|
-
t.
|
|
207
|
-
t.
|
|
211
|
+
t.assert.ifError(err)
|
|
212
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
208
213
|
})
|
|
209
214
|
|
|
210
215
|
fastify.inject({
|
|
@@ -212,13 +217,14 @@ test('Should handle $merge keywords in body', t => {
|
|
|
212
217
|
url: '/',
|
|
213
218
|
payload: { q: 'foo' }
|
|
214
219
|
}, (err, res) => {
|
|
215
|
-
t.
|
|
216
|
-
t.
|
|
220
|
+
t.assert.ifError(err)
|
|
221
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
222
|
+
testDone()
|
|
217
223
|
})
|
|
218
224
|
})
|
|
219
225
|
})
|
|
220
226
|
|
|
221
|
-
test('Should handle $patch keywords in body', t => {
|
|
227
|
+
test('Should handle $patch keywords in body', (t, testDone) => {
|
|
222
228
|
t.plan(5)
|
|
223
229
|
const fastify = Fastify({
|
|
224
230
|
ajv: {
|
|
@@ -252,29 +258,32 @@ test('Should handle $patch keywords in body', t => {
|
|
|
252
258
|
})
|
|
253
259
|
|
|
254
260
|
fastify.ready(err => {
|
|
255
|
-
t.
|
|
261
|
+
t.assert.ifError(err)
|
|
256
262
|
|
|
263
|
+
const completion = waitForCb({ steps: 2 })
|
|
257
264
|
fastify.inject({
|
|
258
265
|
method: 'POST',
|
|
259
266
|
url: '/',
|
|
260
267
|
payload: { q: 'foo' }
|
|
261
268
|
}, (err, res) => {
|
|
262
|
-
t.
|
|
263
|
-
t.
|
|
269
|
+
t.assert.ifError(err)
|
|
270
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
271
|
+
completion.stepIn()
|
|
264
272
|
})
|
|
265
|
-
|
|
266
273
|
fastify.inject({
|
|
267
274
|
method: 'POST',
|
|
268
275
|
url: '/',
|
|
269
276
|
payload: { q: 10 }
|
|
270
277
|
}, (err, res) => {
|
|
271
|
-
t.
|
|
272
|
-
t.
|
|
278
|
+
t.assert.ifError(err)
|
|
279
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
280
|
+
completion.stepIn()
|
|
273
281
|
})
|
|
282
|
+
completion.patience.then(testDone)
|
|
274
283
|
})
|
|
275
284
|
})
|
|
276
285
|
|
|
277
|
-
test("serializer read validator's schemas", t => {
|
|
286
|
+
test("serializer read validator's schemas", (t, testDone) => {
|
|
278
287
|
t.plan(4)
|
|
279
288
|
const ajvInstance = new AJV()
|
|
280
289
|
|
|
@@ -303,7 +312,7 @@ test("serializer read validator's schemas", t => {
|
|
|
303
312
|
const fastify = Fastify({
|
|
304
313
|
schemaController: {
|
|
305
314
|
bucket: function factory (storeInit) {
|
|
306
|
-
t.
|
|
315
|
+
t.assert.ok(!storeInit, 'is always empty because fastify.addSchema is not called')
|
|
307
316
|
return {
|
|
308
317
|
getSchemas () {
|
|
309
318
|
return {
|
|
@@ -330,13 +339,14 @@ test("serializer read validator's schemas", t => {
|
|
|
330
339
|
})
|
|
331
340
|
|
|
332
341
|
fastify.inject('/', (err, res) => {
|
|
333
|
-
t.
|
|
334
|
-
t.
|
|
335
|
-
t.
|
|
342
|
+
t.assert.ifError(err)
|
|
343
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
344
|
+
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
|
345
|
+
testDone()
|
|
336
346
|
})
|
|
337
347
|
})
|
|
338
348
|
|
|
339
|
-
test('setSchemaController in a plugin', t => {
|
|
349
|
+
test('setSchemaController in a plugin', (t, testDone) => {
|
|
340
350
|
t.plan(5)
|
|
341
351
|
const baseSchema = {
|
|
342
352
|
$id: 'urn:schema:base',
|
|
@@ -376,15 +386,16 @@ test('setSchemaController in a plugin', t => {
|
|
|
376
386
|
})
|
|
377
387
|
|
|
378
388
|
fastify.inject('/', (err, res) => {
|
|
379
|
-
t.
|
|
380
|
-
t.
|
|
381
|
-
t.
|
|
389
|
+
t.assert.ifError(err)
|
|
390
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
391
|
+
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
|
392
|
+
testDone()
|
|
382
393
|
})
|
|
383
394
|
|
|
384
395
|
async function schemaPlugin (server) {
|
|
385
396
|
server.setSchemaController({
|
|
386
397
|
bucket () {
|
|
387
|
-
t.
|
|
398
|
+
t.assert.ok('the bucket is created')
|
|
388
399
|
return {
|
|
389
400
|
addSchema (source) {
|
|
390
401
|
ajvInstance.addSchema(source)
|
|
@@ -402,7 +413,7 @@ test('setSchemaController in a plugin', t => {
|
|
|
402
413
|
}
|
|
403
414
|
})
|
|
404
415
|
server.setValidatorCompiler(function ({ schema }) {
|
|
405
|
-
t.
|
|
416
|
+
t.assert.ok('the querystring schema is compiled')
|
|
406
417
|
return ajvInstance.compile(schema)
|
|
407
418
|
})
|
|
408
419
|
}
|
|
@@ -506,7 +517,7 @@ test('only response schema trigger AJV pollution #2', async t => {
|
|
|
506
517
|
await fastify.ready()
|
|
507
518
|
})
|
|
508
519
|
|
|
509
|
-
test('setSchemaController in a plugin with head routes', t => {
|
|
520
|
+
test('setSchemaController in a plugin with head routes', (t, testDone) => {
|
|
510
521
|
t.plan(6)
|
|
511
522
|
const baseSchema = {
|
|
512
523
|
$id: 'urn:schema:base',
|
|
@@ -546,15 +557,16 @@ test('setSchemaController in a plugin with head routes', t => {
|
|
|
546
557
|
})
|
|
547
558
|
|
|
548
559
|
fastify.inject('/', (err, res) => {
|
|
549
|
-
t.
|
|
550
|
-
t.
|
|
551
|
-
t.
|
|
560
|
+
t.assert.ifError(err)
|
|
561
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
562
|
+
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
|
563
|
+
testDone()
|
|
552
564
|
})
|
|
553
565
|
|
|
554
566
|
async function schemaPlugin (server) {
|
|
555
567
|
server.setSchemaController({
|
|
556
568
|
bucket () {
|
|
557
|
-
t.
|
|
569
|
+
t.assert.ok('the bucket is created')
|
|
558
570
|
return {
|
|
559
571
|
addSchema (source) {
|
|
560
572
|
ajvInstance.addSchema(source)
|
|
@@ -575,11 +587,11 @@ test('setSchemaController in a plugin with head routes', t => {
|
|
|
575
587
|
if (schema.$id) {
|
|
576
588
|
const stored = ajvInstance.getSchema(schema.$id)
|
|
577
589
|
if (stored) {
|
|
578
|
-
t.
|
|
590
|
+
t.assert.ok('the schema is reused')
|
|
579
591
|
return stored
|
|
580
592
|
}
|
|
581
593
|
}
|
|
582
|
-
t.
|
|
594
|
+
t.assert.ok('the schema is compiled')
|
|
583
595
|
|
|
584
596
|
return ajvInstance.compile(schema)
|
|
585
597
|
})
|
|
@@ -587,7 +599,7 @@ test('setSchemaController in a plugin with head routes', t => {
|
|
|
587
599
|
schemaPlugin[Symbol.for('skip-override')] = true
|
|
588
600
|
})
|
|
589
601
|
|
|
590
|
-
test('multiple refs with the same ids', t => {
|
|
602
|
+
test('multiple refs with the same ids', (t, testDone) => {
|
|
591
603
|
t.plan(3)
|
|
592
604
|
const baseSchema = {
|
|
593
605
|
$id: 'urn:schema:base',
|
|
@@ -638,13 +650,14 @@ test('multiple refs with the same ids', t => {
|
|
|
638
650
|
})
|
|
639
651
|
|
|
640
652
|
fastify.inject('/', (err, res) => {
|
|
641
|
-
t.
|
|
642
|
-
t.
|
|
643
|
-
t.
|
|
653
|
+
t.assert.ifError(err)
|
|
654
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
655
|
+
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
|
656
|
+
testDone()
|
|
644
657
|
})
|
|
645
658
|
})
|
|
646
659
|
|
|
647
|
-
test('JOI validation overwrite request headers', t => {
|
|
660
|
+
test('JOI validation overwrite request headers', (t, testDone) => {
|
|
648
661
|
t.plan(3)
|
|
649
662
|
const schemaValidator = ({ schema }) => data => {
|
|
650
663
|
const validationResult = schema.validate(data)
|
|
@@ -666,12 +679,13 @@ test('JOI validation overwrite request headers', t => {
|
|
|
666
679
|
})
|
|
667
680
|
|
|
668
681
|
fastify.inject('/', (err, res) => {
|
|
669
|
-
t.
|
|
670
|
-
t.
|
|
671
|
-
t.
|
|
682
|
+
t.assert.ifError(err)
|
|
683
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
684
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
672
685
|
'user-agent': 'lightMyRequest',
|
|
673
686
|
host: 'localhost:80'
|
|
674
687
|
})
|
|
688
|
+
testDone()
|
|
675
689
|
})
|
|
676
690
|
})
|
|
677
691
|
|
|
@@ -700,16 +714,16 @@ test('Custom schema object should not trigger FST_ERR_SCH_DUPLICATE', async t =>
|
|
|
700
714
|
})
|
|
701
715
|
|
|
702
716
|
await fastify.ready()
|
|
703
|
-
t.
|
|
717
|
+
t.assert.ok('fastify is ready')
|
|
704
718
|
})
|
|
705
719
|
|
|
706
720
|
test('The default schema compilers should not be called when overwritten by the user', async t => {
|
|
707
|
-
const Fastify =
|
|
721
|
+
const Fastify = proxyquire('../', {
|
|
708
722
|
'@fastify/ajv-compiler': () => {
|
|
709
|
-
t.fail('The default validator compiler should not be called')
|
|
723
|
+
t.assert.fail('The default validator compiler should not be called')
|
|
710
724
|
},
|
|
711
725
|
'@fastify/fast-json-stringify-compiler': () => {
|
|
712
|
-
t.fail('The default serializer compiler should not be called')
|
|
726
|
+
t.assert.fail('The default serializer compiler should not be called')
|
|
713
727
|
}
|
|
714
728
|
})
|
|
715
729
|
|
|
@@ -717,13 +731,13 @@ test('The default schema compilers should not be called when overwritten by the
|
|
|
717
731
|
schemaController: {
|
|
718
732
|
compilersFactory: {
|
|
719
733
|
buildValidator: function factory () {
|
|
720
|
-
t.
|
|
734
|
+
t.assert.ok('The custom validator compiler should be called')
|
|
721
735
|
return function validatorCompiler () {
|
|
722
736
|
return () => { return true }
|
|
723
737
|
}
|
|
724
738
|
},
|
|
725
739
|
buildSerializer: function factory () {
|
|
726
|
-
t.
|
|
740
|
+
t.assert.ok('The custom serializer compiler should be called')
|
|
727
741
|
return function serializerCompiler () {
|
|
728
742
|
return () => { return true }
|
|
729
743
|
}
|
|
@@ -745,7 +759,7 @@ test('The default schema compilers should not be called when overwritten by the
|
|
|
745
759
|
await fastify.ready()
|
|
746
760
|
})
|
|
747
761
|
|
|
748
|
-
test('Supports async JOI validation', t => {
|
|
762
|
+
test('Supports async JOI validation', (t, testDone) => {
|
|
749
763
|
t.plan(7)
|
|
750
764
|
|
|
751
765
|
const schemaValidator = ({ schema }) => async data => {
|
|
@@ -766,7 +780,7 @@ test('Supports async JOI validation', t => {
|
|
|
766
780
|
throw new Error('Invalid user-agent')
|
|
767
781
|
}
|
|
768
782
|
|
|
769
|
-
t.
|
|
783
|
+
t.assert.strictEqual(val, 'lightMyRequest')
|
|
770
784
|
return val
|
|
771
785
|
}),
|
|
772
786
|
host: Joi.string().required()
|
|
@@ -776,33 +790,37 @@ test('Supports async JOI validation', t => {
|
|
|
776
790
|
reply.send(request.headers)
|
|
777
791
|
})
|
|
778
792
|
|
|
793
|
+
const completion = waitForCb({ steps: 2 })
|
|
779
794
|
fastify.inject('/', (err, res) => {
|
|
780
|
-
t.
|
|
781
|
-
t.
|
|
782
|
-
t.
|
|
795
|
+
t.assert.ifError(err)
|
|
796
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
797
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
783
798
|
'user-agent': 'lightMyRequest',
|
|
784
799
|
host: 'localhost:80'
|
|
785
800
|
})
|
|
801
|
+
completion.stepIn()
|
|
786
802
|
})
|
|
787
|
-
|
|
788
803
|
fastify.inject({
|
|
789
804
|
url: '/',
|
|
790
805
|
headers: {
|
|
791
806
|
'user-agent': 'invalid'
|
|
792
807
|
}
|
|
793
808
|
}, (err, res) => {
|
|
794
|
-
t.
|
|
795
|
-
t.
|
|
796
|
-
t.
|
|
809
|
+
t.assert.ifError(err)
|
|
810
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
811
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
797
812
|
statusCode: 400,
|
|
798
813
|
code: 'FST_ERR_VALIDATION',
|
|
799
814
|
error: 'Bad Request',
|
|
800
815
|
message: 'Invalid user-agent (user-agent)'
|
|
801
816
|
})
|
|
817
|
+
completion.stepIn()
|
|
802
818
|
})
|
|
819
|
+
|
|
820
|
+
completion.patience.then(testDone)
|
|
803
821
|
})
|
|
804
822
|
|
|
805
|
-
test('Supports async AJV validation', t => {
|
|
823
|
+
test('Supports async AJV validation', (t, testDone) => {
|
|
806
824
|
t.plan(12)
|
|
807
825
|
|
|
808
826
|
const fastify = Fastify({
|
|
@@ -861,63 +879,67 @@ test('Supports async AJV validation', t => {
|
|
|
861
879
|
handler (req, reply) { reply.send(req.body) }
|
|
862
880
|
})
|
|
863
881
|
|
|
882
|
+
const completion = waitForCb({ steps: 4 })
|
|
883
|
+
|
|
864
884
|
fastify.inject({
|
|
865
885
|
method: 'POST',
|
|
866
886
|
url: '/',
|
|
867
887
|
payload: { userId: 99 }
|
|
868
888
|
}, (err, res) => {
|
|
869
|
-
t.
|
|
870
|
-
t.
|
|
871
|
-
t.
|
|
889
|
+
t.assert.ifError(err)
|
|
890
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
891
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
872
892
|
statusCode: 400,
|
|
873
893
|
code: 'FST_ERR_VALIDATION',
|
|
874
894
|
error: 'Bad Request',
|
|
875
895
|
message: 'validation failed'
|
|
876
896
|
})
|
|
897
|
+
completion.stepIn()
|
|
877
898
|
})
|
|
878
|
-
|
|
879
899
|
fastify.inject({
|
|
880
900
|
method: 'POST',
|
|
881
901
|
url: '/',
|
|
882
902
|
payload: { userId: 500 }
|
|
883
903
|
}, (err, res) => {
|
|
884
|
-
t.
|
|
885
|
-
t.
|
|
886
|
-
t.
|
|
904
|
+
t.assert.ifError(err)
|
|
905
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
906
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
887
907
|
statusCode: 400,
|
|
888
908
|
code: 'FST_ERR_VALIDATION',
|
|
889
909
|
error: 'Bad Request',
|
|
890
910
|
message: 'custom error'
|
|
891
911
|
})
|
|
912
|
+
completion.stepIn()
|
|
892
913
|
})
|
|
893
|
-
|
|
894
914
|
fastify.inject({
|
|
895
915
|
method: 'POST',
|
|
896
916
|
url: '/',
|
|
897
917
|
payload: { userId: 42 }
|
|
898
918
|
}, (err, res) => {
|
|
899
|
-
t.
|
|
900
|
-
t.
|
|
901
|
-
t.
|
|
919
|
+
t.assert.ifError(err)
|
|
920
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
921
|
+
t.assert.deepStrictEqual(res.json(), { userId: 42 })
|
|
922
|
+
completion.stepIn()
|
|
902
923
|
})
|
|
903
|
-
|
|
904
924
|
fastify.inject({
|
|
905
925
|
method: 'POST',
|
|
906
926
|
url: '/',
|
|
907
927
|
payload: { userId: 42, postId: 19 }
|
|
908
928
|
}, (err, res) => {
|
|
909
|
-
t.
|
|
910
|
-
t.
|
|
911
|
-
t.
|
|
929
|
+
t.assert.ifError(err)
|
|
930
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
931
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
912
932
|
statusCode: 400,
|
|
913
933
|
code: 'FST_ERR_VALIDATION',
|
|
914
934
|
error: 'Bad Request',
|
|
915
935
|
message: 'validation failed'
|
|
916
936
|
})
|
|
937
|
+
completion.stepIn()
|
|
917
938
|
})
|
|
939
|
+
completion.patience.then(testDone)
|
|
918
940
|
})
|
|
919
941
|
|
|
920
|
-
test('Check all the async AJV validation paths', t => {
|
|
942
|
+
test('Check all the async AJV validation paths', async (t) => {
|
|
921
943
|
const fastify = Fastify({
|
|
922
944
|
exposeHeadRoutes: false,
|
|
923
945
|
ajv: {
|
|
@@ -1004,30 +1026,34 @@ test('Check all the async AJV validation paths', t => {
|
|
|
1004
1026
|
response: 200
|
|
1005
1027
|
}
|
|
1006
1028
|
]
|
|
1007
|
-
t.plan(testCases.length
|
|
1008
|
-
testCases
|
|
1029
|
+
t.plan(testCases.length)
|
|
1030
|
+
for (const testCase of testCases) {
|
|
1031
|
+
await validate(testCase)
|
|
1032
|
+
}
|
|
1009
1033
|
|
|
1010
|
-
function validate ({
|
|
1034
|
+
async function validate ({
|
|
1011
1035
|
params,
|
|
1012
1036
|
body,
|
|
1013
1037
|
querystring,
|
|
1014
1038
|
headers,
|
|
1015
1039
|
response
|
|
1016
1040
|
}) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
t.
|
|
1026
|
-
})
|
|
1041
|
+
try {
|
|
1042
|
+
const res = await fastify.inject({
|
|
1043
|
+
method: 'POST',
|
|
1044
|
+
url: `/${params}`,
|
|
1045
|
+
headers: { id: headers },
|
|
1046
|
+
query: { id: querystring },
|
|
1047
|
+
payload: { id: body }
|
|
1048
|
+
})
|
|
1049
|
+
t.assert.strictEqual(res.statusCode, response)
|
|
1050
|
+
} catch (error) {
|
|
1051
|
+
t.assert.fail('should not throw')
|
|
1052
|
+
}
|
|
1027
1053
|
}
|
|
1028
1054
|
})
|
|
1029
1055
|
|
|
1030
|
-
test('Check mixed sync and async AJV validations', t => {
|
|
1056
|
+
test('Check mixed sync and async AJV validations', async (t) => {
|
|
1031
1057
|
const fastify = Fastify({
|
|
1032
1058
|
exposeHeadRoutes: false,
|
|
1033
1059
|
ajv: {
|
|
@@ -1179,10 +1205,12 @@ test('Check mixed sync and async AJV validations', t => {
|
|
|
1179
1205
|
response: 400
|
|
1180
1206
|
}
|
|
1181
1207
|
]
|
|
1182
|
-
t.plan(testCases.length
|
|
1183
|
-
testCases
|
|
1208
|
+
t.plan(testCases.length)
|
|
1209
|
+
for (const testCase of testCases) {
|
|
1210
|
+
await validate(testCase)
|
|
1211
|
+
}
|
|
1184
1212
|
|
|
1185
|
-
function validate ({
|
|
1213
|
+
async function validate ({
|
|
1186
1214
|
url,
|
|
1187
1215
|
params,
|
|
1188
1216
|
body,
|
|
@@ -1190,20 +1218,22 @@ test('Check mixed sync and async AJV validations', t => {
|
|
|
1190
1218
|
headers,
|
|
1191
1219
|
response
|
|
1192
1220
|
}) {
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
t.
|
|
1202
|
-
})
|
|
1221
|
+
try {
|
|
1222
|
+
const res = await fastify.inject({
|
|
1223
|
+
method: 'POST',
|
|
1224
|
+
url: `${url}/${params || ''}`,
|
|
1225
|
+
headers: { id: headers },
|
|
1226
|
+
query: { id: querystring },
|
|
1227
|
+
payload: { id: body }
|
|
1228
|
+
})
|
|
1229
|
+
t.assert.strictEqual(res.statusCode, response)
|
|
1230
|
+
} catch (error) {
|
|
1231
|
+
t.assert.fail('should not fail')
|
|
1232
|
+
}
|
|
1203
1233
|
}
|
|
1204
1234
|
})
|
|
1205
1235
|
|
|
1206
|
-
test('Check if hooks and attachValidation work with AJV validations', t => {
|
|
1236
|
+
test('Check if hooks and attachValidation work with AJV validations', async (t) => {
|
|
1207
1237
|
const fastify = Fastify({
|
|
1208
1238
|
exposeHeadRoutes: false,
|
|
1209
1239
|
ajv: {
|
|
@@ -1245,8 +1275,8 @@ test('Check if hooks and attachValidation work with AJV validations', t => {
|
|
|
1245
1275
|
|
|
1246
1276
|
fastify.post('/:id', {
|
|
1247
1277
|
preHandler: function hook (request, reply, done) {
|
|
1248
|
-
t.
|
|
1249
|
-
t.
|
|
1278
|
+
t.assert.strictEqual(request.validationError.message, 'validation failed')
|
|
1279
|
+
t.assert.ok('preHandler called')
|
|
1250
1280
|
|
|
1251
1281
|
reply.code(400).send(request.body)
|
|
1252
1282
|
},
|
|
@@ -1290,26 +1320,29 @@ test('Check if hooks and attachValidation work with AJV validations', t => {
|
|
|
1290
1320
|
response: 400
|
|
1291
1321
|
}
|
|
1292
1322
|
]
|
|
1293
|
-
t.plan(testCases.length *
|
|
1294
|
-
testCases
|
|
1323
|
+
t.plan(testCases.length * 3)
|
|
1324
|
+
for (const testCase of testCases) {
|
|
1325
|
+
await validate(testCase)
|
|
1326
|
+
}
|
|
1295
1327
|
|
|
1296
|
-
function validate ({
|
|
1297
|
-
url,
|
|
1328
|
+
async function validate ({
|
|
1298
1329
|
params,
|
|
1299
1330
|
body,
|
|
1300
1331
|
querystring,
|
|
1301
1332
|
headers,
|
|
1302
1333
|
response
|
|
1303
1334
|
}) {
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
t.
|
|
1313
|
-
})
|
|
1335
|
+
try {
|
|
1336
|
+
const res = await fastify.inject({
|
|
1337
|
+
method: 'POST',
|
|
1338
|
+
url: `/${params}`,
|
|
1339
|
+
headers: { id: headers },
|
|
1340
|
+
query: { id: querystring },
|
|
1341
|
+
payload: { id: body }
|
|
1342
|
+
})
|
|
1343
|
+
t.assert.strictEqual(res.statusCode, response)
|
|
1344
|
+
} catch (error) {
|
|
1345
|
+
t.assert.fail('should not fail')
|
|
1346
|
+
}
|
|
1314
1347
|
}
|
|
1315
1348
|
})
|