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,11 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
const { request } = require('undici')
|
|
6
6
|
|
|
7
7
|
const AJV = require('ajv')
|
|
8
8
|
const Schema = require('fluent-json-schema')
|
|
9
|
+
const { waitForCb } = require('./toolkit')
|
|
9
10
|
|
|
10
11
|
const customSchemaCompilers = {
|
|
11
12
|
body: new AJV({
|
|
@@ -70,7 +71,7 @@ const schemaArtist = {
|
|
|
70
71
|
required: ['name', 'work']
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
test('Basic validation test', t => {
|
|
74
|
+
test('Basic validation test', (t, testDone) => {
|
|
74
75
|
t.plan(6)
|
|
75
76
|
|
|
76
77
|
const fastify = Fastify()
|
|
@@ -82,6 +83,7 @@ test('Basic validation test', t => {
|
|
|
82
83
|
reply.code(200).send(req.body.name)
|
|
83
84
|
})
|
|
84
85
|
|
|
86
|
+
const completion = waitForCb({ steps: 2 })
|
|
85
87
|
fastify.inject({
|
|
86
88
|
method: 'POST',
|
|
87
89
|
payload: {
|
|
@@ -90,23 +92,25 @@ test('Basic validation test', t => {
|
|
|
90
92
|
},
|
|
91
93
|
url: '/'
|
|
92
94
|
}, (err, res) => {
|
|
93
|
-
t.
|
|
94
|
-
t.
|
|
95
|
-
t.
|
|
95
|
+
t.assert.ifError(err)
|
|
96
|
+
t.assert.deepStrictEqual(res.payload, 'michelangelo')
|
|
97
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
98
|
+
completion.stepIn()
|
|
96
99
|
})
|
|
97
|
-
|
|
98
100
|
fastify.inject({
|
|
99
101
|
method: 'POST',
|
|
100
102
|
payload: { name: 'michelangelo' },
|
|
101
103
|
url: '/'
|
|
102
104
|
}, (err, res) => {
|
|
103
|
-
t.
|
|
104
|
-
t.
|
|
105
|
-
t.
|
|
105
|
+
t.assert.ifError(err)
|
|
106
|
+
t.assert.deepStrictEqual(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: "body must have required property 'work'" })
|
|
107
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
108
|
+
completion.stepIn()
|
|
106
109
|
})
|
|
110
|
+
completion.patience.then(testDone)
|
|
107
111
|
})
|
|
108
112
|
|
|
109
|
-
test('Different schema per content type', t => {
|
|
113
|
+
test('Different schema per content type', (t, testDone) => {
|
|
110
114
|
t.plan(12)
|
|
111
115
|
|
|
112
116
|
const fastify = Fastify()
|
|
@@ -135,6 +139,7 @@ test('Different schema per content type', t => {
|
|
|
135
139
|
return reply.send(req.body)
|
|
136
140
|
})
|
|
137
141
|
|
|
142
|
+
const completion = waitForCb({ steps: 4 })
|
|
138
143
|
fastify.inject({
|
|
139
144
|
url: '/',
|
|
140
145
|
method: 'POST',
|
|
@@ -144,46 +149,48 @@ test('Different schema per content type', t => {
|
|
|
144
149
|
work: 'sculptor, painter, architect and poet'
|
|
145
150
|
}
|
|
146
151
|
}, (err, res) => {
|
|
147
|
-
t.
|
|
148
|
-
t.
|
|
149
|
-
t.
|
|
152
|
+
t.assert.ifError(err)
|
|
153
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload).name, 'michelangelo')
|
|
154
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
155
|
+
completion.stepIn()
|
|
150
156
|
})
|
|
151
|
-
|
|
152
157
|
fastify.inject({
|
|
153
158
|
url: '/',
|
|
154
159
|
method: 'POST',
|
|
155
160
|
headers: { 'Content-Type': 'application/json' },
|
|
156
161
|
body: { name: 'michelangelo' }
|
|
157
162
|
}, (err, res) => {
|
|
158
|
-
t.
|
|
159
|
-
t.
|
|
160
|
-
t.
|
|
163
|
+
t.assert.ifError(err)
|
|
164
|
+
t.assert.deepStrictEqual(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: "body must have required property 'work'" })
|
|
165
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
166
|
+
completion.stepIn()
|
|
161
167
|
})
|
|
162
|
-
|
|
163
168
|
fastify.inject({
|
|
164
169
|
url: '/',
|
|
165
170
|
method: 'POST',
|
|
166
171
|
headers: { 'Content-Type': 'application/octet-stream' },
|
|
167
172
|
body: Buffer.from('AAAAAAAA')
|
|
168
173
|
}, (err, res) => {
|
|
169
|
-
t.
|
|
170
|
-
t.
|
|
171
|
-
t.
|
|
174
|
+
t.assert.ifError(err)
|
|
175
|
+
t.assert.deepStrictEqual(res.payload, 'AAAAAAAA')
|
|
176
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
177
|
+
completion.stepIn()
|
|
172
178
|
})
|
|
173
|
-
|
|
174
179
|
fastify.inject({
|
|
175
180
|
url: '/',
|
|
176
181
|
method: 'POST',
|
|
177
182
|
headers: { 'Content-Type': 'text/plain' },
|
|
178
183
|
body: 'AAAAAAAA'
|
|
179
184
|
}, (err, res) => {
|
|
180
|
-
t.
|
|
181
|
-
t.
|
|
182
|
-
t.
|
|
185
|
+
t.assert.ifError(err)
|
|
186
|
+
t.assert.deepStrictEqual(res.payload, 'AAAAAAAA')
|
|
187
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
188
|
+
completion.stepIn()
|
|
183
189
|
})
|
|
190
|
+
completion.patience.then(testDone)
|
|
184
191
|
})
|
|
185
192
|
|
|
186
|
-
test('Skip validation if no schema for content type', t => {
|
|
193
|
+
test('Skip validation if no schema for content type', (t, testDone) => {
|
|
187
194
|
t.plan(3)
|
|
188
195
|
|
|
189
196
|
const fastify = Fastify()
|
|
@@ -201,20 +208,20 @@ test('Skip validation if no schema for content type', t => {
|
|
|
201
208
|
}, async function (req, reply) {
|
|
202
209
|
return reply.send(req.body)
|
|
203
210
|
})
|
|
204
|
-
|
|
205
211
|
fastify.inject({
|
|
206
212
|
url: '/',
|
|
207
213
|
method: 'POST',
|
|
208
214
|
headers: { 'Content-Type': 'text/plain' },
|
|
209
215
|
body: 'AAAAAAAA'
|
|
210
216
|
}, (err, res) => {
|
|
211
|
-
t.
|
|
212
|
-
t.
|
|
213
|
-
t.
|
|
217
|
+
t.assert.ifError(err)
|
|
218
|
+
t.assert.deepStrictEqual(res.payload, 'AAAAAAAA')
|
|
219
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
220
|
+
testDone()
|
|
214
221
|
})
|
|
215
222
|
})
|
|
216
223
|
|
|
217
|
-
test('Skip validation if no content type schemas', t => {
|
|
224
|
+
test('Skip validation if no content type schemas', (t, testDone) => {
|
|
218
225
|
t.plan(3)
|
|
219
226
|
|
|
220
227
|
const fastify = Fastify()
|
|
@@ -229,20 +236,20 @@ test('Skip validation if no content type schemas', t => {
|
|
|
229
236
|
}, async function (req, reply) {
|
|
230
237
|
return reply.send(req.body)
|
|
231
238
|
})
|
|
232
|
-
|
|
233
239
|
fastify.inject({
|
|
234
240
|
url: '/',
|
|
235
241
|
method: 'POST',
|
|
236
242
|
headers: { 'Content-Type': 'text/plain' },
|
|
237
243
|
body: 'AAAAAAAA'
|
|
238
244
|
}, (err, res) => {
|
|
239
|
-
t.
|
|
240
|
-
t.
|
|
241
|
-
t.
|
|
245
|
+
t.assert.ifError(err)
|
|
246
|
+
t.assert.deepStrictEqual(res.payload, 'AAAAAAAA')
|
|
247
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
248
|
+
testDone()
|
|
242
249
|
})
|
|
243
250
|
})
|
|
244
251
|
|
|
245
|
-
test('External AJV instance', t => {
|
|
252
|
+
test('External AJV instance', (t, testDone) => {
|
|
246
253
|
t.plan(5)
|
|
247
254
|
|
|
248
255
|
const fastify = Fastify()
|
|
@@ -255,7 +262,7 @@ test('External AJV instance', t => {
|
|
|
255
262
|
fastify.addSchema(schemaBRefToA)
|
|
256
263
|
|
|
257
264
|
fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
|
|
258
|
-
t.
|
|
265
|
+
t.assert.ok('custom validator compiler called')
|
|
259
266
|
return ajv.compile(schema)
|
|
260
267
|
})
|
|
261
268
|
|
|
@@ -269,26 +276,29 @@ test('External AJV instance', t => {
|
|
|
269
276
|
}
|
|
270
277
|
})
|
|
271
278
|
|
|
279
|
+
const completion = waitForCb({ steps: 2 })
|
|
272
280
|
fastify.inject({
|
|
273
281
|
method: 'POST',
|
|
274
282
|
url: '/',
|
|
275
283
|
payload: { foo: 42 }
|
|
276
284
|
}, (err, res) => {
|
|
277
|
-
t.
|
|
278
|
-
t.
|
|
285
|
+
t.assert.ifError(err)
|
|
286
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
287
|
+
completion.stepIn()
|
|
279
288
|
})
|
|
280
|
-
|
|
281
289
|
fastify.inject({
|
|
282
290
|
method: 'POST',
|
|
283
291
|
url: '/',
|
|
284
292
|
payload: { foo: 'not a number' }
|
|
285
293
|
}, (err, res) => {
|
|
286
|
-
t.
|
|
287
|
-
t.
|
|
294
|
+
t.assert.ifError(err)
|
|
295
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
296
|
+
completion.stepIn()
|
|
288
297
|
})
|
|
298
|
+
completion.patience.then(testDone)
|
|
289
299
|
})
|
|
290
300
|
|
|
291
|
-
test('Encapsulation', t => {
|
|
301
|
+
test('Encapsulation', (t, testDone) => {
|
|
292
302
|
t.plan(21)
|
|
293
303
|
|
|
294
304
|
const fastify = Fastify()
|
|
@@ -302,7 +312,7 @@ test('Encapsulation', t => {
|
|
|
302
312
|
|
|
303
313
|
fastify.register((instance, opts, done) => {
|
|
304
314
|
const validator = ({ schema, method, url, httpPart }) => {
|
|
305
|
-
t.
|
|
315
|
+
t.assert.ok('custom validator compiler called')
|
|
306
316
|
return ajv.compile(schema)
|
|
307
317
|
}
|
|
308
318
|
instance.setValidatorCompiler(validator)
|
|
@@ -316,7 +326,7 @@ test('Encapsulation', t => {
|
|
|
316
326
|
instance.register((instance, opts, done) => {
|
|
317
327
|
instance.post('/two', {
|
|
318
328
|
handler (req, reply) {
|
|
319
|
-
t.
|
|
329
|
+
t.assert.deepStrictEqual(instance.validatorCompiler, validator)
|
|
320
330
|
reply.send({ foo: 'two' })
|
|
321
331
|
},
|
|
322
332
|
schema: {
|
|
@@ -330,7 +340,7 @@ test('Encapsulation', t => {
|
|
|
330
340
|
instance.post('/three', {
|
|
331
341
|
validatorCompiler: anotherValidator,
|
|
332
342
|
handler (req, reply) {
|
|
333
|
-
t.
|
|
343
|
+
t.assert.deepStrictEqual(instance.validatorCompiler, validator, 'the route validator does not change the instance one')
|
|
334
344
|
reply.send({ foo: 'three' })
|
|
335
345
|
},
|
|
336
346
|
schema: {
|
|
@@ -344,72 +354,75 @@ test('Encapsulation', t => {
|
|
|
344
354
|
|
|
345
355
|
fastify.register((instance, opts, done) => {
|
|
346
356
|
instance.post('/clean', function (req, reply) {
|
|
347
|
-
t.
|
|
357
|
+
t.assert.strictEqual(instance.validatorCompiler, undefined)
|
|
348
358
|
reply.send({ foo: 'bar' })
|
|
349
359
|
})
|
|
350
360
|
done()
|
|
351
361
|
})
|
|
352
362
|
|
|
363
|
+
const completion = waitForCb({ steps: 6 })
|
|
353
364
|
fastify.inject({
|
|
354
365
|
method: 'POST',
|
|
355
366
|
url: '/one',
|
|
356
367
|
payload: { foo: 1 }
|
|
357
368
|
}, (err, res) => {
|
|
358
|
-
t.
|
|
359
|
-
t.
|
|
360
|
-
t.
|
|
369
|
+
t.assert.ifError(err)
|
|
370
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
371
|
+
t.assert.deepStrictEqual(res.json(), { foo: 'one' })
|
|
372
|
+
completion.stepIn()
|
|
361
373
|
})
|
|
362
|
-
|
|
363
374
|
fastify.inject({
|
|
364
375
|
method: 'POST',
|
|
365
376
|
url: '/one',
|
|
366
377
|
payload: { wrongFoo: 'bar' }
|
|
367
378
|
}, (err, res) => {
|
|
368
|
-
t.
|
|
369
|
-
t.
|
|
379
|
+
t.assert.ifError(err)
|
|
380
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
381
|
+
completion.stepIn()
|
|
370
382
|
})
|
|
371
|
-
|
|
372
383
|
fastify.inject({
|
|
373
384
|
method: 'POST',
|
|
374
385
|
url: '/two',
|
|
375
386
|
payload: { foo: 2 }
|
|
376
387
|
}, (err, res) => {
|
|
377
|
-
t.
|
|
378
|
-
t.
|
|
379
|
-
t.
|
|
388
|
+
t.assert.ifError(err)
|
|
389
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
390
|
+
t.assert.deepStrictEqual(res.json(), { foo: 'two' })
|
|
391
|
+
completion.stepIn()
|
|
380
392
|
})
|
|
381
|
-
|
|
382
393
|
fastify.inject({
|
|
383
394
|
method: 'POST',
|
|
384
395
|
url: '/two',
|
|
385
396
|
payload: { wrongFoo: 'bar' }
|
|
386
397
|
}, (err, res) => {
|
|
387
|
-
t.
|
|
388
|
-
t.
|
|
398
|
+
t.assert.ifError(err)
|
|
399
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
400
|
+
completion.stepIn()
|
|
389
401
|
})
|
|
390
|
-
|
|
391
402
|
fastify.inject({
|
|
392
403
|
method: 'POST',
|
|
393
404
|
url: '/three',
|
|
394
405
|
payload: { wrongFoo: 'but works' }
|
|
395
406
|
}, (err, res) => {
|
|
396
|
-
t.
|
|
397
|
-
t.
|
|
398
|
-
t.
|
|
407
|
+
t.assert.ifError(err)
|
|
408
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
409
|
+
t.assert.deepStrictEqual(res.json(), { foo: 'three' })
|
|
410
|
+
completion.stepIn()
|
|
399
411
|
})
|
|
400
|
-
|
|
401
412
|
fastify.inject({
|
|
402
413
|
method: 'POST',
|
|
403
414
|
url: '/clean',
|
|
404
415
|
payload: { wrongFoo: 'bar' }
|
|
405
416
|
}, (err, res) => {
|
|
406
|
-
t.
|
|
407
|
-
t.
|
|
408
|
-
t.
|
|
417
|
+
t.assert.ifError(err)
|
|
418
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
419
|
+
t.assert.deepStrictEqual(res.json(), { foo: 'bar' })
|
|
420
|
+
completion.stepIn()
|
|
409
421
|
})
|
|
422
|
+
completion.patience.then(testDone)
|
|
410
423
|
})
|
|
411
424
|
|
|
412
|
-
test('Triple $ref with a simple $id', t => {
|
|
425
|
+
test('Triple $ref with a simple $id', (t, testDone) => {
|
|
413
426
|
t.plan(7)
|
|
414
427
|
|
|
415
428
|
const fastify = Fastify()
|
|
@@ -424,7 +437,7 @@ test('Triple $ref with a simple $id', t => {
|
|
|
424
437
|
fastify.addSchema(schemaCRefToB)
|
|
425
438
|
|
|
426
439
|
fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
|
|
427
|
-
t.
|
|
440
|
+
t.assert.ok('custom validator compiler called')
|
|
428
441
|
return ajv.compile(schema)
|
|
429
442
|
})
|
|
430
443
|
|
|
@@ -438,28 +451,31 @@ test('Triple $ref with a simple $id', t => {
|
|
|
438
451
|
}
|
|
439
452
|
})
|
|
440
453
|
|
|
454
|
+
const completion = waitForCb({ steps: 2 })
|
|
441
455
|
fastify.inject({
|
|
442
456
|
method: 'POST',
|
|
443
457
|
url: '/',
|
|
444
458
|
payload: { foo: 43 }
|
|
445
459
|
}, (err, res) => {
|
|
446
|
-
t.
|
|
447
|
-
t.
|
|
448
|
-
t.
|
|
460
|
+
t.assert.ifError(err)
|
|
461
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
462
|
+
t.assert.deepStrictEqual(res.json(), { foo: 105 })
|
|
463
|
+
completion.stepIn()
|
|
449
464
|
})
|
|
450
|
-
|
|
451
465
|
fastify.inject({
|
|
452
466
|
method: 'POST',
|
|
453
467
|
url: '/',
|
|
454
468
|
payload: { fool: 'bar' }
|
|
455
469
|
}, (err, res) => {
|
|
456
|
-
t.
|
|
457
|
-
t.
|
|
458
|
-
t.
|
|
470
|
+
t.assert.ifError(err)
|
|
471
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
472
|
+
t.assert.deepStrictEqual(res.json().message, "body must have required property 'foo'")
|
|
473
|
+
completion.stepIn()
|
|
459
474
|
})
|
|
475
|
+
completion.patience.then(testDone)
|
|
460
476
|
})
|
|
461
477
|
|
|
462
|
-
test('Extending schema', t => {
|
|
478
|
+
test('Extending schema', (t, testDone) => {
|
|
463
479
|
t.plan(4)
|
|
464
480
|
const fastify = Fastify()
|
|
465
481
|
|
|
@@ -499,7 +515,6 @@ test('Extending schema', t => {
|
|
|
499
515
|
}
|
|
500
516
|
}
|
|
501
517
|
})
|
|
502
|
-
|
|
503
518
|
fastify.inject({
|
|
504
519
|
method: 'POST',
|
|
505
520
|
url: '/',
|
|
@@ -510,10 +525,9 @@ test('Extending schema', t => {
|
|
|
510
525
|
}
|
|
511
526
|
}
|
|
512
527
|
}, (err, res) => {
|
|
513
|
-
t.
|
|
514
|
-
t.
|
|
528
|
+
t.assert.ifError(err)
|
|
529
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
515
530
|
})
|
|
516
|
-
|
|
517
531
|
fastify.inject({
|
|
518
532
|
method: 'POST',
|
|
519
533
|
url: '/',
|
|
@@ -525,12 +539,13 @@ test('Extending schema', t => {
|
|
|
525
539
|
}
|
|
526
540
|
}
|
|
527
541
|
}, (err, res) => {
|
|
528
|
-
t.
|
|
529
|
-
t.
|
|
542
|
+
t.assert.ifError(err)
|
|
543
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
544
|
+
testDone()
|
|
530
545
|
})
|
|
531
546
|
})
|
|
532
547
|
|
|
533
|
-
test('Should work with nested ids', t => {
|
|
548
|
+
test('Should work with nested ids', (t, testDone) => {
|
|
534
549
|
t.plan(6)
|
|
535
550
|
const fastify = Fastify()
|
|
536
551
|
|
|
@@ -560,6 +575,7 @@ test('Should work with nested ids', t => {
|
|
|
560
575
|
}
|
|
561
576
|
})
|
|
562
577
|
|
|
578
|
+
const completion = waitForCb({ steps: 2 })
|
|
563
579
|
fastify.inject({
|
|
564
580
|
method: 'POST',
|
|
565
581
|
url: '/123',
|
|
@@ -567,11 +583,11 @@ test('Should work with nested ids', t => {
|
|
|
567
583
|
hello: 'world'
|
|
568
584
|
}
|
|
569
585
|
}, (err, res) => {
|
|
570
|
-
t.
|
|
571
|
-
t.
|
|
572
|
-
t.
|
|
586
|
+
t.assert.ifError(err)
|
|
587
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
588
|
+
t.assert.strictEqual(res.payload, 'number')
|
|
589
|
+
completion.stepIn()
|
|
573
590
|
})
|
|
574
|
-
|
|
575
591
|
fastify.inject({
|
|
576
592
|
method: 'POST',
|
|
577
593
|
url: '/abc',
|
|
@@ -579,14 +595,16 @@ test('Should work with nested ids', t => {
|
|
|
579
595
|
hello: 'world'
|
|
580
596
|
}
|
|
581
597
|
}, (err, res) => {
|
|
582
|
-
t.
|
|
583
|
-
t.
|
|
584
|
-
t.
|
|
598
|
+
t.assert.ifError(err)
|
|
599
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
600
|
+
t.assert.strictEqual(res.json().message, 'params/id must be number')
|
|
601
|
+
completion.stepIn()
|
|
585
602
|
})
|
|
603
|
+
completion.patience.then(testDone)
|
|
586
604
|
})
|
|
587
605
|
|
|
588
|
-
test('Use the same schema across multiple routes', t => {
|
|
589
|
-
t.plan(
|
|
606
|
+
test('Use the same schema across multiple routes', async (t) => {
|
|
607
|
+
t.plan(4)
|
|
590
608
|
const fastify = Fastify()
|
|
591
609
|
|
|
592
610
|
fastify.addSchema({
|
|
@@ -611,34 +629,35 @@ test('Use the same schema across multiple routes', t => {
|
|
|
611
629
|
}
|
|
612
630
|
})
|
|
613
631
|
|
|
614
|
-
|
|
632
|
+
const validTestCases = [
|
|
615
633
|
'/first/123',
|
|
616
634
|
'/second/123'
|
|
617
|
-
]
|
|
618
|
-
|
|
635
|
+
]
|
|
636
|
+
|
|
637
|
+
for (const url of validTestCases) {
|
|
638
|
+
const res = await fastify.inject({
|
|
619
639
|
url,
|
|
620
640
|
method: 'GET'
|
|
621
|
-
}, (err, res) => {
|
|
622
|
-
t.error(err)
|
|
623
|
-
t.equal(res.payload, 'number')
|
|
624
641
|
})
|
|
625
|
-
})
|
|
626
642
|
|
|
627
|
-
|
|
643
|
+
t.assert.strictEqual(res.payload, 'number')
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const invalidTestCases = [
|
|
628
647
|
'/first/abc',
|
|
629
648
|
'/second/abc'
|
|
630
|
-
]
|
|
631
|
-
|
|
649
|
+
]
|
|
650
|
+
|
|
651
|
+
for (const url of invalidTestCases) {
|
|
652
|
+
const res = await fastify.inject({
|
|
632
653
|
url,
|
|
633
654
|
method: 'GET'
|
|
634
|
-
}, (err, res) => {
|
|
635
|
-
t.error(err)
|
|
636
|
-
t.equal(res.statusCode, 400)
|
|
637
655
|
})
|
|
638
|
-
|
|
656
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
657
|
+
}
|
|
639
658
|
})
|
|
640
659
|
|
|
641
|
-
test('JSON Schema validation keywords', t => {
|
|
660
|
+
test('JSON Schema validation keywords', (t, testDone) => {
|
|
642
661
|
t.plan(6)
|
|
643
662
|
const fastify = Fastify()
|
|
644
663
|
|
|
@@ -660,31 +679,34 @@ test('JSON Schema validation keywords', t => {
|
|
|
660
679
|
}
|
|
661
680
|
})
|
|
662
681
|
|
|
682
|
+
const completion = waitForCb({ steps: 2 })
|
|
663
683
|
fastify.inject({
|
|
664
684
|
method: 'GET',
|
|
665
685
|
url: '/127.0.0.1'
|
|
666
686
|
}, (err, res) => {
|
|
667
|
-
t.
|
|
668
|
-
t.
|
|
669
|
-
t.
|
|
687
|
+
t.assert.ifError(err)
|
|
688
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
689
|
+
t.assert.strictEqual(res.payload, 'string')
|
|
690
|
+
completion.stepIn()
|
|
670
691
|
})
|
|
671
|
-
|
|
672
692
|
fastify.inject({
|
|
673
693
|
method: 'GET',
|
|
674
694
|
url: '/localhost'
|
|
675
695
|
}, (err, res) => {
|
|
676
|
-
t.
|
|
677
|
-
t.
|
|
678
|
-
t.
|
|
696
|
+
t.assert.ifError(err)
|
|
697
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
698
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
679
699
|
statusCode: 400,
|
|
680
700
|
code: 'FST_ERR_VALIDATION',
|
|
681
701
|
error: 'Bad Request',
|
|
682
702
|
message: 'params/ip must match format "ipv4"'
|
|
683
703
|
})
|
|
704
|
+
completion.stepIn()
|
|
684
705
|
})
|
|
706
|
+
completion.patience.then(testDone)
|
|
685
707
|
})
|
|
686
708
|
|
|
687
|
-
test('Nested id calls', t => {
|
|
709
|
+
test('Nested id calls', (t, testDone) => {
|
|
688
710
|
t.plan(6)
|
|
689
711
|
const fastify = Fastify()
|
|
690
712
|
|
|
@@ -714,33 +736,36 @@ test('Nested id calls', t => {
|
|
|
714
736
|
}
|
|
715
737
|
})
|
|
716
738
|
|
|
739
|
+
const completion = waitForCb({ steps: 2 })
|
|
717
740
|
fastify.inject({
|
|
718
741
|
method: 'POST',
|
|
719
742
|
url: '/',
|
|
720
743
|
payload: { host: { ip: '127.0.0.1' } }
|
|
721
744
|
}, (err, res) => {
|
|
722
|
-
t.
|
|
723
|
-
t.
|
|
724
|
-
t.
|
|
745
|
+
t.assert.ifError(err)
|
|
746
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
747
|
+
t.assert.strictEqual(res.payload, 'string')
|
|
748
|
+
completion.stepIn()
|
|
725
749
|
})
|
|
726
|
-
|
|
727
750
|
fastify.inject({
|
|
728
751
|
method: 'POST',
|
|
729
752
|
url: '/',
|
|
730
753
|
payload: { host: { ip: 'localhost' } }
|
|
731
754
|
}, (err, res) => {
|
|
732
|
-
t.
|
|
733
|
-
t.
|
|
734
|
-
t.
|
|
755
|
+
t.assert.ifError(err)
|
|
756
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
757
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
735
758
|
error: 'Bad Request',
|
|
736
759
|
message: 'body/host/ip must match format "ipv4"',
|
|
737
760
|
statusCode: 400,
|
|
738
761
|
code: 'FST_ERR_VALIDATION'
|
|
739
762
|
})
|
|
763
|
+
completion.stepIn()
|
|
740
764
|
})
|
|
765
|
+
completion.patience.then(testDone)
|
|
741
766
|
})
|
|
742
767
|
|
|
743
|
-
test('Use the same schema id in different places', t => {
|
|
768
|
+
test('Use the same schema id in different places', (t, testDone) => {
|
|
744
769
|
t.plan(2)
|
|
745
770
|
const fastify = Fastify()
|
|
746
771
|
|
|
@@ -761,18 +786,18 @@ test('Use the same schema id in different places', t => {
|
|
|
761
786
|
}
|
|
762
787
|
}
|
|
763
788
|
})
|
|
764
|
-
|
|
765
789
|
fastify.inject({
|
|
766
790
|
method: 'POST',
|
|
767
791
|
url: '/',
|
|
768
792
|
payload: { id: 42 }
|
|
769
793
|
}, (err, res) => {
|
|
770
|
-
t.
|
|
771
|
-
t.
|
|
794
|
+
t.assert.ifError(err)
|
|
795
|
+
t.assert.deepStrictEqual(res.json(), { id: 21 })
|
|
796
|
+
testDone()
|
|
772
797
|
})
|
|
773
798
|
})
|
|
774
799
|
|
|
775
|
-
test('Use shared schema and $ref with $id ($ref to $id)', t => {
|
|
800
|
+
test('Use shared schema and $ref with $id ($ref to $id)', (t, testDone) => {
|
|
776
801
|
t.plan(5)
|
|
777
802
|
const fastify = Fastify()
|
|
778
803
|
|
|
@@ -815,6 +840,7 @@ test('Use shared schema and $ref with $id ($ref to $id)', t => {
|
|
|
815
840
|
})
|
|
816
841
|
|
|
817
842
|
const id = Date.now()
|
|
843
|
+
const completion = waitForCb({ steps: 2 })
|
|
818
844
|
fastify.inject({
|
|
819
845
|
method: 'POST',
|
|
820
846
|
url: '/',
|
|
@@ -823,27 +849,29 @@ test('Use shared schema and $ref with $id ($ref to $id)', t => {
|
|
|
823
849
|
test: { id }
|
|
824
850
|
}
|
|
825
851
|
}, (err, res) => {
|
|
826
|
-
t.
|
|
827
|
-
t.
|
|
852
|
+
t.assert.ifError(err)
|
|
853
|
+
t.assert.deepStrictEqual(res.json(), { id })
|
|
854
|
+
completion.stepIn()
|
|
828
855
|
})
|
|
829
|
-
|
|
830
856
|
fastify.inject({
|
|
831
857
|
method: 'POST',
|
|
832
858
|
url: '/',
|
|
833
859
|
payload: { test: { id } }
|
|
834
860
|
}, (err, res) => {
|
|
835
|
-
t.
|
|
836
|
-
t.
|
|
837
|
-
t.
|
|
861
|
+
t.assert.ifError(err)
|
|
862
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
863
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
838
864
|
error: 'Bad Request',
|
|
839
865
|
message: "body must have required property 'address'",
|
|
840
866
|
statusCode: 400,
|
|
841
867
|
code: 'FST_ERR_VALIDATION'
|
|
842
868
|
})
|
|
869
|
+
completion.stepIn()
|
|
843
870
|
})
|
|
871
|
+
completion.patience.then(testDone)
|
|
844
872
|
})
|
|
845
873
|
|
|
846
|
-
test('Use items with $ref', t => {
|
|
874
|
+
test('Use items with $ref', (t, testDone) => {
|
|
847
875
|
t.plan(4)
|
|
848
876
|
const fastify = Fastify()
|
|
849
877
|
|
|
@@ -865,26 +893,29 @@ test('Use items with $ref', t => {
|
|
|
865
893
|
handler: (_, r) => { r.send('ok') }
|
|
866
894
|
})
|
|
867
895
|
|
|
896
|
+
const completion = waitForCb({ steps: 2 })
|
|
868
897
|
fastify.inject({
|
|
869
898
|
method: 'POST',
|
|
870
899
|
url: '/',
|
|
871
900
|
payload: [{ hello: 'world' }]
|
|
872
901
|
}, (err, res) => {
|
|
873
|
-
t.
|
|
874
|
-
t.
|
|
902
|
+
t.assert.ifError(err)
|
|
903
|
+
t.assert.strictEqual(res.payload, 'ok')
|
|
904
|
+
completion.stepIn()
|
|
875
905
|
})
|
|
876
|
-
|
|
877
906
|
fastify.inject({
|
|
878
907
|
method: 'POST',
|
|
879
908
|
url: '/',
|
|
880
909
|
payload: { hello: 'world' }
|
|
881
910
|
}, (err, res) => {
|
|
882
|
-
t.
|
|
883
|
-
t.
|
|
911
|
+
t.assert.ifError(err)
|
|
912
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
913
|
+
completion.stepIn()
|
|
884
914
|
})
|
|
915
|
+
completion.patience.then(testDone)
|
|
885
916
|
})
|
|
886
917
|
|
|
887
|
-
test('Use $ref to /definitions', t => {
|
|
918
|
+
test('Use $ref to /definitions', (t, testDone) => {
|
|
888
919
|
t.plan(6)
|
|
889
920
|
const fastify = Fastify()
|
|
890
921
|
|
|
@@ -931,16 +962,17 @@ test('Use $ref to /definitions', t => {
|
|
|
931
962
|
address: { city: 'New Node' },
|
|
932
963
|
test: { id: Date.now() }
|
|
933
964
|
}
|
|
965
|
+
const completion = waitForCb({ steps: 2 })
|
|
934
966
|
fastify.inject({
|
|
935
967
|
method: 'POST',
|
|
936
968
|
url: '/',
|
|
937
969
|
payload
|
|
938
970
|
}, (err, res) => {
|
|
939
|
-
t.
|
|
940
|
-
t.
|
|
941
|
-
t.
|
|
971
|
+
t.assert.ifError(err)
|
|
972
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
973
|
+
t.assert.deepStrictEqual(res.json(), payload)
|
|
974
|
+
completion.stepIn()
|
|
942
975
|
})
|
|
943
|
-
|
|
944
976
|
fastify.inject({
|
|
945
977
|
method: 'POST',
|
|
946
978
|
url: '/',
|
|
@@ -949,18 +981,20 @@ test('Use $ref to /definitions', t => {
|
|
|
949
981
|
test: { id: 'wrong' }
|
|
950
982
|
}
|
|
951
983
|
}, (err, res) => {
|
|
952
|
-
t.
|
|
953
|
-
t.
|
|
954
|
-
t.
|
|
984
|
+
t.assert.ifError(err)
|
|
985
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
986
|
+
t.assert.deepStrictEqual(res.json(), {
|
|
955
987
|
error: 'Bad Request',
|
|
956
988
|
message: 'body/test/id must be number',
|
|
957
989
|
statusCode: 400,
|
|
958
990
|
code: 'FST_ERR_VALIDATION'
|
|
959
991
|
})
|
|
992
|
+
completion.stepIn()
|
|
960
993
|
})
|
|
994
|
+
completion.patience.then(testDone)
|
|
961
995
|
})
|
|
962
996
|
|
|
963
|
-
test('Custom AJV settings - pt1', t => {
|
|
997
|
+
test('Custom AJV settings - pt1', (t, testDone) => {
|
|
964
998
|
t.plan(4)
|
|
965
999
|
const fastify = Fastify()
|
|
966
1000
|
|
|
@@ -974,11 +1008,10 @@ test('Custom AJV settings - pt1', t => {
|
|
|
974
1008
|
}
|
|
975
1009
|
},
|
|
976
1010
|
handler: (req, reply) => {
|
|
977
|
-
t.
|
|
1011
|
+
t.assert.strictEqual(req.body.num, 12)
|
|
978
1012
|
reply.send(req.body)
|
|
979
1013
|
}
|
|
980
1014
|
})
|
|
981
|
-
|
|
982
1015
|
fastify.inject({
|
|
983
1016
|
method: 'POST',
|
|
984
1017
|
url: '/',
|
|
@@ -986,13 +1019,14 @@ test('Custom AJV settings - pt1', t => {
|
|
|
986
1019
|
num: '12'
|
|
987
1020
|
}
|
|
988
1021
|
}, (err, res) => {
|
|
989
|
-
t.
|
|
990
|
-
t.
|
|
991
|
-
t.
|
|
1022
|
+
t.assert.ifError(err)
|
|
1023
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
1024
|
+
t.assert.deepStrictEqual(res.json(), { num: 12 })
|
|
1025
|
+
testDone()
|
|
992
1026
|
})
|
|
993
1027
|
})
|
|
994
1028
|
|
|
995
|
-
test('Custom AJV settings - pt2', t => {
|
|
1029
|
+
test('Custom AJV settings - pt2', (t, testDone) => {
|
|
996
1030
|
t.plan(2)
|
|
997
1031
|
const fastify = Fastify({
|
|
998
1032
|
ajv: {
|
|
@@ -1015,7 +1049,6 @@ test('Custom AJV settings - pt2', t => {
|
|
|
1015
1049
|
t.fail('the handler is not called because the "12" is not coerced to number')
|
|
1016
1050
|
}
|
|
1017
1051
|
})
|
|
1018
|
-
|
|
1019
1052
|
fastify.inject({
|
|
1020
1053
|
method: 'POST',
|
|
1021
1054
|
url: '/',
|
|
@@ -1023,12 +1056,13 @@ test('Custom AJV settings - pt2', t => {
|
|
|
1023
1056
|
num: '12'
|
|
1024
1057
|
}
|
|
1025
1058
|
}, (err, res) => {
|
|
1026
|
-
t.
|
|
1027
|
-
t.
|
|
1059
|
+
t.assert.ifError(err)
|
|
1060
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
1061
|
+
testDone()
|
|
1028
1062
|
})
|
|
1029
1063
|
})
|
|
1030
1064
|
|
|
1031
|
-
test('Custom AJV settings on different parameters - pt1', t => {
|
|
1065
|
+
test('Custom AJV settings on different parameters - pt1', (t, testDone) => {
|
|
1032
1066
|
t.plan(2)
|
|
1033
1067
|
const fastify = Fastify()
|
|
1034
1068
|
|
|
@@ -1054,7 +1088,6 @@ test('Custom AJV settings on different parameters - pt1', t => {
|
|
|
1054
1088
|
t.fail('the handler is not called because the "12" is not coerced to number')
|
|
1055
1089
|
}
|
|
1056
1090
|
})
|
|
1057
|
-
|
|
1058
1091
|
fastify.inject({
|
|
1059
1092
|
method: 'POST',
|
|
1060
1093
|
url: '/api/42',
|
|
@@ -1062,12 +1095,13 @@ test('Custom AJV settings on different parameters - pt1', t => {
|
|
|
1062
1095
|
num: '12'
|
|
1063
1096
|
}
|
|
1064
1097
|
}, (err, res) => {
|
|
1065
|
-
t.
|
|
1066
|
-
t.
|
|
1098
|
+
t.assert.ifError(err)
|
|
1099
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
1100
|
+
testDone()
|
|
1067
1101
|
})
|
|
1068
1102
|
})
|
|
1069
1103
|
|
|
1070
|
-
test('Custom AJV settings on different parameters - pt2', t => {
|
|
1104
|
+
test('Custom AJV settings on different parameters - pt2', (t, testDone) => {
|
|
1071
1105
|
t.plan(4)
|
|
1072
1106
|
const fastify = Fastify()
|
|
1073
1107
|
|
|
@@ -1091,13 +1125,13 @@ test('Custom AJV settings on different parameters - pt2', t => {
|
|
|
1091
1125
|
}
|
|
1092
1126
|
},
|
|
1093
1127
|
handler: (req, reply) => {
|
|
1094
|
-
t.
|
|
1095
|
-
t.
|
|
1096
|
-
t.
|
|
1097
|
-
t.
|
|
1128
|
+
t.assert.deepStrictEqual(typeof req.params.id, 'number')
|
|
1129
|
+
t.assert.deepStrictEqual(typeof req.body.num, 'number')
|
|
1130
|
+
t.assert.deepStrictEqual(req.params.id, 42)
|
|
1131
|
+
t.assert.deepStrictEqual(req.body.num, 12)
|
|
1132
|
+
testDone()
|
|
1098
1133
|
}
|
|
1099
1134
|
})
|
|
1100
|
-
|
|
1101
1135
|
fastify.inject({
|
|
1102
1136
|
method: 'POST',
|
|
1103
1137
|
url: '/api/42',
|
|
@@ -1107,7 +1141,7 @@ test('Custom AJV settings on different parameters - pt2', t => {
|
|
|
1107
1141
|
})
|
|
1108
1142
|
})
|
|
1109
1143
|
|
|
1110
|
-
test("The same $id in route's schema must not overwrite others", t => {
|
|
1144
|
+
test("The same $id in route's schema must not overwrite others", (t, testDone) => {
|
|
1111
1145
|
t.plan(4)
|
|
1112
1146
|
const fastify = Fastify()
|
|
1113
1147
|
|
|
@@ -1158,23 +1192,26 @@ test("The same $id in route's schema must not overwrite others", t => {
|
|
|
1158
1192
|
handler: () => { return 'ok' }
|
|
1159
1193
|
})
|
|
1160
1194
|
|
|
1195
|
+
const completion = waitForCb({ steps: 2 })
|
|
1161
1196
|
fastify.inject({
|
|
1162
1197
|
method: 'POST',
|
|
1163
1198
|
url: '/user',
|
|
1164
1199
|
body: {}
|
|
1165
1200
|
}, (err, res) => {
|
|
1166
|
-
t.
|
|
1167
|
-
t.
|
|
1201
|
+
t.assert.ifError(err)
|
|
1202
|
+
t.assert.deepStrictEqual(res.json().message, "body must have required property 'username'")
|
|
1203
|
+
completion.stepIn()
|
|
1168
1204
|
})
|
|
1169
|
-
|
|
1170
1205
|
fastify.inject({
|
|
1171
1206
|
url: '/user/1',
|
|
1172
1207
|
method: 'PATCH',
|
|
1173
1208
|
body: {}
|
|
1174
1209
|
}, (err, res) => {
|
|
1175
|
-
t.
|
|
1176
|
-
t.
|
|
1210
|
+
t.assert.ifError(err)
|
|
1211
|
+
t.assert.deepStrictEqual(res.payload, 'ok')
|
|
1212
|
+
completion.stepIn()
|
|
1177
1213
|
})
|
|
1214
|
+
completion.patience.then(testDone)
|
|
1178
1215
|
})
|
|
1179
1216
|
|
|
1180
1217
|
test('Custom validator compiler should not mutate schema', async t => {
|
|
@@ -1183,7 +1220,7 @@ test('Custom validator compiler should not mutate schema', async t => {
|
|
|
1183
1220
|
const fastify = Fastify()
|
|
1184
1221
|
|
|
1185
1222
|
fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
|
|
1186
|
-
t.
|
|
1223
|
+
t.assert.ok(schema instanceof Headers)
|
|
1187
1224
|
return () => { }
|
|
1188
1225
|
})
|
|
1189
1226
|
|
|
@@ -1221,8 +1258,8 @@ test('Custom validator builder override by custom validator compiler', async t =
|
|
|
1221
1258
|
}
|
|
1222
1259
|
},
|
|
1223
1260
|
handler: (req, _reply) => {
|
|
1224
|
-
t.
|
|
1225
|
-
t.
|
|
1261
|
+
t.assert.deepStrictEqual(typeof req.params.id, 'number')
|
|
1262
|
+
t.assert.deepStrictEqual(req.params.id, 43)
|
|
1226
1263
|
return 'ok'
|
|
1227
1264
|
}
|
|
1228
1265
|
})
|
|
@@ -1233,7 +1270,7 @@ test('Custom validator builder override by custom validator compiler', async t =
|
|
|
1233
1270
|
method: 'POST',
|
|
1234
1271
|
url: '/two/43'
|
|
1235
1272
|
})
|
|
1236
|
-
t.
|
|
1273
|
+
t.assert.strictEqual(two.statusCode, 200)
|
|
1237
1274
|
})
|
|
1238
1275
|
|
|
1239
1276
|
test('Custom validator builder override by custom validator compiler in child instance', async t => {
|
|
@@ -1261,8 +1298,8 @@ test('Custom validator builder override by custom validator compiler in child in
|
|
|
1261
1298
|
}
|
|
1262
1299
|
},
|
|
1263
1300
|
handler: (req, _reply) => {
|
|
1264
|
-
t.
|
|
1265
|
-
t.
|
|
1301
|
+
t.assert.deepStrictEqual(typeof req.params.id, 'number')
|
|
1302
|
+
t.assert.deepStrictEqual(req.params.id, 43)
|
|
1266
1303
|
return 'ok'
|
|
1267
1304
|
}
|
|
1268
1305
|
})
|
|
@@ -1281,8 +1318,8 @@ test('Custom validator builder override by custom validator compiler in child in
|
|
|
1281
1318
|
}
|
|
1282
1319
|
},
|
|
1283
1320
|
handler: (req, _reply) => {
|
|
1284
|
-
t.
|
|
1285
|
-
t.
|
|
1321
|
+
t.assert.deepStrictEqual(typeof req.params.id, 'number')
|
|
1322
|
+
t.assert.deepStrictEqual(req.params.id, 42)
|
|
1286
1323
|
return 'ok'
|
|
1287
1324
|
}
|
|
1288
1325
|
})
|
|
@@ -1293,13 +1330,13 @@ test('Custom validator builder override by custom validator compiler in child in
|
|
|
1293
1330
|
method: 'POST',
|
|
1294
1331
|
url: '/one/42'
|
|
1295
1332
|
})
|
|
1296
|
-
t.
|
|
1333
|
+
t.assert.strictEqual(one.statusCode, 200)
|
|
1297
1334
|
|
|
1298
1335
|
const two = await fastify.inject({
|
|
1299
1336
|
method: 'POST',
|
|
1300
1337
|
url: '/two/43'
|
|
1301
1338
|
})
|
|
1302
|
-
t.
|
|
1339
|
+
t.assert.strictEqual(two.statusCode, 200)
|
|
1303
1340
|
})
|
|
1304
1341
|
|
|
1305
1342
|
test('Schema validation when no content type is provided', async t => {
|
|
@@ -1339,12 +1376,10 @@ test('Schema validation when no content type is provided', async t => {
|
|
|
1339
1376
|
},
|
|
1340
1377
|
body: { invalid: 'string' }
|
|
1341
1378
|
})
|
|
1342
|
-
t.
|
|
1379
|
+
t.assert.strictEqual(invalid.statusCode, 200)
|
|
1343
1380
|
})
|
|
1344
1381
|
|
|
1345
1382
|
test('Schema validation will not be bypass by different content type', async t => {
|
|
1346
|
-
t.plan(10)
|
|
1347
|
-
|
|
1348
1383
|
const fastify = Fastify()
|
|
1349
1384
|
|
|
1350
1385
|
fastify.post('/', {
|
|
@@ -1367,7 +1402,7 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1367
1402
|
}, async () => 'ok')
|
|
1368
1403
|
|
|
1369
1404
|
await fastify.listen({ port: 0 })
|
|
1370
|
-
t.
|
|
1405
|
+
t.after(() => fastify.close())
|
|
1371
1406
|
const address = fastify.listeningOrigin
|
|
1372
1407
|
|
|
1373
1408
|
const correct1 = await request(address, {
|
|
@@ -1378,7 +1413,7 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1378
1413
|
},
|
|
1379
1414
|
body: JSON.stringify({ foo: 'string' })
|
|
1380
1415
|
})
|
|
1381
|
-
t.
|
|
1416
|
+
t.assert.strictEqual(correct1.statusCode, 200)
|
|
1382
1417
|
await correct1.body.dump()
|
|
1383
1418
|
|
|
1384
1419
|
const correct2 = await request(address, {
|
|
@@ -1389,7 +1424,7 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1389
1424
|
},
|
|
1390
1425
|
body: JSON.stringify({ foo: 'string' })
|
|
1391
1426
|
})
|
|
1392
|
-
t.
|
|
1427
|
+
t.assert.strictEqual(correct2.statusCode, 200)
|
|
1393
1428
|
await correct2.body.dump()
|
|
1394
1429
|
|
|
1395
1430
|
const invalid1 = await request(address, {
|
|
@@ -1400,8 +1435,8 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1400
1435
|
},
|
|
1401
1436
|
body: JSON.stringify({ invalid: 'string' })
|
|
1402
1437
|
})
|
|
1403
|
-
t.
|
|
1404
|
-
t.
|
|
1438
|
+
t.assert.strictEqual(invalid1.statusCode, 400)
|
|
1439
|
+
t.assert.strictEqual((await invalid1.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1405
1440
|
|
|
1406
1441
|
const invalid2 = await request(address, {
|
|
1407
1442
|
method: 'POST',
|
|
@@ -1411,8 +1446,8 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1411
1446
|
},
|
|
1412
1447
|
body: JSON.stringify({ invalid: 'string' })
|
|
1413
1448
|
})
|
|
1414
|
-
t.
|
|
1415
|
-
t.
|
|
1449
|
+
t.assert.strictEqual(invalid2.statusCode, 400)
|
|
1450
|
+
t.assert.strictEqual((await invalid2.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1416
1451
|
|
|
1417
1452
|
const invalid3 = await request(address, {
|
|
1418
1453
|
method: 'POST',
|
|
@@ -1422,8 +1457,8 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1422
1457
|
},
|
|
1423
1458
|
body: JSON.stringify({ invalid: 'string' })
|
|
1424
1459
|
})
|
|
1425
|
-
t.
|
|
1426
|
-
t.
|
|
1460
|
+
t.assert.strictEqual(invalid3.statusCode, 400)
|
|
1461
|
+
t.assert.strictEqual((await invalid3.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1427
1462
|
|
|
1428
1463
|
const invalid4 = await request(address, {
|
|
1429
1464
|
method: 'POST',
|
|
@@ -1433,6 +1468,50 @@ test('Schema validation will not be bypass by different content type', async t =
|
|
|
1433
1468
|
},
|
|
1434
1469
|
body: JSON.stringify({ invalid: 'string' })
|
|
1435
1470
|
})
|
|
1436
|
-
t.
|
|
1437
|
-
t.
|
|
1471
|
+
t.assert.strictEqual(invalid4.statusCode, 400)
|
|
1472
|
+
t.assert.strictEqual((await invalid4.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1473
|
+
|
|
1474
|
+
const invalid5 = await request(address, {
|
|
1475
|
+
method: 'POST',
|
|
1476
|
+
url: '/',
|
|
1477
|
+
headers: {
|
|
1478
|
+
'content-type': 'ApPlIcAtIoN/JsOn \tfoo;'
|
|
1479
|
+
},
|
|
1480
|
+
body: JSON.stringify({ invalid: 'string' })
|
|
1481
|
+
})
|
|
1482
|
+
t.assert.strictEqual(invalid5.statusCode, 400)
|
|
1483
|
+
t.assert.strictEqual((await invalid5.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1484
|
+
|
|
1485
|
+
const invalid6 = await request(address, {
|
|
1486
|
+
method: 'POST',
|
|
1487
|
+
url: '/',
|
|
1488
|
+
headers: {
|
|
1489
|
+
'content-type': 'ApPlIcAtIoN/JsOn\t foo;'
|
|
1490
|
+
},
|
|
1491
|
+
body: JSON.stringify({ invalid: 'string' })
|
|
1492
|
+
})
|
|
1493
|
+
t.assert.strictEqual(invalid6.statusCode, 415)
|
|
1494
|
+
t.assert.strictEqual((await invalid6.body.json()).code, 'FST_ERR_CTP_INVALID_MEDIA_TYPE')
|
|
1495
|
+
|
|
1496
|
+
const invalid7 = await request(address, {
|
|
1497
|
+
method: 'POST',
|
|
1498
|
+
url: '/',
|
|
1499
|
+
headers: {
|
|
1500
|
+
'content-type': 'ApPlIcAtIoN/JsOn \t'
|
|
1501
|
+
},
|
|
1502
|
+
body: JSON.stringify({ invalid: 'string' })
|
|
1503
|
+
})
|
|
1504
|
+
t.assert.strictEqual(invalid7.statusCode, 400)
|
|
1505
|
+
t.assert.strictEqual((await invalid7.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1506
|
+
|
|
1507
|
+
const invalid8 = await request(address, {
|
|
1508
|
+
method: 'POST',
|
|
1509
|
+
url: '/',
|
|
1510
|
+
headers: {
|
|
1511
|
+
'content-type': 'ApPlIcAtIoN/JsOn\t'
|
|
1512
|
+
},
|
|
1513
|
+
body: JSON.stringify({ invalid: 'string' })
|
|
1514
|
+
})
|
|
1515
|
+
t.assert.strictEqual(invalid8.statusCode, 400)
|
|
1516
|
+
t.assert.strictEqual((await invalid8.body.json()).code, 'FST_ERR_VALIDATION')
|
|
1438
1517
|
})
|