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,12 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
|
-
const
|
|
5
|
+
const { waitForCb } = require('./toolkit')
|
|
6
6
|
|
|
7
7
|
const echoBody = (req, reply) => { reply.send(req.body) }
|
|
8
8
|
|
|
9
|
-
test('basic test', t => {
|
|
9
|
+
test('basic test', (t, testDone) => {
|
|
10
10
|
t.plan(3)
|
|
11
11
|
|
|
12
12
|
const fastify = Fastify()
|
|
@@ -27,13 +27,14 @@ test('basic test', t => {
|
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
fastify.inject('/', (err, res) => {
|
|
30
|
-
t.
|
|
31
|
-
t.
|
|
32
|
-
t.
|
|
30
|
+
t.assert.ifError(err)
|
|
31
|
+
t.assert.deepStrictEqual(res.json(), { name: 'Foo', work: 'Bar' })
|
|
32
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
33
|
+
testDone()
|
|
33
34
|
})
|
|
34
35
|
})
|
|
35
36
|
|
|
36
|
-
test('custom serializer options', t => {
|
|
37
|
+
test('custom serializer options', (t, testDone) => {
|
|
37
38
|
t.plan(3)
|
|
38
39
|
|
|
39
40
|
const fastify = Fastify({
|
|
@@ -54,13 +55,14 @@ test('custom serializer options', t => {
|
|
|
54
55
|
})
|
|
55
56
|
|
|
56
57
|
fastify.inject('/', (err, res) => {
|
|
57
|
-
t.
|
|
58
|
-
t.
|
|
59
|
-
t.
|
|
58
|
+
t.assert.ifError(err)
|
|
59
|
+
t.assert.strictEqual(res.payload, '5', 'it must use the ceil rounding')
|
|
60
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
61
|
+
testDone()
|
|
60
62
|
})
|
|
61
63
|
})
|
|
62
64
|
|
|
63
|
-
test('Different content types', t => {
|
|
65
|
+
test('Different content types', (t, testDone) => {
|
|
64
66
|
t.plan(46)
|
|
65
67
|
|
|
66
68
|
const fastify = Fastify()
|
|
@@ -217,7 +219,7 @@ test('Different content types', t => {
|
|
|
217
219
|
|
|
218
220
|
fastify.get('/test', {
|
|
219
221
|
serializerCompiler: ({ contentType }) => {
|
|
220
|
-
t.
|
|
222
|
+
t.assert.strictEqual(contentType, 'application/json')
|
|
221
223
|
return data => JSON.stringify(data)
|
|
222
224
|
},
|
|
223
225
|
schema: {
|
|
@@ -270,92 +272,96 @@ test('Different content types', t => {
|
|
|
270
272
|
}
|
|
271
273
|
})
|
|
272
274
|
|
|
275
|
+
const completion = waitForCb({ steps: 14 })
|
|
273
276
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/json' } }, (err, res) => {
|
|
274
|
-
t.
|
|
275
|
-
t.
|
|
276
|
-
t.
|
|
277
|
+
t.assert.ifError(err)
|
|
278
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ name: 'Foo', image: 'profile picture', address: 'New Node' }))
|
|
279
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
280
|
+
completion.stepIn()
|
|
277
281
|
})
|
|
278
|
-
|
|
279
282
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v1+json' } }, (err, res) => {
|
|
280
|
-
t.
|
|
281
|
-
t.
|
|
282
|
-
t.
|
|
283
|
+
t.assert.ifError(err)
|
|
284
|
+
t.assert.strictEqual(res.payload, JSON.stringify([{ name: 'Boo', age: 18, verified: false }, { name: 'Woo', age: 30, verified: true }]))
|
|
285
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
286
|
+
completion.stepIn()
|
|
283
287
|
})
|
|
284
|
-
|
|
285
288
|
fastify.inject({ method: 'GET', url: '/' }, (err, res) => {
|
|
286
|
-
t.
|
|
287
|
-
t.
|
|
288
|
-
t.
|
|
289
|
+
t.assert.ifError(err)
|
|
290
|
+
t.assert.strictEqual(res.payload, JSON.stringify([{ type: 'student', grade: 6 }, { type: 'student', grade: 9 }]))
|
|
291
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
292
|
+
completion.stepIn()
|
|
289
293
|
})
|
|
290
|
-
|
|
291
294
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v2+json' } }, (err, res) => {
|
|
292
|
-
t.
|
|
293
|
-
t.
|
|
294
|
-
t.
|
|
295
|
+
t.assert.ifError(err)
|
|
296
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ fullName: 'Jhon Smith', phone: '01090000000' }))
|
|
297
|
+
t.assert.strictEqual(res.statusCode, 300)
|
|
298
|
+
completion.stepIn()
|
|
295
299
|
})
|
|
296
|
-
|
|
297
300
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v3+json' } }, (err, res) => {
|
|
298
|
-
t.
|
|
299
|
-
t.
|
|
300
|
-
t.
|
|
301
|
+
t.assert.ifError(err)
|
|
302
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ firstName: 'New', lastName: 'Hoo', country: 'eg', city: 'node' }))
|
|
303
|
+
t.assert.strictEqual(res.statusCode, 300)
|
|
304
|
+
completion.stepIn()
|
|
301
305
|
})
|
|
302
|
-
|
|
303
306
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v4+json' } }, (err, res) => {
|
|
304
|
-
t.
|
|
305
|
-
t.
|
|
306
|
-
t.
|
|
307
|
+
t.assert.ifError(err)
|
|
308
|
+
t.assert.strictEqual(res.payload, '"[object Object]"')
|
|
309
|
+
t.assert.strictEqual(res.statusCode, 201)
|
|
310
|
+
completion.stepIn()
|
|
307
311
|
})
|
|
308
|
-
|
|
309
312
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v5+json' } }, (err, res) => {
|
|
310
|
-
t.
|
|
311
|
-
t.
|
|
312
|
-
t.
|
|
313
|
+
t.assert.ifError(err)
|
|
314
|
+
t.assert.strictEqual(res.payload, '"Processing exclusive content"')
|
|
315
|
+
t.assert.strictEqual(res.statusCode, 202)
|
|
316
|
+
completion.stepIn()
|
|
313
317
|
})
|
|
314
|
-
|
|
315
318
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v6+json' } }, (err, res) => {
|
|
316
|
-
t.
|
|
317
|
-
t.
|
|
318
|
-
t.
|
|
319
|
+
t.assert.ifError(err)
|
|
320
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ details: 'validation error' }))
|
|
321
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
322
|
+
completion.stepIn()
|
|
319
323
|
})
|
|
320
|
-
|
|
321
324
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v7+json' } }, (err, res) => {
|
|
322
|
-
t.
|
|
323
|
-
t.
|
|
324
|
-
t.
|
|
325
|
+
t.assert.ifError(err)
|
|
326
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ details: 'validation error' }))
|
|
327
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
328
|
+
completion.stepIn()
|
|
325
329
|
})
|
|
326
|
-
|
|
327
330
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v8+json' } }, (err, res) => {
|
|
328
|
-
t.
|
|
329
|
-
t.
|
|
330
|
-
t.
|
|
331
|
+
t.assert.ifError(err)
|
|
332
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ desc: 'age is missing', details: 'validation error' }))
|
|
333
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
334
|
+
completion.stepIn()
|
|
331
335
|
})
|
|
332
|
-
|
|
333
336
|
fastify.inject({ method: 'GET', url: '/', headers: { Accept: 'application/vnd.v9+json' } }, (err, res) => {
|
|
334
|
-
t.
|
|
335
|
-
t.
|
|
336
|
-
t.
|
|
337
|
+
t.assert.ifError(err)
|
|
338
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ details: 'validation error' }))
|
|
339
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
340
|
+
completion.stepIn()
|
|
337
341
|
})
|
|
338
|
-
|
|
339
342
|
fastify.inject({ method: 'GET', url: '/test', headers: { Code: '200' } }, (err, res) => {
|
|
340
|
-
t.
|
|
341
|
-
t.
|
|
342
|
-
t.
|
|
343
|
+
t.assert.ifError(err)
|
|
344
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ age: 18, city: 'AU' }))
|
|
345
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
346
|
+
completion.stepIn()
|
|
343
347
|
})
|
|
344
|
-
|
|
345
348
|
fastify.inject({ method: 'GET', url: '/test', headers: { Code: '201' } }, (err, res) => {
|
|
346
|
-
t.
|
|
347
|
-
t.
|
|
348
|
-
t.
|
|
349
|
+
t.assert.ifError(err)
|
|
350
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ details: 'validation error' }))
|
|
351
|
+
t.assert.strictEqual(res.statusCode, 201)
|
|
352
|
+
completion.stepIn()
|
|
349
353
|
})
|
|
350
|
-
|
|
351
354
|
fastify.inject({ method: 'GET', url: '/test', headers: { Accept: 'application/vnd.v1+json' } }, (err, res) => {
|
|
352
|
-
t.
|
|
353
|
-
t.
|
|
354
|
-
t.
|
|
355
|
+
t.assert.ifError(err)
|
|
356
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ created: true }))
|
|
357
|
+
t.assert.strictEqual(res.statusCode, 201)
|
|
358
|
+
completion.stepIn()
|
|
355
359
|
})
|
|
360
|
+
|
|
361
|
+
completion.patience.then(testDone)
|
|
356
362
|
})
|
|
357
363
|
|
|
358
|
-
test('Invalid multiple content schema, throw FST_ERR_SCH_CONTENT_MISSING_SCHEMA error', t => {
|
|
364
|
+
test('Invalid multiple content schema, throw FST_ERR_SCH_CONTENT_MISSING_SCHEMA error', (t, testDone) => {
|
|
359
365
|
t.plan(3)
|
|
360
366
|
const fastify = Fastify()
|
|
361
367
|
|
|
@@ -388,13 +394,14 @@ test('Invalid multiple content schema, throw FST_ERR_SCH_CONTENT_MISSING_SCHEMA
|
|
|
388
394
|
})
|
|
389
395
|
|
|
390
396
|
fastify.ready((err) => {
|
|
391
|
-
t.
|
|
392
|
-
t.
|
|
393
|
-
t.
|
|
397
|
+
t.assert.strictEqual(err.message, "Schema is missing for the content type 'type'")
|
|
398
|
+
t.assert.strictEqual(err.statusCode, 500)
|
|
399
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_CONTENT_MISSING_SCHEMA')
|
|
400
|
+
testDone()
|
|
394
401
|
})
|
|
395
402
|
})
|
|
396
403
|
|
|
397
|
-
test('Use the same schema id in different places', t => {
|
|
404
|
+
test('Use the same schema id in different places', (t, testDone) => {
|
|
398
405
|
t.plan(2)
|
|
399
406
|
const fastify = Fastify()
|
|
400
407
|
|
|
@@ -424,12 +431,13 @@ test('Use the same schema id in different places', t => {
|
|
|
424
431
|
method: 'GET',
|
|
425
432
|
url: '/123'
|
|
426
433
|
}, (err, res) => {
|
|
427
|
-
t.
|
|
428
|
-
t.
|
|
434
|
+
t.assert.ifError(err)
|
|
435
|
+
t.assert.deepStrictEqual(res.json(), [{ id: 1 }, { id: 2 }, {}])
|
|
436
|
+
testDone()
|
|
429
437
|
})
|
|
430
438
|
})
|
|
431
439
|
|
|
432
|
-
test('Use shared schema and $ref with $id in response ($ref to $id)', t => {
|
|
440
|
+
test('Use shared schema and $ref with $id in response ($ref to $id)', (t, testDone) => {
|
|
433
441
|
t.plan(5)
|
|
434
442
|
const fastify = Fastify()
|
|
435
443
|
|
|
@@ -479,32 +487,36 @@ test('Use shared schema and $ref with $id in response ($ref to $id)', t => {
|
|
|
479
487
|
test: { id: Date.now() }
|
|
480
488
|
}
|
|
481
489
|
|
|
490
|
+
const completion = waitForCb({ steps: 2 })
|
|
482
491
|
fastify.inject({
|
|
483
492
|
method: 'POST',
|
|
484
493
|
url: '/',
|
|
485
494
|
payload
|
|
486
495
|
}, (err, res) => {
|
|
487
|
-
t.
|
|
488
|
-
t.
|
|
496
|
+
t.assert.ifError(err)
|
|
497
|
+
t.assert.deepStrictEqual(res.json(), payload)
|
|
498
|
+
completion.stepIn()
|
|
489
499
|
})
|
|
490
|
-
|
|
491
500
|
fastify.inject({
|
|
492
501
|
method: 'POST',
|
|
493
502
|
url: '/',
|
|
494
503
|
payload: { test: { id: Date.now() } }
|
|
495
504
|
}, (err, res) => {
|
|
496
|
-
t.
|
|
497
|
-
t.
|
|
498
|
-
t.
|
|
505
|
+
t.assert.ifError(err)
|
|
506
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
507
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
499
508
|
error: 'Bad Request',
|
|
500
509
|
message: "body must have required property 'address'",
|
|
501
510
|
statusCode: 400,
|
|
502
511
|
code: 'FST_ERR_VALIDATION'
|
|
503
512
|
})
|
|
513
|
+
completion.stepIn()
|
|
504
514
|
})
|
|
515
|
+
|
|
516
|
+
completion.patience.then(testDone)
|
|
505
517
|
})
|
|
506
518
|
|
|
507
|
-
test('Shared schema should be pass to serializer and validator ($ref to shared schema /definitions)', t => {
|
|
519
|
+
test('Shared schema should be pass to serializer and validator ($ref to shared schema /definitions)', (t, testDone) => {
|
|
508
520
|
t.plan(5)
|
|
509
521
|
const fastify = Fastify()
|
|
510
522
|
|
|
@@ -592,8 +604,8 @@ test('Shared schema should be pass to serializer and validator ($ref to shared s
|
|
|
592
604
|
url: '/',
|
|
593
605
|
payload: locations
|
|
594
606
|
}, (err, res) => {
|
|
595
|
-
t.
|
|
596
|
-
t.
|
|
607
|
+
t.assert.ifError(err)
|
|
608
|
+
t.assert.deepStrictEqual(res.json(), locations)
|
|
597
609
|
|
|
598
610
|
fastify.inject({
|
|
599
611
|
method: 'POST',
|
|
@@ -603,19 +615,20 @@ test('Shared schema should be pass to serializer and validator ($ref to shared s
|
|
|
603
615
|
return _
|
|
604
616
|
})
|
|
605
617
|
}, (err, res) => {
|
|
606
|
-
t.
|
|
607
|
-
t.
|
|
608
|
-
t.
|
|
618
|
+
t.assert.ifError(err)
|
|
619
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
620
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
609
621
|
error: 'Bad Request',
|
|
610
622
|
message: 'body/0/location/email must match format "email"',
|
|
611
623
|
statusCode: 400,
|
|
612
624
|
code: 'FST_ERR_VALIDATION'
|
|
613
625
|
})
|
|
626
|
+
testDone()
|
|
614
627
|
})
|
|
615
628
|
})
|
|
616
629
|
})
|
|
617
630
|
|
|
618
|
-
test('Custom setSerializerCompiler', t => {
|
|
631
|
+
test('Custom setSerializerCompiler', (t, testDone) => {
|
|
619
632
|
t.plan(7)
|
|
620
633
|
const fastify = Fastify({ exposeHeadRoutes: false })
|
|
621
634
|
|
|
@@ -626,10 +639,10 @@ test('Custom setSerializerCompiler', t => {
|
|
|
626
639
|
}
|
|
627
640
|
|
|
628
641
|
fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
|
|
629
|
-
t.
|
|
630
|
-
t.
|
|
631
|
-
t.
|
|
632
|
-
t.
|
|
642
|
+
t.assert.strictEqual(method, 'GET')
|
|
643
|
+
t.assert.strictEqual(url, '/foo/:id')
|
|
644
|
+
t.assert.strictEqual(httpStatus, '200')
|
|
645
|
+
t.assert.deepStrictEqual(schema, outSchema)
|
|
633
646
|
return data => JSON.stringify(data)
|
|
634
647
|
})
|
|
635
648
|
|
|
@@ -644,7 +657,7 @@ test('Custom setSerializerCompiler', t => {
|
|
|
644
657
|
}
|
|
645
658
|
}
|
|
646
659
|
})
|
|
647
|
-
t.ok(instance.serializerCompiler, 'the serializer is set by the parent')
|
|
660
|
+
t.assert.ok(instance.serializerCompiler, 'the serializer is set by the parent')
|
|
648
661
|
done()
|
|
649
662
|
}, { prefix: '/foo' })
|
|
650
663
|
|
|
@@ -652,12 +665,13 @@ test('Custom setSerializerCompiler', t => {
|
|
|
652
665
|
method: 'GET',
|
|
653
666
|
url: '/foo/123'
|
|
654
667
|
}, (err, res) => {
|
|
655
|
-
t.
|
|
656
|
-
t.
|
|
668
|
+
t.assert.ifError(err)
|
|
669
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ id: 1 }))
|
|
670
|
+
testDone()
|
|
657
671
|
})
|
|
658
672
|
})
|
|
659
673
|
|
|
660
|
-
test('Custom setSerializerCompiler returns bad serialized output', t => {
|
|
674
|
+
test('Custom setSerializerCompiler returns bad serialized output', (t, testDone) => {
|
|
661
675
|
t.plan(4)
|
|
662
676
|
const fastify = Fastify()
|
|
663
677
|
|
|
@@ -669,7 +683,7 @@ test('Custom setSerializerCompiler returns bad serialized output', t => {
|
|
|
669
683
|
|
|
670
684
|
fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
|
|
671
685
|
return data => {
|
|
672
|
-
t.
|
|
686
|
+
t.assert.ok('returning an invalid serialization')
|
|
673
687
|
return { not: 'a string' }
|
|
674
688
|
}
|
|
675
689
|
})
|
|
@@ -687,17 +701,18 @@ test('Custom setSerializerCompiler returns bad serialized output', t => {
|
|
|
687
701
|
method: 'GET',
|
|
688
702
|
url: '/123'
|
|
689
703
|
}, (err, res) => {
|
|
690
|
-
t.
|
|
691
|
-
t.
|
|
692
|
-
t.
|
|
704
|
+
t.assert.ifError(err)
|
|
705
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
706
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
693
707
|
code: 'FST_ERR_REP_INVALID_PAYLOAD_TYPE',
|
|
694
708
|
message: 'Attempted to send payload of invalid type \'object\'. Expected a string or Buffer.',
|
|
695
709
|
statusCode: 500
|
|
696
710
|
})
|
|
711
|
+
testDone()
|
|
697
712
|
})
|
|
698
713
|
})
|
|
699
714
|
|
|
700
|
-
test('Custom setSerializerCompiler with addSchema', t => {
|
|
715
|
+
test('Custom setSerializerCompiler with addSchema', (t, testDone) => {
|
|
701
716
|
t.plan(6)
|
|
702
717
|
const fastify = Fastify({ exposeHeadRoutes: false })
|
|
703
718
|
|
|
@@ -708,10 +723,10 @@ test('Custom setSerializerCompiler with addSchema', t => {
|
|
|
708
723
|
}
|
|
709
724
|
|
|
710
725
|
fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
|
|
711
|
-
t.
|
|
712
|
-
t.
|
|
713
|
-
t.
|
|
714
|
-
t.
|
|
726
|
+
t.assert.strictEqual(method, 'GET')
|
|
727
|
+
t.assert.strictEqual(url, '/foo/:id')
|
|
728
|
+
t.assert.strictEqual(httpStatus, '200')
|
|
729
|
+
t.assert.deepStrictEqual(schema, outSchema)
|
|
715
730
|
return _data => JSON.stringify({ id: 2 })
|
|
716
731
|
})
|
|
717
732
|
|
|
@@ -733,8 +748,9 @@ test('Custom setSerializerCompiler with addSchema', t => {
|
|
|
733
748
|
method: 'GET',
|
|
734
749
|
url: '/foo/123'
|
|
735
750
|
}, (err, res) => {
|
|
736
|
-
t.
|
|
737
|
-
t.
|
|
751
|
+
t.assert.ifError(err)
|
|
752
|
+
t.assert.strictEqual(res.payload, JSON.stringify({ id: 2 }))
|
|
753
|
+
testDone()
|
|
738
754
|
})
|
|
739
755
|
})
|
|
740
756
|
|
|
@@ -777,23 +793,23 @@ test('Custom serializer per route', async t => {
|
|
|
777
793
|
})
|
|
778
794
|
|
|
779
795
|
let res = await fastify.inject('/default')
|
|
780
|
-
t.
|
|
796
|
+
t.assert.strictEqual(res.json().mean, 'default')
|
|
781
797
|
|
|
782
798
|
res = await fastify.inject('/custom')
|
|
783
|
-
t.
|
|
799
|
+
t.assert.strictEqual(res.json().mean, 'custom')
|
|
784
800
|
|
|
785
801
|
res = await fastify.inject('/route')
|
|
786
|
-
t.
|
|
802
|
+
t.assert.strictEqual(res.json().mean, 'route')
|
|
787
803
|
|
|
788
|
-
t.
|
|
804
|
+
t.assert.strictEqual(hit, 4, 'the custom and route serializer has been called')
|
|
789
805
|
})
|
|
790
806
|
|
|
791
|
-
test('Reply serializer win over serializer ', t => {
|
|
807
|
+
test('Reply serializer win over serializer ', (t, testDone) => {
|
|
792
808
|
t.plan(6)
|
|
793
809
|
|
|
794
810
|
const fastify = Fastify()
|
|
795
811
|
fastify.setReplySerializer(function (payload, statusCode) {
|
|
796
|
-
t.
|
|
812
|
+
t.assert.deepStrictEqual(payload, { name: 'Foo', work: 'Bar', nick: 'Boo' })
|
|
797
813
|
return 'instance serializator'
|
|
798
814
|
})
|
|
799
815
|
|
|
@@ -810,9 +826,9 @@ test('Reply serializer win over serializer ', t => {
|
|
|
810
826
|
}
|
|
811
827
|
},
|
|
812
828
|
serializerCompiler: ({ schema, method, url, httpPart }) => {
|
|
813
|
-
t.ok(method, 'the custom compiler has been created')
|
|
829
|
+
t.assert.ok(method, 'the custom compiler has been created')
|
|
814
830
|
return () => {
|
|
815
|
-
t.fail('the serializer must not be called when there is a reply serializer')
|
|
831
|
+
t.assert.fail('the serializer must not be called when there is a reply serializer')
|
|
816
832
|
return 'fail'
|
|
817
833
|
}
|
|
818
834
|
}
|
|
@@ -821,18 +837,19 @@ test('Reply serializer win over serializer ', t => {
|
|
|
821
837
|
})
|
|
822
838
|
|
|
823
839
|
fastify.inject('/', (err, res) => {
|
|
824
|
-
t.
|
|
825
|
-
t.
|
|
826
|
-
t.
|
|
840
|
+
t.assert.ifError(err)
|
|
841
|
+
t.assert.deepStrictEqual(res.payload, 'instance serializator')
|
|
842
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
843
|
+
testDone()
|
|
827
844
|
})
|
|
828
845
|
})
|
|
829
846
|
|
|
830
|
-
test('Reply serializer win over serializer ', t => {
|
|
847
|
+
test('Reply serializer win over serializer ', (t, testDone) => {
|
|
831
848
|
t.plan(6)
|
|
832
849
|
|
|
833
850
|
const fastify = Fastify()
|
|
834
851
|
fastify.setReplySerializer(function (payload, statusCode) {
|
|
835
|
-
t.
|
|
852
|
+
t.assert.deepStrictEqual(payload, { name: 'Foo', work: 'Bar', nick: 'Boo' })
|
|
836
853
|
return 'instance serializator'
|
|
837
854
|
})
|
|
838
855
|
|
|
@@ -849,9 +866,9 @@ test('Reply serializer win over serializer ', t => {
|
|
|
849
866
|
}
|
|
850
867
|
},
|
|
851
868
|
serializerCompiler: ({ schema, method, url, httpPart }) => {
|
|
852
|
-
t.ok(method, 'the custom compiler has been created')
|
|
869
|
+
t.assert.ok(method, 'the custom compiler has been created')
|
|
853
870
|
return () => {
|
|
854
|
-
t.fail('the serializer must not be called when there is a reply serializer')
|
|
871
|
+
t.assert.fail('the serializer must not be called when there is a reply serializer')
|
|
855
872
|
return 'fail'
|
|
856
873
|
}
|
|
857
874
|
}
|
|
@@ -860,13 +877,14 @@ test('Reply serializer win over serializer ', t => {
|
|
|
860
877
|
})
|
|
861
878
|
|
|
862
879
|
fastify.inject('/', (err, res) => {
|
|
863
|
-
t.
|
|
864
|
-
t.
|
|
865
|
-
t.
|
|
880
|
+
t.assert.ifError(err)
|
|
881
|
+
t.assert.deepStrictEqual(res.payload, 'instance serializator')
|
|
882
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
883
|
+
testDone()
|
|
866
884
|
})
|
|
867
885
|
})
|
|
868
886
|
|
|
869
|
-
test('The schema compiler recreate itself if needed', t => {
|
|
887
|
+
test('The schema compiler recreate itself if needed', (t, testDone) => {
|
|
870
888
|
t.plan(1)
|
|
871
889
|
const fastify = Fastify()
|
|
872
890
|
|
|
@@ -896,7 +914,10 @@ test('The schema compiler recreate itself if needed', t => {
|
|
|
896
914
|
done()
|
|
897
915
|
})
|
|
898
916
|
|
|
899
|
-
fastify.ready(err => {
|
|
917
|
+
fastify.ready(err => {
|
|
918
|
+
t.assert.ifError(err)
|
|
919
|
+
testDone()
|
|
920
|
+
})
|
|
900
921
|
})
|
|
901
922
|
|
|
902
923
|
test('The schema changes the default error handler output', async t => {
|
|
@@ -933,12 +954,12 @@ test('The schema changes the default error handler output', async t => {
|
|
|
933
954
|
})
|
|
934
955
|
|
|
935
956
|
let res = await fastify.inject('/501')
|
|
936
|
-
t.
|
|
937
|
-
t.
|
|
957
|
+
t.assert.strictEqual(res.statusCode, 501)
|
|
958
|
+
t.assert.deepStrictEqual(res.json(), { message: '501 message' })
|
|
938
959
|
|
|
939
960
|
res = await fastify.inject('/500')
|
|
940
|
-
t.
|
|
941
|
-
t.
|
|
961
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
962
|
+
t.assert.deepStrictEqual(res.json(), { error: 'Internal Server Error', message: '500 message', customId: 42 })
|
|
942
963
|
})
|
|
943
964
|
|
|
944
965
|
test('do not crash if status code serializer errors', async t => {
|
|
@@ -967,7 +988,7 @@ test('do not crash if status code serializer errors', async t => {
|
|
|
967
988
|
}
|
|
968
989
|
},
|
|
969
990
|
(request, reply) => {
|
|
970
|
-
t.fail('handler, should not be called')
|
|
991
|
+
t.assert.fail('handler, should not be called')
|
|
971
992
|
}
|
|
972
993
|
)
|
|
973
994
|
|
|
@@ -977,8 +998,8 @@ test('do not crash if status code serializer errors', async t => {
|
|
|
977
998
|
notfoo: true
|
|
978
999
|
}
|
|
979
1000
|
})
|
|
980
|
-
t.
|
|
981
|
-
t.
|
|
1001
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
1002
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
982
1003
|
statusCode: 500,
|
|
983
1004
|
code: 'FST_ERR_FAILED_ERROR_SERIALIZATION',
|
|
984
1005
|
message: 'Failed to serialize an error. Error: "customCode" is required!. ' +
|
|
@@ -1009,11 +1030,11 @@ test('custom schema serializer error, empty message', async t => {
|
|
|
1009
1030
|
})
|
|
1010
1031
|
|
|
1011
1032
|
const res = await fastify.inject('/501')
|
|
1012
|
-
t.
|
|
1013
|
-
t.
|
|
1033
|
+
t.assert.strictEqual(res.statusCode, 501)
|
|
1034
|
+
t.assert.deepStrictEqual(res.json(), { message: '' })
|
|
1014
1035
|
})
|
|
1015
1036
|
|
|
1016
|
-
test('error in custom schema serialize compiler, throw FST_ERR_SCH_SERIALIZATION_BUILD error', t => {
|
|
1037
|
+
test('error in custom schema serialize compiler, throw FST_ERR_SCH_SERIALIZATION_BUILD error', (t, testDone) => {
|
|
1017
1038
|
t.plan(3)
|
|
1018
1039
|
|
|
1019
1040
|
const fastify = Fastify()
|
|
@@ -1043,9 +1064,10 @@ test('error in custom schema serialize compiler, throw FST_ERR_SCH_SERIALIZATION
|
|
|
1043
1064
|
})
|
|
1044
1065
|
|
|
1045
1066
|
fastify.ready((err) => {
|
|
1046
|
-
t.
|
|
1047
|
-
t.
|
|
1048
|
-
t.
|
|
1067
|
+
t.assert.strictEqual(err.message, 'Failed building the serialization schema for GET: /, due to error CUSTOM_ERROR')
|
|
1068
|
+
t.assert.strictEqual(err.statusCode, 500)
|
|
1069
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_SERIALIZATION_BUILD')
|
|
1070
|
+
testDone()
|
|
1049
1071
|
})
|
|
1050
1072
|
})
|
|
1051
1073
|
|
|
@@ -1077,20 +1099,19 @@ test('Errors in serializer send to errorHandler', async t => {
|
|
|
1077
1099
|
|
|
1078
1100
|
const res = await fastify.inject('/')
|
|
1079
1101
|
|
|
1080
|
-
t.
|
|
1102
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
1081
1103
|
|
|
1082
|
-
// t.
|
|
1083
|
-
t.
|
|
1104
|
+
// t.assert.deepStrictEqual(savedError, new Error('"name" is required!'));
|
|
1105
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
1084
1106
|
statusCode: 500,
|
|
1085
1107
|
error: 'Internal Server Error',
|
|
1086
1108
|
message: '"name" is required!'
|
|
1087
1109
|
})
|
|
1088
|
-
t.ok(savedError, 'error presents')
|
|
1089
|
-
t.ok(savedError.serialization, 'Serialization sign presents')
|
|
1090
|
-
t.end()
|
|
1110
|
+
t.assert.ok(savedError, 'error presents')
|
|
1111
|
+
t.assert.ok(savedError.serialization, 'Serialization sign presents')
|
|
1091
1112
|
})
|
|
1092
1113
|
|
|
1093
|
-
test('capital X', t => {
|
|
1114
|
+
test('capital X', (t, testDone) => {
|
|
1094
1115
|
t.plan(3)
|
|
1095
1116
|
|
|
1096
1117
|
const fastify = Fastify()
|
|
@@ -1111,13 +1132,14 @@ test('capital X', t => {
|
|
|
1111
1132
|
})
|
|
1112
1133
|
|
|
1113
1134
|
fastify.inject('/', (err, res) => {
|
|
1114
|
-
t.
|
|
1115
|
-
t.
|
|
1116
|
-
t.
|
|
1135
|
+
t.assert.ifError(err)
|
|
1136
|
+
t.assert.deepStrictEqual(res.json(), { name: 'Foo', work: 'Bar' })
|
|
1137
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
1138
|
+
testDone()
|
|
1117
1139
|
})
|
|
1118
1140
|
})
|
|
1119
1141
|
|
|
1120
|
-
test('allow default as status code and used as last fallback', t => {
|
|
1142
|
+
test('allow default as status code and used as last fallback', (t, testDone) => {
|
|
1121
1143
|
t.plan(3)
|
|
1122
1144
|
const fastify = Fastify()
|
|
1123
1145
|
|
|
@@ -1141,8 +1163,9 @@ test('allow default as status code and used as last fallback', t => {
|
|
|
1141
1163
|
})
|
|
1142
1164
|
|
|
1143
1165
|
fastify.inject('/', (err, res) => {
|
|
1144
|
-
t.
|
|
1145
|
-
t.
|
|
1146
|
-
t.
|
|
1166
|
+
t.assert.ifError(err)
|
|
1167
|
+
t.assert.deepStrictEqual(res.json(), { name: 'Foo', work: 'Bar' })
|
|
1168
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
1169
|
+
testDone()
|
|
1147
1170
|
})
|
|
1148
1171
|
})
|