fastify 5.3.2 → 5.3.3
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/.vscode/settings.json +22 -0
- package/docs/Guides/Ecosystem.md +7 -2
- package/docs/Guides/Serverless.md +28 -69
- package/docs/Reference/Errors.md +0 -2
- package/docs/Reference/Server.md +17 -1
- package/eslint.config.js +17 -9
- package/fastify.js +6 -2
- package/lib/decorate.js +2 -2
- package/lib/errors.js +0 -8
- package/lib/logger-factory.js +1 -1
- package/lib/logger-pino.js +2 -2
- package/lib/reply.js +2 -2
- package/lib/request.js +1 -1
- package/lib/server.js +30 -51
- package/package.json +4 -4
- package/test/close-pipelining.test.js +5 -4
- package/test/decorator.test.js +422 -341
- package/test/helper.js +107 -69
- package/test/hooks.on-listen.test.js +255 -239
- package/test/hooks.on-ready.test.js +110 -92
- package/test/inject.test.js +114 -97
- package/test/input-validation.js +63 -53
- package/test/internals/errors.test.js +1 -11
- package/test/internals/hooks.test.js +17 -0
- package/test/issue-4959.test.js +2 -2
- package/test/logger/response.test.js +19 -20
- package/test/options.error-handler.test.js +1 -1
- package/test/options.test.js +1 -1
- package/test/output-validation.test.js +49 -70
- 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/promises.test.js +36 -30
- 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/schema-feature.test.js +309 -238
- package/test/schema-validation.test.js +44 -2
- 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/types/errors.test-d.ts +0 -1
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/register.test-d.ts +1 -1
- package/test/use-semicolon-delimiter.test.js +1 -1
- package/types/errors.d.ts +0 -1
- package/test/http2/missing-http2-module.test.js +0 -17
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
const fp = require('fastify-plugin')
|
|
6
6
|
const deepClone = require('rfdc')({ circles: true, proto: false })
|
|
7
7
|
const Ajv = require('ajv')
|
|
8
8
|
const { kSchemaController } = require('../lib/symbols.js')
|
|
9
9
|
const { FSTWRN001 } = require('../lib/warnings')
|
|
10
|
+
const { waitForCb } = require('./toolkit')
|
|
10
11
|
|
|
11
12
|
const echoParams = (req, reply) => { reply.send(req.params) }
|
|
12
13
|
const echoBody = (req, reply) => { reply.send(req.body) }
|
|
@@ -15,22 +16,23 @@ const echoBody = (req, reply) => { reply.send(req.body) }
|
|
|
15
16
|
test(`Should expose ${f} function`, t => {
|
|
16
17
|
t.plan(1)
|
|
17
18
|
const fastify = Fastify()
|
|
18
|
-
t.
|
|
19
|
+
t.assert.strictEqual(typeof fastify[f], 'function')
|
|
19
20
|
})
|
|
20
21
|
})
|
|
21
22
|
|
|
22
23
|
;['setValidatorCompiler', 'setSerializerCompiler'].forEach(f => {
|
|
23
|
-
test(`cannot call ${f} after binding`, t => {
|
|
24
|
+
test(`cannot call ${f} after binding`, (t, testDone) => {
|
|
24
25
|
t.plan(2)
|
|
25
26
|
const fastify = Fastify()
|
|
26
|
-
t.
|
|
27
|
+
t.after(() => fastify.close())
|
|
27
28
|
fastify.listen({ port: 0 }, err => {
|
|
28
|
-
t.
|
|
29
|
+
t.assert.ifError(err)
|
|
29
30
|
try {
|
|
30
31
|
fastify[f](() => { })
|
|
31
|
-
t.fail()
|
|
32
|
+
t.assert.fail()
|
|
32
33
|
} catch (e) {
|
|
33
|
-
t.
|
|
34
|
+
t.assert.ok(true)
|
|
35
|
+
testDone()
|
|
34
36
|
}
|
|
35
37
|
})
|
|
36
38
|
})
|
|
@@ -41,7 +43,7 @@ test('The schemas should be added to an internal storage', t => {
|
|
|
41
43
|
const fastify = Fastify()
|
|
42
44
|
const schema = { $id: 'id', my: 'schema' }
|
|
43
45
|
fastify.addSchema(schema)
|
|
44
|
-
t.
|
|
46
|
+
t.assert.deepStrictEqual(fastify[kSchemaController].schemaBucket.store, { id: schema })
|
|
45
47
|
})
|
|
46
48
|
|
|
47
49
|
test('The schemas should be accessible via getSchemas', t => {
|
|
@@ -55,10 +57,10 @@ test('The schemas should be accessible via getSchemas', t => {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
Object.values(schemas).forEach(schema => { fastify.addSchema(schema) })
|
|
58
|
-
t.
|
|
60
|
+
t.assert.deepStrictEqual(fastify.getSchemas(), schemas)
|
|
59
61
|
})
|
|
60
62
|
|
|
61
|
-
test('The schema should be accessible by id via getSchema', t => {
|
|
63
|
+
test('The schema should be accessible by id via getSchema', (t, testDone) => {
|
|
62
64
|
t.plan(5)
|
|
63
65
|
const fastify = Fastify()
|
|
64
66
|
|
|
@@ -68,41 +70,50 @@ test('The schema should be accessible by id via getSchema', t => {
|
|
|
68
70
|
{ $id: 'bcd', my: 'schema', properties: { a: 'a', b: 1 } }
|
|
69
71
|
]
|
|
70
72
|
schemas.forEach(schema => { fastify.addSchema(schema) })
|
|
71
|
-
t.
|
|
72
|
-
t.
|
|
73
|
-
t.
|
|
73
|
+
t.assert.deepStrictEqual(fastify.getSchema('abc'), schemas[1])
|
|
74
|
+
t.assert.deepStrictEqual(fastify.getSchema('id'), schemas[0])
|
|
75
|
+
t.assert.deepStrictEqual(fastify.getSchema('foo'), undefined)
|
|
74
76
|
|
|
75
77
|
fastify.register((instance, opts, done) => {
|
|
76
78
|
const pluginSchema = { $id: 'cde', my: 'schema' }
|
|
77
79
|
instance.addSchema(pluginSchema)
|
|
78
|
-
t.
|
|
80
|
+
t.assert.deepStrictEqual(instance.getSchema('cde'), pluginSchema)
|
|
79
81
|
done()
|
|
80
82
|
})
|
|
81
83
|
|
|
82
|
-
fastify.ready(err =>
|
|
84
|
+
fastify.ready(err => {
|
|
85
|
+
t.assert.ifError(err)
|
|
86
|
+
testDone()
|
|
87
|
+
})
|
|
83
88
|
})
|
|
84
89
|
|
|
85
|
-
test('Get validatorCompiler after setValidatorCompiler', t => {
|
|
90
|
+
test('Get validatorCompiler after setValidatorCompiler', (t, testDone) => {
|
|
86
91
|
t.plan(2)
|
|
87
92
|
const myCompiler = () => { }
|
|
88
93
|
const fastify = Fastify()
|
|
89
94
|
fastify.setValidatorCompiler(myCompiler)
|
|
90
95
|
const sc = fastify.validatorCompiler
|
|
91
|
-
t.ok(Object.is(myCompiler, sc))
|
|
92
|
-
fastify.ready(err =>
|
|
96
|
+
t.assert.ok(Object.is(myCompiler, sc))
|
|
97
|
+
fastify.ready(err => {
|
|
98
|
+
t.assert.ifError(err)
|
|
99
|
+
testDone()
|
|
100
|
+
})
|
|
93
101
|
})
|
|
94
102
|
|
|
95
|
-
test('Get serializerCompiler after setSerializerCompiler', t => {
|
|
103
|
+
test('Get serializerCompiler after setSerializerCompiler', (t, testDone) => {
|
|
96
104
|
t.plan(2)
|
|
97
105
|
const myCompiler = () => { }
|
|
98
106
|
const fastify = Fastify()
|
|
99
107
|
fastify.setSerializerCompiler(myCompiler)
|
|
100
108
|
const sc = fastify.serializerCompiler
|
|
101
|
-
t.ok(Object.is(myCompiler, sc))
|
|
102
|
-
fastify.ready(err =>
|
|
109
|
+
t.assert.ok(Object.is(myCompiler, sc))
|
|
110
|
+
fastify.ready(err => {
|
|
111
|
+
t.assert.ifError(err)
|
|
112
|
+
testDone()
|
|
113
|
+
})
|
|
103
114
|
})
|
|
104
115
|
|
|
105
|
-
test('Get compilers is empty when settle on routes', t => {
|
|
116
|
+
test('Get compilers is empty when settle on routes', (t, testDone) => {
|
|
106
117
|
t.plan(3)
|
|
107
118
|
|
|
108
119
|
const fastify = Fastify()
|
|
@@ -130,9 +141,10 @@ test('Get compilers is empty when settle on routes', t => {
|
|
|
130
141
|
payload: {},
|
|
131
142
|
url: '/'
|
|
132
143
|
}, (err, res) => {
|
|
133
|
-
t.
|
|
134
|
-
t.
|
|
135
|
-
t.
|
|
144
|
+
t.assert.ifError(err)
|
|
145
|
+
t.assert.strictEqual(fastify.validatorCompiler, undefined)
|
|
146
|
+
t.assert.strictEqual(fastify.serializerCompiler, undefined)
|
|
147
|
+
testDone()
|
|
136
148
|
})
|
|
137
149
|
})
|
|
138
150
|
|
|
@@ -141,9 +153,9 @@ test('Should throw if the $id property is missing', t => {
|
|
|
141
153
|
const fastify = Fastify()
|
|
142
154
|
try {
|
|
143
155
|
fastify.addSchema({ type: 'string' })
|
|
144
|
-
t.fail()
|
|
156
|
+
t.assert.fail()
|
|
145
157
|
} catch (err) {
|
|
146
|
-
t.
|
|
158
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_MISSING_ID')
|
|
147
159
|
}
|
|
148
160
|
})
|
|
149
161
|
|
|
@@ -155,12 +167,12 @@ test('Cannot add multiple times the same id', t => {
|
|
|
155
167
|
try {
|
|
156
168
|
fastify.addSchema({ $id: 'id' })
|
|
157
169
|
} catch (err) {
|
|
158
|
-
t.
|
|
159
|
-
t.
|
|
170
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_ALREADY_PRESENT')
|
|
171
|
+
t.assert.strictEqual(err.message, 'Schema with id \'id\' already declared!')
|
|
160
172
|
}
|
|
161
173
|
})
|
|
162
174
|
|
|
163
|
-
test('Cannot add schema for query and querystring', t => {
|
|
175
|
+
test('Cannot add schema for query and querystring', (t, testDone) => {
|
|
164
176
|
t.plan(2)
|
|
165
177
|
const fastify = Fastify()
|
|
166
178
|
|
|
@@ -183,12 +195,13 @@ test('Cannot add schema for query and querystring', t => {
|
|
|
183
195
|
})
|
|
184
196
|
|
|
185
197
|
fastify.ready(err => {
|
|
186
|
-
t.
|
|
187
|
-
t.
|
|
198
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_DUPLICATE')
|
|
199
|
+
t.assert.strictEqual(err.message, 'Schema with \'querystring\' already present!')
|
|
200
|
+
testDone()
|
|
188
201
|
})
|
|
189
202
|
})
|
|
190
203
|
|
|
191
|
-
test('Should throw of the schema does not exists in input', t => {
|
|
204
|
+
test('Should throw of the schema does not exists in input', (t, testDone) => {
|
|
192
205
|
t.plan(2)
|
|
193
206
|
const fastify = Fastify()
|
|
194
207
|
|
|
@@ -205,12 +218,13 @@ test('Should throw of the schema does not exists in input', t => {
|
|
|
205
218
|
})
|
|
206
219
|
|
|
207
220
|
fastify.ready(err => {
|
|
208
|
-
t.
|
|
209
|
-
t.
|
|
221
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_VALIDATION_BUILD')
|
|
222
|
+
t.assert.strictEqual(err.message, "Failed building the validation schema for GET: /:id, due to error can't resolve reference #notExist from id #")
|
|
223
|
+
testDone()
|
|
210
224
|
})
|
|
211
225
|
})
|
|
212
226
|
|
|
213
|
-
test('Should throw if schema is missing for content type', t => {
|
|
227
|
+
test('Should throw if schema is missing for content type', (t, testDone) => {
|
|
214
228
|
t.plan(2)
|
|
215
229
|
|
|
216
230
|
const fastify = Fastify()
|
|
@@ -226,12 +240,13 @@ test('Should throw if schema is missing for content type', t => {
|
|
|
226
240
|
})
|
|
227
241
|
|
|
228
242
|
fastify.ready(err => {
|
|
229
|
-
t.
|
|
230
|
-
t.
|
|
243
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_CONTENT_MISSING_SCHEMA')
|
|
244
|
+
t.assert.strictEqual(err.message, "Schema is missing for the content type 'application/json'")
|
|
245
|
+
testDone()
|
|
231
246
|
})
|
|
232
247
|
})
|
|
233
248
|
|
|
234
|
-
test('Should throw of the schema does not exists in output', t => {
|
|
249
|
+
test('Should throw of the schema does not exists in output', (t, testDone) => {
|
|
235
250
|
t.plan(2)
|
|
236
251
|
const fastify = Fastify()
|
|
237
252
|
|
|
@@ -250,12 +265,13 @@ test('Should throw of the schema does not exists in output', t => {
|
|
|
250
265
|
})
|
|
251
266
|
|
|
252
267
|
fastify.ready(err => {
|
|
253
|
-
t.
|
|
254
|
-
t.match(err.message, /^Failed building the serialization schema for GET: \/:id, due to error Cannot find reference.*/) // error from fast-json-stringify
|
|
268
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_SERIALIZATION_BUILD')
|
|
269
|
+
t.assert.match(err.message, /^Failed building the serialization schema for GET: \/:id, due to error Cannot find reference.*/) // error from fast-json-stringify
|
|
270
|
+
testDone()
|
|
255
271
|
})
|
|
256
272
|
})
|
|
257
273
|
|
|
258
|
-
test('Should not change the input schemas', t => {
|
|
274
|
+
test('Should not change the input schemas', (t, testDone) => {
|
|
259
275
|
t.plan(4)
|
|
260
276
|
|
|
261
277
|
const theSchema = {
|
|
@@ -294,24 +310,25 @@ test('Should not change the input schemas', t => {
|
|
|
294
310
|
method: 'POST',
|
|
295
311
|
payload: { name: 'Foo', surname: 'Bar' }
|
|
296
312
|
}, (err, res) => {
|
|
297
|
-
t.
|
|
298
|
-
t.
|
|
299
|
-
t.ok(theSchema.$id, 'the $id is not removed')
|
|
300
|
-
t.
|
|
313
|
+
t.assert.ifError(err)
|
|
314
|
+
t.assert.deepStrictEqual(res.json(), { name: 'Foo' })
|
|
315
|
+
t.assert.ok(theSchema.$id, 'the $id is not removed')
|
|
316
|
+
t.assert.deepStrictEqual(fastify.getSchema('helloSchema'), theSchema)
|
|
317
|
+
testDone()
|
|
301
318
|
})
|
|
302
319
|
})
|
|
303
320
|
|
|
304
|
-
test('Should emit warning if the schema headers is undefined', t => {
|
|
321
|
+
test('Should emit warning if the schema headers is undefined', (t, testDone) => {
|
|
305
322
|
t.plan(4)
|
|
306
323
|
const fastify = Fastify()
|
|
307
324
|
|
|
308
325
|
process.on('warning', onWarning)
|
|
309
326
|
function onWarning (warning) {
|
|
310
|
-
t.
|
|
311
|
-
t.
|
|
327
|
+
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
328
|
+
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
312
329
|
}
|
|
313
330
|
|
|
314
|
-
t.
|
|
331
|
+
t.after(() => {
|
|
315
332
|
process.removeListener('warning', onWarning)
|
|
316
333
|
FSTWRN001.emitted = false
|
|
317
334
|
})
|
|
@@ -327,22 +344,23 @@ test('Should emit warning if the schema headers is undefined', t => {
|
|
|
327
344
|
method: 'POST',
|
|
328
345
|
url: '/123'
|
|
329
346
|
}, (error, res) => {
|
|
330
|
-
t.
|
|
331
|
-
t.
|
|
347
|
+
t.assert.ifError(error)
|
|
348
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
349
|
+
testDone()
|
|
332
350
|
})
|
|
333
351
|
})
|
|
334
352
|
|
|
335
|
-
test('Should emit warning if the schema body is undefined', t => {
|
|
353
|
+
test('Should emit warning if the schema body is undefined', (t, testDone) => {
|
|
336
354
|
t.plan(4)
|
|
337
355
|
const fastify = Fastify()
|
|
338
356
|
|
|
339
357
|
process.on('warning', onWarning)
|
|
340
358
|
function onWarning (warning) {
|
|
341
|
-
t.
|
|
342
|
-
t.
|
|
359
|
+
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
360
|
+
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
343
361
|
}
|
|
344
362
|
|
|
345
|
-
t.
|
|
363
|
+
t.after(() => {
|
|
346
364
|
process.removeListener('warning', onWarning)
|
|
347
365
|
FSTWRN001.emitted = false
|
|
348
366
|
})
|
|
@@ -358,22 +376,23 @@ test('Should emit warning if the schema body is undefined', t => {
|
|
|
358
376
|
method: 'POST',
|
|
359
377
|
url: '/123'
|
|
360
378
|
}, (error, res) => {
|
|
361
|
-
t.
|
|
362
|
-
t.
|
|
379
|
+
t.assert.ifError(error)
|
|
380
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
381
|
+
testDone()
|
|
363
382
|
})
|
|
364
383
|
})
|
|
365
384
|
|
|
366
|
-
test('Should emit warning if the schema query is undefined', t => {
|
|
385
|
+
test('Should emit warning if the schema query is undefined', (t, testDone) => {
|
|
367
386
|
t.plan(4)
|
|
368
387
|
const fastify = Fastify()
|
|
369
388
|
|
|
370
389
|
process.on('warning', onWarning)
|
|
371
390
|
function onWarning (warning) {
|
|
372
|
-
t.
|
|
373
|
-
t.
|
|
391
|
+
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
392
|
+
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
374
393
|
}
|
|
375
394
|
|
|
376
|
-
t.
|
|
395
|
+
t.after(() => {
|
|
377
396
|
process.removeListener('warning', onWarning)
|
|
378
397
|
FSTWRN001.emitted = false
|
|
379
398
|
})
|
|
@@ -389,22 +408,23 @@ test('Should emit warning if the schema query is undefined', t => {
|
|
|
389
408
|
method: 'POST',
|
|
390
409
|
url: '/123'
|
|
391
410
|
}, (error, res) => {
|
|
392
|
-
t.
|
|
393
|
-
t.
|
|
411
|
+
t.assert.ifError(error)
|
|
412
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
413
|
+
testDone()
|
|
394
414
|
})
|
|
395
415
|
})
|
|
396
416
|
|
|
397
|
-
test('Should emit warning if the schema params is undefined', t => {
|
|
417
|
+
test('Should emit warning if the schema params is undefined', (t, testDone) => {
|
|
398
418
|
t.plan(4)
|
|
399
419
|
const fastify = Fastify()
|
|
400
420
|
|
|
401
421
|
process.on('warning', onWarning)
|
|
402
422
|
function onWarning (warning) {
|
|
403
|
-
t.
|
|
404
|
-
t.
|
|
423
|
+
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
424
|
+
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
405
425
|
}
|
|
406
426
|
|
|
407
|
-
t.
|
|
427
|
+
t.after(() => {
|
|
408
428
|
process.removeListener('warning', onWarning)
|
|
409
429
|
FSTWRN001.emitted = false
|
|
410
430
|
})
|
|
@@ -420,12 +440,13 @@ test('Should emit warning if the schema params is undefined', t => {
|
|
|
420
440
|
method: 'POST',
|
|
421
441
|
url: '/123'
|
|
422
442
|
}, (error, res) => {
|
|
423
|
-
t.
|
|
424
|
-
t.
|
|
443
|
+
t.assert.ifError(error)
|
|
444
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
445
|
+
testDone()
|
|
425
446
|
})
|
|
426
447
|
})
|
|
427
448
|
|
|
428
|
-
test('Should emit a warning for every route with undefined schema', t => {
|
|
449
|
+
test('Should emit a warning for every route with undefined schema', (t, testDone) => {
|
|
429
450
|
t.plan(16)
|
|
430
451
|
const fastify = Fastify()
|
|
431
452
|
|
|
@@ -436,13 +457,13 @@ test('Should emit a warning for every route with undefined schema', t => {
|
|
|
436
457
|
// - 2 - GET and HEAD for /undefinedBody/:id
|
|
437
458
|
// => 3 x 4 assertions = 12 assertions
|
|
438
459
|
function onWarning (warning) {
|
|
439
|
-
t.
|
|
440
|
-
t.
|
|
441
|
-
t.
|
|
460
|
+
t.assert.strictEqual(warning.name, 'FastifyWarning')
|
|
461
|
+
t.assert.strictEqual(warning.code, FSTWRN001.code)
|
|
462
|
+
t.assert.strictEqual(runs++, expectedWarningEmitted.shift())
|
|
442
463
|
}
|
|
443
464
|
|
|
444
465
|
process.on('warning', onWarning)
|
|
445
|
-
t.
|
|
466
|
+
t.after(() => {
|
|
446
467
|
process.removeListener('warning', onWarning)
|
|
447
468
|
FSTWRN001.emitted = false
|
|
448
469
|
})
|
|
@@ -465,20 +486,21 @@ test('Should emit a warning for every route with undefined schema', t => {
|
|
|
465
486
|
method: 'GET',
|
|
466
487
|
url: '/undefinedParams/123'
|
|
467
488
|
}, (error, res) => {
|
|
468
|
-
t.
|
|
469
|
-
t.
|
|
489
|
+
t.assert.ifError(error)
|
|
490
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
470
491
|
})
|
|
471
492
|
|
|
472
493
|
fastify.inject({
|
|
473
494
|
method: 'GET',
|
|
474
495
|
url: '/undefinedBody/123'
|
|
475
496
|
}, (error, res) => {
|
|
476
|
-
t.
|
|
477
|
-
t.
|
|
497
|
+
t.assert.ifError(error)
|
|
498
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
499
|
+
testDone()
|
|
478
500
|
})
|
|
479
501
|
})
|
|
480
502
|
|
|
481
|
-
test('First level $ref', t => {
|
|
503
|
+
test('First level $ref', (t, testDone) => {
|
|
482
504
|
t.plan(2)
|
|
483
505
|
const fastify = Fastify()
|
|
484
506
|
|
|
@@ -506,8 +528,9 @@ test('First level $ref', t => {
|
|
|
506
528
|
method: 'GET',
|
|
507
529
|
url: '/123'
|
|
508
530
|
}, (err, res) => {
|
|
509
|
-
t.
|
|
510
|
-
t.
|
|
531
|
+
t.assert.ifError(err)
|
|
532
|
+
t.assert.deepStrictEqual(res.json(), { id: 246 })
|
|
533
|
+
testDone()
|
|
511
534
|
})
|
|
512
535
|
})
|
|
513
536
|
|
|
@@ -516,38 +539,38 @@ test('Customize validator compiler in instance and route', t => {
|
|
|
516
539
|
const fastify = Fastify({ exposeHeadRoutes: false })
|
|
517
540
|
|
|
518
541
|
fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
|
|
519
|
-
t.
|
|
520
|
-
t.
|
|
542
|
+
t.assert.strictEqual(method, 'POST') // run 4 times
|
|
543
|
+
t.assert.strictEqual(url, '/:id') // run 4 times
|
|
521
544
|
switch (httpPart) {
|
|
522
545
|
case 'body':
|
|
523
|
-
t.
|
|
546
|
+
t.assert.ok('body evaluated')
|
|
524
547
|
return body => {
|
|
525
|
-
t.
|
|
548
|
+
t.assert.deepStrictEqual(body, { foo: ['bar', 'BAR'] })
|
|
526
549
|
return true
|
|
527
550
|
}
|
|
528
551
|
case 'params':
|
|
529
|
-
t.
|
|
552
|
+
t.assert.ok('params evaluated')
|
|
530
553
|
return params => {
|
|
531
|
-
t.
|
|
554
|
+
t.assert.strictEqual(params.id, '1234')
|
|
532
555
|
return true
|
|
533
556
|
}
|
|
534
557
|
case 'querystring':
|
|
535
|
-
t.
|
|
558
|
+
t.assert.ok('querystring evaluated')
|
|
536
559
|
return query => {
|
|
537
|
-
t.
|
|
560
|
+
t.assert.strictEqual(query.lang, 'en')
|
|
538
561
|
return true
|
|
539
562
|
}
|
|
540
563
|
case 'headers':
|
|
541
|
-
t.
|
|
564
|
+
t.assert.ok('headers evaluated')
|
|
542
565
|
return headers => {
|
|
543
|
-
t.
|
|
566
|
+
t.assert.strictEqual(headers.x, 'hello')
|
|
544
567
|
return true
|
|
545
568
|
}
|
|
546
569
|
case '2xx':
|
|
547
|
-
t.fail('the validator doesn\'t process the response')
|
|
570
|
+
t.assert.fail('the validator doesn\'t process the response')
|
|
548
571
|
break
|
|
549
572
|
default:
|
|
550
|
-
t.fail(`unknown httpPart ${httpPart}`)
|
|
573
|
+
t.assert.fail(`unknown httpPart ${httpPart}`)
|
|
551
574
|
}
|
|
552
575
|
})
|
|
553
576
|
|
|
@@ -592,8 +615,8 @@ test('Customize validator compiler in instance and route', t => {
|
|
|
592
615
|
fastify.get('/wow/:id', {
|
|
593
616
|
handler: echoParams,
|
|
594
617
|
validatorCompiler: ({ schema, method, url, httpPart }) => {
|
|
595
|
-
t.
|
|
596
|
-
t.
|
|
618
|
+
t.assert.strictEqual(method, 'GET') // run 3 times (params, headers, query)
|
|
619
|
+
t.assert.strictEqual(url, '/wow/:id') // run 4 times
|
|
597
620
|
return () => { return true } // ignore the validation
|
|
598
621
|
},
|
|
599
622
|
schema: {
|
|
@@ -626,6 +649,8 @@ test('Customize validator compiler in instance and route', t => {
|
|
|
626
649
|
}
|
|
627
650
|
})
|
|
628
651
|
|
|
652
|
+
const { stepIn, patience } = waitForCb({ steps: 2 })
|
|
653
|
+
|
|
629
654
|
fastify.inject({
|
|
630
655
|
url: '/1234',
|
|
631
656
|
method: 'POST',
|
|
@@ -633,9 +658,10 @@ test('Customize validator compiler in instance and route', t => {
|
|
|
633
658
|
query: { lang: 'en' },
|
|
634
659
|
payload: { foo: ['bar', 'BAR'] }
|
|
635
660
|
}, (err, res) => {
|
|
636
|
-
t.
|
|
637
|
-
t.
|
|
638
|
-
t.
|
|
661
|
+
t.assert.ifError(err)
|
|
662
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
663
|
+
t.assert.deepStrictEqual(res.json(), { foo: ['bar', 'BAR'] })
|
|
664
|
+
stepIn()
|
|
639
665
|
})
|
|
640
666
|
|
|
641
667
|
fastify.inject({
|
|
@@ -644,13 +670,16 @@ test('Customize validator compiler in instance and route', t => {
|
|
|
644
670
|
headers: { x: 'hello' },
|
|
645
671
|
query: { lang: 'jp' } // not in the enum
|
|
646
672
|
}, (err, res) => {
|
|
647
|
-
t.
|
|
648
|
-
t.
|
|
649
|
-
t.
|
|
673
|
+
t.assert.ifError(err)
|
|
674
|
+
t.assert.strictEqual(res.statusCode, 200) // the validation is always true
|
|
675
|
+
t.assert.deepStrictEqual(res.json(), {})
|
|
676
|
+
stepIn()
|
|
650
677
|
})
|
|
678
|
+
|
|
679
|
+
return patience
|
|
651
680
|
})
|
|
652
681
|
|
|
653
|
-
test('Use the same schema across multiple routes', t => {
|
|
682
|
+
test('Use the same schema across multiple routes', (t, testDone) => {
|
|
654
683
|
t.plan(4)
|
|
655
684
|
const fastify = Fastify()
|
|
656
685
|
|
|
@@ -694,20 +723,21 @@ test('Use the same schema across multiple routes', t => {
|
|
|
694
723
|
method: 'GET',
|
|
695
724
|
url: '/first/123'
|
|
696
725
|
}, (err, res) => {
|
|
697
|
-
t.
|
|
698
|
-
t.
|
|
726
|
+
t.assert.ifError(err)
|
|
727
|
+
t.assert.strictEqual(res.payload, 'number')
|
|
699
728
|
})
|
|
700
729
|
|
|
701
730
|
fastify.inject({
|
|
702
731
|
method: 'GET',
|
|
703
732
|
url: '/second/123'
|
|
704
733
|
}, (err, res) => {
|
|
705
|
-
t.
|
|
706
|
-
t.
|
|
734
|
+
t.assert.ifError(err)
|
|
735
|
+
t.assert.strictEqual(res.payload, 'number')
|
|
736
|
+
testDone()
|
|
707
737
|
})
|
|
708
738
|
})
|
|
709
739
|
|
|
710
|
-
test('Encapsulation should intervene', t => {
|
|
740
|
+
test('Encapsulation should intervene', (t, testDone) => {
|
|
711
741
|
t.plan(2)
|
|
712
742
|
const fastify = Fastify()
|
|
713
743
|
|
|
@@ -738,12 +768,13 @@ test('Encapsulation should intervene', t => {
|
|
|
738
768
|
})
|
|
739
769
|
|
|
740
770
|
fastify.ready(err => {
|
|
741
|
-
t.
|
|
742
|
-
t.
|
|
771
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_VALIDATION_BUILD')
|
|
772
|
+
t.assert.strictEqual(err.message, "Failed building the validation schema for GET: /:id, due to error can't resolve reference encapsulation#/properties/id from id #")
|
|
773
|
+
testDone()
|
|
743
774
|
})
|
|
744
775
|
})
|
|
745
776
|
|
|
746
|
-
test('Encapsulation isolation', t => {
|
|
777
|
+
test('Encapsulation isolation', (t, testDone) => {
|
|
747
778
|
t.plan(1)
|
|
748
779
|
const fastify = Fastify()
|
|
749
780
|
|
|
@@ -757,10 +788,13 @@ test('Encapsulation isolation', t => {
|
|
|
757
788
|
done()
|
|
758
789
|
})
|
|
759
790
|
|
|
760
|
-
fastify.ready(err =>
|
|
791
|
+
fastify.ready(err => {
|
|
792
|
+
t.assert.ifError(err)
|
|
793
|
+
testDone()
|
|
794
|
+
})
|
|
761
795
|
})
|
|
762
796
|
|
|
763
|
-
test('Add schema after register', t => {
|
|
797
|
+
test('Add schema after register', (t, testDone) => {
|
|
764
798
|
t.plan(5)
|
|
765
799
|
|
|
766
800
|
const fastify = Fastify()
|
|
@@ -784,8 +818,8 @@ test('Add schema after register', t => {
|
|
|
784
818
|
try {
|
|
785
819
|
instance.addSchema({ $id: 'test' })
|
|
786
820
|
} catch (err) {
|
|
787
|
-
t.
|
|
788
|
-
t.
|
|
821
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_ALREADY_PRESENT')
|
|
822
|
+
t.assert.strictEqual(err.message, 'Schema with id \'test\' already declared!')
|
|
789
823
|
}
|
|
790
824
|
done()
|
|
791
825
|
})
|
|
@@ -794,13 +828,14 @@ test('Add schema after register', t => {
|
|
|
794
828
|
method: 'GET',
|
|
795
829
|
url: '/4242'
|
|
796
830
|
}, (err, res) => {
|
|
797
|
-
t.
|
|
798
|
-
t.
|
|
799
|
-
t.
|
|
831
|
+
t.assert.ifError(err)
|
|
832
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
833
|
+
t.assert.deepStrictEqual(res.json(), { id: 4242 })
|
|
834
|
+
testDone()
|
|
800
835
|
})
|
|
801
836
|
})
|
|
802
837
|
|
|
803
|
-
test('Encapsulation isolation for getSchemas', t => {
|
|
838
|
+
test('Encapsulation isolation for getSchemas', (t, testDone) => {
|
|
804
839
|
t.plan(5)
|
|
805
840
|
const fastify = Fastify()
|
|
806
841
|
|
|
@@ -835,15 +870,16 @@ test('Encapsulation isolation for getSchemas', t => {
|
|
|
835
870
|
})
|
|
836
871
|
|
|
837
872
|
fastify.ready(err => {
|
|
838
|
-
t.
|
|
839
|
-
t.
|
|
840
|
-
t.
|
|
841
|
-
t.
|
|
842
|
-
t.
|
|
873
|
+
t.assert.ifError(err)
|
|
874
|
+
t.assert.deepStrictEqual(fastify.getSchemas(), { z: schemas.z })
|
|
875
|
+
t.assert.deepStrictEqual(pluginDeepOneSide.getSchemas(), { z: schemas.z, a: schemas.a })
|
|
876
|
+
t.assert.deepStrictEqual(pluginDeepOne.getSchemas(), { z: schemas.z, b: schemas.b })
|
|
877
|
+
t.assert.deepStrictEqual(pluginDeepTwo.getSchemas(), { z: schemas.z, b: schemas.b, c: schemas.c })
|
|
878
|
+
testDone()
|
|
843
879
|
})
|
|
844
880
|
})
|
|
845
881
|
|
|
846
|
-
test('Use the same schema id in different places', t => {
|
|
882
|
+
test('Use the same schema id in different places', (t, testDone) => {
|
|
847
883
|
t.plan(1)
|
|
848
884
|
const fastify = Fastify()
|
|
849
885
|
|
|
@@ -887,10 +923,13 @@ test('Use the same schema id in different places', t => {
|
|
|
887
923
|
}
|
|
888
924
|
})
|
|
889
925
|
|
|
890
|
-
fastify.ready(err =>
|
|
926
|
+
fastify.ready(err => {
|
|
927
|
+
t.assert.ifError(err)
|
|
928
|
+
testDone()
|
|
929
|
+
})
|
|
891
930
|
})
|
|
892
931
|
|
|
893
|
-
test('Get schema anyway should not add `properties` if allOf is present', t => {
|
|
932
|
+
test('Get schema anyway should not add `properties` if allOf is present', (t, testDone) => {
|
|
894
933
|
t.plan(1)
|
|
895
934
|
const fastify = Fastify()
|
|
896
935
|
|
|
@@ -924,10 +963,13 @@ test('Get schema anyway should not add `properties` if allOf is present', t => {
|
|
|
924
963
|
}
|
|
925
964
|
})
|
|
926
965
|
|
|
927
|
-
fastify.ready(err =>
|
|
966
|
+
fastify.ready(err => {
|
|
967
|
+
t.assert.ifError(err)
|
|
968
|
+
testDone()
|
|
969
|
+
})
|
|
928
970
|
})
|
|
929
971
|
|
|
930
|
-
test('Get schema anyway should not add `properties` if oneOf is present', t => {
|
|
972
|
+
test('Get schema anyway should not add `properties` if oneOf is present', (t, testDone) => {
|
|
931
973
|
t.plan(1)
|
|
932
974
|
const fastify = Fastify()
|
|
933
975
|
|
|
@@ -961,10 +1003,13 @@ test('Get schema anyway should not add `properties` if oneOf is present', t => {
|
|
|
961
1003
|
}
|
|
962
1004
|
})
|
|
963
1005
|
|
|
964
|
-
fastify.ready(err =>
|
|
1006
|
+
fastify.ready(err => {
|
|
1007
|
+
t.assert.ifError(err)
|
|
1008
|
+
testDone()
|
|
1009
|
+
})
|
|
965
1010
|
})
|
|
966
1011
|
|
|
967
|
-
test('Get schema anyway should not add `properties` if anyOf is present', t => {
|
|
1012
|
+
test('Get schema anyway should not add `properties` if anyOf is present', (t, testDone) => {
|
|
968
1013
|
t.plan(1)
|
|
969
1014
|
const fastify = Fastify()
|
|
970
1015
|
|
|
@@ -998,10 +1043,13 @@ test('Get schema anyway should not add `properties` if anyOf is present', t => {
|
|
|
998
1043
|
}
|
|
999
1044
|
})
|
|
1000
1045
|
|
|
1001
|
-
fastify.ready(err =>
|
|
1046
|
+
fastify.ready(err => {
|
|
1047
|
+
t.assert.ifError(err)
|
|
1048
|
+
testDone()
|
|
1049
|
+
})
|
|
1002
1050
|
})
|
|
1003
1051
|
|
|
1004
|
-
test('Shared schema should be ignored in string enum', t => {
|
|
1052
|
+
test('Shared schema should be ignored in string enum', (t, testDone) => {
|
|
1005
1053
|
t.plan(2)
|
|
1006
1054
|
const fastify = Fastify()
|
|
1007
1055
|
|
|
@@ -1021,12 +1069,13 @@ test('Shared schema should be ignored in string enum', t => {
|
|
|
1021
1069
|
})
|
|
1022
1070
|
|
|
1023
1071
|
fastify.inject('/C%23', (err, res) => {
|
|
1024
|
-
t.
|
|
1025
|
-
t.
|
|
1072
|
+
t.assert.ifError(err)
|
|
1073
|
+
t.assert.deepStrictEqual(res.json(), { lang: 'C#' })
|
|
1074
|
+
testDone()
|
|
1026
1075
|
})
|
|
1027
1076
|
})
|
|
1028
1077
|
|
|
1029
|
-
test('Shared schema should NOT be ignored in != string enum', t => {
|
|
1078
|
+
test('Shared schema should NOT be ignored in != string enum', (t, testDone) => {
|
|
1030
1079
|
t.plan(2)
|
|
1031
1080
|
const fastify = Fastify()
|
|
1032
1081
|
|
|
@@ -1053,12 +1102,13 @@ test('Shared schema should NOT be ignored in != string enum', t => {
|
|
|
1053
1102
|
method: 'POST',
|
|
1054
1103
|
payload: { lang: 'C#' }
|
|
1055
1104
|
}, (err, res) => {
|
|
1056
|
-
t.
|
|
1057
|
-
t.
|
|
1105
|
+
t.assert.ifError(err)
|
|
1106
|
+
t.assert.deepStrictEqual(res.json(), { lang: 'C#' })
|
|
1107
|
+
testDone()
|
|
1058
1108
|
})
|
|
1059
1109
|
})
|
|
1060
1110
|
|
|
1061
|
-
test('Case insensitive header validation', t => {
|
|
1111
|
+
test('Case insensitive header validation', (t, testDone) => {
|
|
1062
1112
|
t.plan(2)
|
|
1063
1113
|
const fastify = Fastify()
|
|
1064
1114
|
fastify.get('/', {
|
|
@@ -1082,12 +1132,13 @@ test('Case insensitive header validation', t => {
|
|
|
1082
1132
|
FooBar: 'Baz'
|
|
1083
1133
|
}
|
|
1084
1134
|
}, (err, res) => {
|
|
1085
|
-
t.
|
|
1086
|
-
t.
|
|
1135
|
+
t.assert.ifError(err)
|
|
1136
|
+
t.assert.strictEqual(res.payload, 'Baz')
|
|
1137
|
+
testDone()
|
|
1087
1138
|
})
|
|
1088
1139
|
})
|
|
1089
1140
|
|
|
1090
|
-
test('Not evaluate json-schema $schema keyword', t => {
|
|
1141
|
+
test('Not evaluate json-schema $schema keyword', (t, testDone) => {
|
|
1091
1142
|
t.plan(2)
|
|
1092
1143
|
const fastify = Fastify()
|
|
1093
1144
|
fastify.post('/', {
|
|
@@ -1110,19 +1161,20 @@ test('Not evaluate json-schema $schema keyword', t => {
|
|
|
1110
1161
|
method: 'POST',
|
|
1111
1162
|
body: { hello: 'world', foo: 'bar' }
|
|
1112
1163
|
}, (err, res) => {
|
|
1113
|
-
t.
|
|
1114
|
-
t.
|
|
1164
|
+
t.assert.ifError(err)
|
|
1165
|
+
t.assert.deepStrictEqual(res.json(), { hello: 'world' })
|
|
1166
|
+
testDone()
|
|
1115
1167
|
})
|
|
1116
1168
|
})
|
|
1117
1169
|
|
|
1118
|
-
test('Validation context in validation result', t => {
|
|
1170
|
+
test('Validation context in validation result', (t, testDone) => {
|
|
1119
1171
|
t.plan(5)
|
|
1120
1172
|
const fastify = Fastify()
|
|
1121
1173
|
// custom error handler to expose validation context in response, so we can test it later
|
|
1122
1174
|
fastify.setErrorHandler((err, request, reply) => {
|
|
1123
|
-
t.
|
|
1124
|
-
t.ok(err.validation, 'detailed errors')
|
|
1125
|
-
t.
|
|
1175
|
+
t.assert.strictEqual(err instanceof Error, true)
|
|
1176
|
+
t.assert.ok(err.validation, 'detailed errors')
|
|
1177
|
+
t.assert.strictEqual(err.validationContext, 'body')
|
|
1126
1178
|
reply.code(400).send()
|
|
1127
1179
|
})
|
|
1128
1180
|
fastify.post('/', {
|
|
@@ -1142,12 +1194,13 @@ test('Validation context in validation result', t => {
|
|
|
1142
1194
|
url: '/',
|
|
1143
1195
|
payload: {} // body lacks required field, will fail validation
|
|
1144
1196
|
}, (err, res) => {
|
|
1145
|
-
t.
|
|
1146
|
-
t.
|
|
1197
|
+
t.assert.ifError(err)
|
|
1198
|
+
t.assert.strictEqual(res.statusCode, 400)
|
|
1199
|
+
testDone()
|
|
1147
1200
|
})
|
|
1148
1201
|
})
|
|
1149
1202
|
|
|
1150
|
-
test('The schema build should not modify the input', t => {
|
|
1203
|
+
test('The schema build should not modify the input', (t, testDone) => {
|
|
1151
1204
|
t.plan(3)
|
|
1152
1205
|
const fastify = Fastify()
|
|
1153
1206
|
|
|
@@ -1205,14 +1258,15 @@ test('The schema build should not modify the input', t => {
|
|
|
1205
1258
|
}
|
|
1206
1259
|
})
|
|
1207
1260
|
|
|
1208
|
-
t.ok(first.$id)
|
|
1261
|
+
t.assert.ok(first.$id)
|
|
1209
1262
|
fastify.ready(err => {
|
|
1210
|
-
t.
|
|
1211
|
-
t.ok(first.$id)
|
|
1263
|
+
t.assert.ifError(err)
|
|
1264
|
+
t.assert.ok(first.$id)
|
|
1265
|
+
testDone()
|
|
1212
1266
|
})
|
|
1213
1267
|
})
|
|
1214
1268
|
|
|
1215
|
-
test('Cross schema reference with encapsulation references', t => {
|
|
1269
|
+
test('Cross schema reference with encapsulation references', (t, testDone) => {
|
|
1216
1270
|
t.plan(1)
|
|
1217
1271
|
|
|
1218
1272
|
const fastify = Fastify()
|
|
@@ -1262,29 +1316,30 @@ test('Cross schema reference with encapsulation references', t => {
|
|
|
1262
1316
|
fastify.get('/get', { schema: { params: refItem, response: { 200: refItem } } }, () => { })
|
|
1263
1317
|
|
|
1264
1318
|
fastify.ready(err => {
|
|
1265
|
-
t.
|
|
1319
|
+
t.assert.ifError(err)
|
|
1320
|
+
testDone()
|
|
1266
1321
|
})
|
|
1267
1322
|
})
|
|
1268
1323
|
|
|
1269
|
-
test('Check how many AJV instances are built #1', t => {
|
|
1324
|
+
test('Check how many AJV instances are built #1', (t, testDone) => {
|
|
1270
1325
|
t.plan(12)
|
|
1271
1326
|
const fastify = Fastify()
|
|
1272
1327
|
addRandomRoute(fastify) // this trigger the schema validation creation
|
|
1273
|
-
t.
|
|
1328
|
+
t.assert.ok(!fastify.validatorCompiler, 'validator not initialized')
|
|
1274
1329
|
|
|
1275
1330
|
const instances = []
|
|
1276
1331
|
fastify.register((instance, opts, done) => {
|
|
1277
|
-
t.
|
|
1332
|
+
t.assert.ok(!fastify.validatorCompiler, 'validator not initialized')
|
|
1278
1333
|
instances.push(instance)
|
|
1279
1334
|
done()
|
|
1280
1335
|
})
|
|
1281
1336
|
fastify.register((instance, opts, done) => {
|
|
1282
|
-
t.
|
|
1337
|
+
t.assert.ok(!fastify.validatorCompiler, 'validator not initialized')
|
|
1283
1338
|
addRandomRoute(instance)
|
|
1284
1339
|
instances.push(instance)
|
|
1285
1340
|
done()
|
|
1286
1341
|
instance.register((instance, opts, done) => {
|
|
1287
|
-
t.
|
|
1342
|
+
t.assert.ok(!fastify.validatorCompiler, 'validator not initialized')
|
|
1288
1343
|
addRandomRoute(instance)
|
|
1289
1344
|
instances.push(instance)
|
|
1290
1345
|
done()
|
|
@@ -1292,18 +1347,19 @@ test('Check how many AJV instances are built #1', t => {
|
|
|
1292
1347
|
})
|
|
1293
1348
|
|
|
1294
1349
|
fastify.ready(err => {
|
|
1295
|
-
t.
|
|
1350
|
+
t.assert.ifError(err)
|
|
1296
1351
|
|
|
1297
|
-
t.ok(fastify.validatorCompiler, 'validator initialized on preReady')
|
|
1352
|
+
t.assert.ok(fastify.validatorCompiler, 'validator initialized on preReady')
|
|
1298
1353
|
fastify.validatorCompiler.checkPointer = true
|
|
1299
1354
|
instances.forEach(i => {
|
|
1300
|
-
t.ok(i.validatorCompiler, 'validator initialized on preReady')
|
|
1301
|
-
t.
|
|
1355
|
+
t.assert.ok(i.validatorCompiler, 'validator initialized on preReady')
|
|
1356
|
+
t.assert.strictEqual(i.validatorCompiler.checkPointer, true, 'validator is only one for all the instances')
|
|
1302
1357
|
})
|
|
1358
|
+
testDone()
|
|
1303
1359
|
})
|
|
1304
1360
|
})
|
|
1305
1361
|
|
|
1306
|
-
test('onReady hook has the compilers ready', t => {
|
|
1362
|
+
test('onReady hook has the compilers ready', (t, testDone) => {
|
|
1307
1363
|
t.plan(6)
|
|
1308
1364
|
|
|
1309
1365
|
const fastify = Fastify()
|
|
@@ -1317,16 +1373,16 @@ test('onReady hook has the compilers ready', t => {
|
|
|
1317
1373
|
})
|
|
1318
1374
|
|
|
1319
1375
|
fastify.addHook('onReady', function (done) {
|
|
1320
|
-
t.ok(this.validatorCompiler)
|
|
1321
|
-
t.ok(this.serializerCompiler)
|
|
1376
|
+
t.assert.ok(this.validatorCompiler)
|
|
1377
|
+
t.assert.ok(this.serializerCompiler)
|
|
1322
1378
|
done()
|
|
1323
1379
|
})
|
|
1324
1380
|
|
|
1325
1381
|
let hookCallCounter = 0
|
|
1326
1382
|
fastify.register(async (i, o) => {
|
|
1327
1383
|
i.addHook('onReady', function (done) {
|
|
1328
|
-
t.ok(this.validatorCompiler)
|
|
1329
|
-
t.ok(this.serializerCompiler)
|
|
1384
|
+
t.assert.ok(this.validatorCompiler)
|
|
1385
|
+
t.assert.ok(this.serializerCompiler)
|
|
1330
1386
|
done()
|
|
1331
1387
|
})
|
|
1332
1388
|
|
|
@@ -1339,44 +1395,45 @@ test('onReady hook has the compilers ready', t => {
|
|
|
1339
1395
|
})
|
|
1340
1396
|
|
|
1341
1397
|
fastify.ready(err => {
|
|
1342
|
-
t.
|
|
1343
|
-
t.
|
|
1398
|
+
t.assert.ifError(err)
|
|
1399
|
+
t.assert.strictEqual(hookCallCounter, 1, 'it is called once')
|
|
1400
|
+
testDone()
|
|
1344
1401
|
})
|
|
1345
1402
|
})
|
|
1346
1403
|
|
|
1347
|
-
test('Check how many AJV instances are built #2 - verify validatorPool', t => {
|
|
1404
|
+
test('Check how many AJV instances are built #2 - verify validatorPool', (t, testDone) => {
|
|
1348
1405
|
t.plan(13)
|
|
1349
1406
|
const fastify = Fastify()
|
|
1350
|
-
t.
|
|
1407
|
+
t.assert.ok(!fastify.validatorCompiler, 'validator not initialized')
|
|
1351
1408
|
|
|
1352
1409
|
fastify.register(function sibling1 (instance, opts, done) {
|
|
1353
1410
|
addRandomRoute(instance)
|
|
1354
|
-
t.
|
|
1411
|
+
t.assert.ok(!instance.validatorCompiler, 'validator not initialized')
|
|
1355
1412
|
instance.ready(() => {
|
|
1356
|
-
t.ok(instance.validatorCompiler, 'validator is initialized')
|
|
1413
|
+
t.assert.ok(instance.validatorCompiler, 'validator is initialized')
|
|
1357
1414
|
instance.validatorCompiler.sharedPool = 1
|
|
1358
1415
|
})
|
|
1359
1416
|
instance.after(() => {
|
|
1360
|
-
t.
|
|
1417
|
+
t.assert.ok(!instance.validatorCompiler, 'validator not initialized')
|
|
1361
1418
|
})
|
|
1362
1419
|
done()
|
|
1363
1420
|
})
|
|
1364
1421
|
|
|
1365
1422
|
fastify.register(function sibling2 (instance, opts, done) {
|
|
1366
1423
|
addRandomRoute(instance)
|
|
1367
|
-
t.
|
|
1424
|
+
t.assert.ok(!instance.validatorCompiler, 'validator not initialized')
|
|
1368
1425
|
instance.ready(() => {
|
|
1369
|
-
t.
|
|
1426
|
+
t.assert.strictEqual(instance.validatorCompiler.sharedPool, 1, 'this context must share the validator with the same schemas')
|
|
1370
1427
|
instance.validatorCompiler.sharedPool = 2
|
|
1371
1428
|
})
|
|
1372
1429
|
instance.after(() => {
|
|
1373
|
-
t.
|
|
1430
|
+
t.assert.ok(!instance.validatorCompiler, 'validator not initialized')
|
|
1374
1431
|
})
|
|
1375
1432
|
|
|
1376
1433
|
instance.register((instance, opts, done) => {
|
|
1377
|
-
t.
|
|
1434
|
+
t.assert.ok(!instance.validatorCompiler, 'validator not initialized')
|
|
1378
1435
|
instance.ready(() => {
|
|
1379
|
-
t.
|
|
1436
|
+
t.assert.strictEqual(instance.validatorCompiler.sharedPool, 2, 'this context must share the validator of the parent')
|
|
1380
1437
|
})
|
|
1381
1438
|
done()
|
|
1382
1439
|
})
|
|
@@ -1389,15 +1446,18 @@ test('Check how many AJV instances are built #2 - verify validatorPool', t => {
|
|
|
1389
1446
|
// this trigger to don't reuse the same compiler pool
|
|
1390
1447
|
instance.addSchema({ $id: 'diff', type: 'object' })
|
|
1391
1448
|
|
|
1392
|
-
t.
|
|
1449
|
+
t.assert.ok(!instance.validatorCompiler, 'validator not initialized')
|
|
1393
1450
|
instance.ready(() => {
|
|
1394
|
-
t.ok(instance.validatorCompiler, 'validator is initialized')
|
|
1395
|
-
t.
|
|
1451
|
+
t.assert.ok(instance.validatorCompiler, 'validator is initialized')
|
|
1452
|
+
t.assert.ok(!instance.validatorCompiler.sharedPool, 'this context has its own compiler')
|
|
1396
1453
|
})
|
|
1397
1454
|
done()
|
|
1398
1455
|
})
|
|
1399
1456
|
|
|
1400
|
-
fastify.ready(err => {
|
|
1457
|
+
fastify.ready(err => {
|
|
1458
|
+
t.assert.ifError(err)
|
|
1459
|
+
testDone()
|
|
1460
|
+
})
|
|
1401
1461
|
})
|
|
1402
1462
|
|
|
1403
1463
|
function addRandomRoute (server) {
|
|
@@ -1407,7 +1467,7 @@ function addRandomRoute (server) {
|
|
|
1407
1467
|
)
|
|
1408
1468
|
}
|
|
1409
1469
|
|
|
1410
|
-
test('Add schema order should not break the startup', t => {
|
|
1470
|
+
test('Add schema order should not break the startup', (t, testDone) => {
|
|
1411
1471
|
t.plan(1)
|
|
1412
1472
|
const fastify = Fastify()
|
|
1413
1473
|
|
|
@@ -1433,10 +1493,13 @@ test('Add schema order should not break the startup', t => {
|
|
|
1433
1493
|
}
|
|
1434
1494
|
}, () => {})
|
|
1435
1495
|
|
|
1436
|
-
fastify.ready(err => {
|
|
1496
|
+
fastify.ready(err => {
|
|
1497
|
+
t.assert.ifError(err)
|
|
1498
|
+
testDone()
|
|
1499
|
+
})
|
|
1437
1500
|
})
|
|
1438
1501
|
|
|
1439
|
-
test('The schema compiler recreate itself if needed', t => {
|
|
1502
|
+
test('The schema compiler recreate itself if needed', (t, testDone) => {
|
|
1440
1503
|
t.plan(1)
|
|
1441
1504
|
const fastify = Fastify()
|
|
1442
1505
|
|
|
@@ -1463,23 +1526,26 @@ test('The schema compiler recreate itself if needed', t => {
|
|
|
1463
1526
|
done()
|
|
1464
1527
|
})
|
|
1465
1528
|
|
|
1466
|
-
fastify.ready(err => {
|
|
1529
|
+
fastify.ready(err => {
|
|
1530
|
+
t.assert.ifError(err)
|
|
1531
|
+
testDone()
|
|
1532
|
+
})
|
|
1467
1533
|
})
|
|
1468
1534
|
|
|
1469
1535
|
test('Schema controller setter', t => {
|
|
1470
1536
|
t.plan(2)
|
|
1471
1537
|
Fastify({ schemaController: {} })
|
|
1472
|
-
t.
|
|
1538
|
+
t.assert.ok('allow empty object')
|
|
1473
1539
|
|
|
1474
1540
|
try {
|
|
1475
1541
|
Fastify({ schemaController: { bucket: {} } })
|
|
1476
1542
|
t.fail('the bucket option must be a function')
|
|
1477
1543
|
} catch (err) {
|
|
1478
|
-
t.
|
|
1544
|
+
t.assert.strictEqual(err.message, "schemaController.bucket option should be a function, instead got 'object'")
|
|
1479
1545
|
}
|
|
1480
1546
|
})
|
|
1481
1547
|
|
|
1482
|
-
test('Schema controller bucket', t => {
|
|
1548
|
+
test('Schema controller bucket', (t, testDone) => {
|
|
1483
1549
|
t.plan(10)
|
|
1484
1550
|
|
|
1485
1551
|
let added = 0
|
|
@@ -1489,7 +1555,7 @@ test('Schema controller bucket', t => {
|
|
|
1489
1555
|
|
|
1490
1556
|
function factoryBucket (storeInit) {
|
|
1491
1557
|
builtBucket++
|
|
1492
|
-
t.
|
|
1558
|
+
t.assert.deepStrictEqual(initStoreQueue.pop(), storeInit)
|
|
1493
1559
|
const store = new Map(storeInit)
|
|
1494
1560
|
return {
|
|
1495
1561
|
add (schema) {
|
|
@@ -1516,13 +1582,13 @@ test('Schema controller bucket', t => {
|
|
|
1516
1582
|
fastify.register(async (instance) => {
|
|
1517
1583
|
instance.addSchema({ $id: 'b', type: 'string' })
|
|
1518
1584
|
instance.addHook('onReady', function (done) {
|
|
1519
|
-
t.
|
|
1585
|
+
t.assert.strictEqual(instance.getSchemas().size, 2)
|
|
1520
1586
|
done()
|
|
1521
1587
|
})
|
|
1522
1588
|
instance.register(async (subinstance) => {
|
|
1523
1589
|
subinstance.addSchema({ $id: 'c', type: 'string' })
|
|
1524
1590
|
subinstance.addHook('onReady', function (done) {
|
|
1525
|
-
t.
|
|
1591
|
+
t.assert.strictEqual(subinstance.getSchemas().size, 3)
|
|
1526
1592
|
done()
|
|
1527
1593
|
})
|
|
1528
1594
|
})
|
|
@@ -1530,7 +1596,7 @@ test('Schema controller bucket', t => {
|
|
|
1530
1596
|
|
|
1531
1597
|
fastify.register(async (instance) => {
|
|
1532
1598
|
instance.addHook('onReady', function (done) {
|
|
1533
|
-
t.
|
|
1599
|
+
t.assert.strictEqual(instance.getSchemas().size, 1)
|
|
1534
1600
|
done()
|
|
1535
1601
|
})
|
|
1536
1602
|
})
|
|
@@ -1538,20 +1604,21 @@ test('Schema controller bucket', t => {
|
|
|
1538
1604
|
fastify.addSchema({ $id: 'a', type: 'string' })
|
|
1539
1605
|
|
|
1540
1606
|
fastify.ready(err => {
|
|
1541
|
-
t.
|
|
1542
|
-
t.
|
|
1543
|
-
t.
|
|
1607
|
+
t.assert.ifError(err)
|
|
1608
|
+
t.assert.strictEqual(added, 3, 'three schema added')
|
|
1609
|
+
t.assert.strictEqual(builtBucket, 4, 'one bucket built for every register call + 1 for the root instance')
|
|
1610
|
+
testDone()
|
|
1544
1611
|
})
|
|
1545
1612
|
})
|
|
1546
1613
|
|
|
1547
|
-
test('setSchemaController per instance', t => {
|
|
1614
|
+
test('setSchemaController per instance', (t, testDone) => {
|
|
1548
1615
|
t.plan(7)
|
|
1549
1616
|
const fastify = Fastify({})
|
|
1550
1617
|
|
|
1551
1618
|
fastify.register(async (instance1) => {
|
|
1552
1619
|
instance1.setSchemaController({
|
|
1553
1620
|
bucket: function factoryBucket (storeInit) {
|
|
1554
|
-
t.
|
|
1621
|
+
t.assert.ok('instance1 has created the bucket')
|
|
1555
1622
|
return {
|
|
1556
1623
|
add (schema) { t.fail('add is not called') },
|
|
1557
1624
|
getSchema (id) { t.fail('getSchema is not called') },
|
|
@@ -1566,19 +1633,19 @@ test('setSchemaController per instance', t => {
|
|
|
1566
1633
|
|
|
1567
1634
|
instance2.setSchemaController({
|
|
1568
1635
|
bucket: function factoryBucket (storeInit) {
|
|
1569
|
-
t.
|
|
1636
|
+
t.assert.ok('instance2 has created the bucket')
|
|
1570
1637
|
const map = {}
|
|
1571
1638
|
return {
|
|
1572
1639
|
add (schema) {
|
|
1573
|
-
t.
|
|
1640
|
+
t.assert.strictEqual(schema.$id, bSchema.$id, 'add is called')
|
|
1574
1641
|
map[schema.$id] = schema
|
|
1575
1642
|
},
|
|
1576
1643
|
getSchema (id) {
|
|
1577
|
-
t.
|
|
1644
|
+
t.assert.ok('getSchema is called')
|
|
1578
1645
|
return map[id]
|
|
1579
1646
|
},
|
|
1580
1647
|
getSchemas () {
|
|
1581
|
-
t.
|
|
1648
|
+
t.assert.ok('getSchemas is called')
|
|
1582
1649
|
}
|
|
1583
1650
|
}
|
|
1584
1651
|
}
|
|
@@ -1588,12 +1655,15 @@ test('setSchemaController per instance', t => {
|
|
|
1588
1655
|
|
|
1589
1656
|
instance2.addHook('onReady', function (done) {
|
|
1590
1657
|
instance2.getSchemas()
|
|
1591
|
-
t.
|
|
1658
|
+
t.assert.deepStrictEqual(instance2.getSchema('b'), bSchema, 'the schema are loaded')
|
|
1592
1659
|
done()
|
|
1593
1660
|
})
|
|
1594
1661
|
})
|
|
1595
1662
|
|
|
1596
|
-
fastify.ready(err => {
|
|
1663
|
+
fastify.ready(err => {
|
|
1664
|
+
t.assert.ifError(err)
|
|
1665
|
+
testDone()
|
|
1666
|
+
})
|
|
1597
1667
|
})
|
|
1598
1668
|
|
|
1599
1669
|
test('setSchemaController: Inherits correctly parent schemas with a customized validator instance', async t => {
|
|
@@ -1628,8 +1698,8 @@ test('setSchemaController: Inherits correctly parent schemas with a customized v
|
|
|
1628
1698
|
compilersFactory: {
|
|
1629
1699
|
buildValidator: function (externalSchemas) {
|
|
1630
1700
|
const schemaKeys = Object.keys(externalSchemas)
|
|
1631
|
-
t.
|
|
1632
|
-
t.
|
|
1701
|
+
t.assert.strictEqual(schemaKeys.length, 2, 'Contains same number of schemas')
|
|
1702
|
+
t.assert.deepStrictEqual([someSchema, errorResponseSchema], Object.values(externalSchemas), 'Contains expected schemas')
|
|
1633
1703
|
for (const key of schemaKeys) {
|
|
1634
1704
|
if (customAjv.getSchema(key) == null) {
|
|
1635
1705
|
customAjv.addSchema(externalSchemas[key], key)
|
|
@@ -1678,9 +1748,9 @@ test('setSchemaController: Inherits correctly parent schemas with a customized v
|
|
|
1678
1748
|
})
|
|
1679
1749
|
const json = res.json()
|
|
1680
1750
|
|
|
1681
|
-
t.
|
|
1682
|
-
t.
|
|
1683
|
-
t.
|
|
1751
|
+
t.assert.strictEqual(json.message, 'querystring/msg must be array')
|
|
1752
|
+
t.assert.strictEqual(json.statusCode, 400)
|
|
1753
|
+
t.assert.strictEqual(res.statusCode, 400, 'Should not coerce the string into array')
|
|
1684
1754
|
})
|
|
1685
1755
|
|
|
1686
1756
|
test('setSchemaController: Inherits buildSerializer from parent if not present within the instance', async t => {
|
|
@@ -1786,17 +1856,17 @@ test('setSchemaController: Inherits buildSerializer from parent if not present w
|
|
|
1786
1856
|
method: 'GET',
|
|
1787
1857
|
url: '/',
|
|
1788
1858
|
query: {
|
|
1789
|
-
msg: 'string'
|
|
1859
|
+
msg: ['string']
|
|
1790
1860
|
}
|
|
1791
1861
|
})
|
|
1792
1862
|
const json = res.json()
|
|
1793
1863
|
|
|
1794
|
-
t.
|
|
1795
|
-
t.
|
|
1796
|
-
t.
|
|
1797
|
-
t.
|
|
1798
|
-
t.
|
|
1799
|
-
t.
|
|
1864
|
+
t.assert.strictEqual(json.statusCode, 400)
|
|
1865
|
+
t.assert.strictEqual(json.message, 'querystring/msg must be array')
|
|
1866
|
+
t.assert.strictEqual(rootSerializerCalled, 1, 'Should be called from the child')
|
|
1867
|
+
t.assert.strictEqual(rootValidatorCalled, 0, 'Should not be called from the child')
|
|
1868
|
+
t.assert.strictEqual(childValidatorCalled, 1, 'Should be called from the child')
|
|
1869
|
+
t.assert.strictEqual(res.statusCode, 400, 'Should not coerce the string into array')
|
|
1800
1870
|
})
|
|
1801
1871
|
|
|
1802
1872
|
test('setSchemaController: Inherits buildValidator from parent if not present within the instance', async t => {
|
|
@@ -1911,12 +1981,12 @@ test('setSchemaController: Inherits buildValidator from parent if not present wi
|
|
|
1911
1981
|
})
|
|
1912
1982
|
const json = res.json()
|
|
1913
1983
|
|
|
1914
|
-
t.
|
|
1915
|
-
t.
|
|
1916
|
-
t.
|
|
1917
|
-
t.
|
|
1918
|
-
t.
|
|
1919
|
-
t.
|
|
1984
|
+
t.assert.strictEqual(json.statusCode, 400)
|
|
1985
|
+
t.assert.strictEqual(json.message, 'querystring/msg must be array')
|
|
1986
|
+
t.assert.strictEqual(rootSerializerCalled, 0, 'Should be called from the child')
|
|
1987
|
+
t.assert.strictEqual(rootValidatorCalled, 1, 'Should not be called from the child')
|
|
1988
|
+
t.assert.strictEqual(childSerializerCalled, 1, 'Should be called from the child')
|
|
1989
|
+
t.assert.strictEqual(res.statusCode, 400, 'Should not coerce the string into array')
|
|
1920
1990
|
})
|
|
1921
1991
|
|
|
1922
1992
|
test('Should throw if not default validator passed', async t => {
|
|
@@ -1938,8 +2008,8 @@ test('Should throw if not default validator passed', async t => {
|
|
|
1938
2008
|
compilersFactory: {
|
|
1939
2009
|
buildValidator: function (externalSchemas) {
|
|
1940
2010
|
const schemaKeys = Object.keys(externalSchemas)
|
|
1941
|
-
t.
|
|
1942
|
-
t.
|
|
2011
|
+
t.assert.strictEqual(schemaKeys.length, 2)
|
|
2012
|
+
t.assert.deepStrictEqual(schemaKeys, ['some', 'another'])
|
|
1943
2013
|
|
|
1944
2014
|
for (const key of schemaKeys) {
|
|
1945
2015
|
if (customAjv.getSchema(key) == null) {
|
|
@@ -2003,10 +2073,10 @@ test('Should throw if not default validator passed', async t => {
|
|
|
2003
2073
|
}
|
|
2004
2074
|
})
|
|
2005
2075
|
|
|
2006
|
-
t.
|
|
2007
|
-
t.
|
|
2076
|
+
t.assert.strictEqual(res.json().message, 'querystring/msg must be array')
|
|
2077
|
+
t.assert.strictEqual(res.statusCode, 400, 'Should not coerce the string into array')
|
|
2008
2078
|
} catch (err) {
|
|
2009
|
-
t.
|
|
2079
|
+
t.assert.ifError(err)
|
|
2010
2080
|
}
|
|
2011
2081
|
})
|
|
2012
2082
|
|
|
@@ -2070,14 +2140,14 @@ test('Should coerce the array if the default validator is used', async t => {
|
|
|
2070
2140
|
}
|
|
2071
2141
|
})
|
|
2072
2142
|
|
|
2073
|
-
t.
|
|
2074
|
-
t.
|
|
2143
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
2144
|
+
t.assert.deepStrictEqual(res.json(), { msg: ['string'] }, 'Should coerce the string into array')
|
|
2075
2145
|
} catch (err) {
|
|
2076
|
-
t.
|
|
2146
|
+
t.assert.ifError(err)
|
|
2077
2147
|
}
|
|
2078
2148
|
})
|
|
2079
2149
|
|
|
2080
|
-
test('Should return a human-friendly error if response status codes are not specified', t => {
|
|
2150
|
+
test('Should return a human-friendly error if response status codes are not specified', (t, testDone) => {
|
|
2081
2151
|
t.plan(2)
|
|
2082
2152
|
const fastify = Fastify()
|
|
2083
2153
|
|
|
@@ -2096,8 +2166,9 @@ test('Should return a human-friendly error if response status codes are not spec
|
|
|
2096
2166
|
})
|
|
2097
2167
|
|
|
2098
2168
|
fastify.ready(err => {
|
|
2099
|
-
t.
|
|
2100
|
-
t.
|
|
2169
|
+
t.assert.strictEqual(err.code, 'FST_ERR_SCH_SERIALIZATION_BUILD')
|
|
2170
|
+
t.assert.strictEqual(err.message, 'Failed building the serialization schema for GET: /, due to error response schemas should be nested under a valid status code, e.g { 2xx: { type: "object" } }')
|
|
2171
|
+
testDone()
|
|
2101
2172
|
})
|
|
2102
2173
|
})
|
|
2103
2174
|
|
|
@@ -2110,7 +2181,7 @@ test('setSchemaController: custom validator instance should not mutate headers s
|
|
|
2110
2181
|
compilersFactory: {
|
|
2111
2182
|
buildValidator: function () {
|
|
2112
2183
|
return ({ schema, method, url, httpPart }) => {
|
|
2113
|
-
t.
|
|
2184
|
+
t.assert.ok(schema instanceof Headers)
|
|
2114
2185
|
return () => {}
|
|
2115
2186
|
}
|
|
2116
2187
|
}
|