You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					949 lines
				
				18 KiB
			
		
		
			
		
	
	
					949 lines
				
				18 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const { test } = require('tap')
							 | 
						||
| 
								 | 
							
								const Fastify = require('..')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const AJV = require('ajv')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const customSchemaCompilers = {
							 | 
						||
| 
								 | 
							
								  body: new AJV({
							 | 
						||
| 
								 | 
							
								    coerceTypes: false
							 | 
						||
| 
								 | 
							
								  }),
							 | 
						||
| 
								 | 
							
								  params: new AJV({
							 | 
						||
| 
								 | 
							
								    coerceTypes: true
							 | 
						||
| 
								 | 
							
								  }),
							 | 
						||
| 
								 | 
							
								  querystring: new AJV({
							 | 
						||
| 
								 | 
							
								    coerceTypes: true
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const customValidatorCompiler = req => {
							 | 
						||
| 
								 | 
							
								  if (!req.httpPart) {
							 | 
						||
| 
								 | 
							
								    throw new Error('Missing httpPart')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const compiler = customSchemaCompilers[req.httpPart]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!compiler) {
							 | 
						||
| 
								 | 
							
								    throw new Error(`Missing compiler for ${req.httpPart}`)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return compiler.compile(req.schema)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schemaA = {
							 | 
						||
| 
								 | 
							
								  $id: 'urn:schema:foo',
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  definitions: {
							 | 
						||
| 
								 | 
							
								    foo: { type: 'integer' }
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    foo: { $ref: '#/definitions/foo' }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								const schemaBRefToA = {
							 | 
						||
| 
								 | 
							
								  $id: 'urn:schema:response',
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  required: ['foo'],
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    foo: { $ref: 'urn:schema:foo#/definitions/foo' }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schemaCRefToB = {
							 | 
						||
| 
								 | 
							
								  $id: 'urn:schema:request',
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  required: ['foo'],
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    foo: { $ref: 'urn:schema:response#/properties/foo' }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const schemaArtist = {
							 | 
						||
| 
								 | 
							
								  type: 'object',
							 | 
						||
| 
								 | 
							
								  properties: {
							 | 
						||
| 
								 | 
							
								    name: { type: 'string' },
							 | 
						||
| 
								 | 
							
								    work: { type: 'string' }
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  required: ['name', 'work']
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Basic validation test', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(6)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: schemaArtist
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, function (req, reply) {
							 | 
						||
| 
								 | 
							
								    reply.code(200).send(req.body.name)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      name: 'michelangelo',
							 | 
						||
| 
								 | 
							
								      work: 'sculptor, painter, architect and poet'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    url: '/'
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.same(res.payload, 'michelangelo')
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    payload: { name: 'michelangelo' },
							 | 
						||
| 
								 | 
							
								    url: '/'
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { statusCode: 400, error: 'Bad Request', message: "body should have required property 'work'" })
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('External AJV instance', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(4)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  const ajv = new AJV()
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaA)
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaBRefToA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // the user must provide the schemas to fastify also
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaA)
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaBRefToA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
							 | 
						||
| 
								 | 
							
								    return ajv.compile(schema)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send({ foo: 1 }) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: schemaCRefToB,
							 | 
						||
| 
								 | 
							
								      response: {
							 | 
						||
| 
								 | 
							
								        '2xx': ajv.getSchema('urn:schema:response').schema
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { foo: 42 }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { foo: 'not a number' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Encapsulation', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(19)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  const ajv = new AJV()
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaA)
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaBRefToA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // the user must provide the schemas to fastify also
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaA)
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaBRefToA)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.register((instance, opts, done) => {
							 | 
						||
| 
								 | 
							
								    const validator = ({ schema, method, url, httpPart }) => {
							 | 
						||
| 
								 | 
							
								      return ajv.compile(schema)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    instance.setValidatorCompiler(validator)
							 | 
						||
| 
								 | 
							
								    instance.post('/one', {
							 | 
						||
| 
								 | 
							
								      handler (req, reply) { reply.send({ foo: 'one' }) },
							 | 
						||
| 
								 | 
							
								      schema: {
							 | 
						||
| 
								 | 
							
								        body: ajv.getSchema('urn:schema:response').schema
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    instance.register((instance, opts, done) => {
							 | 
						||
| 
								 | 
							
								      instance.post('/two', {
							 | 
						||
| 
								 | 
							
								        handler (req, reply) {
							 | 
						||
| 
								 | 
							
								          t.same(instance.validatorCompiler, validator)
							 | 
						||
| 
								 | 
							
								          reply.send({ foo: 'two' })
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        schema: {
							 | 
						||
| 
								 | 
							
								          body: ajv.getSchema('urn:schema:response').schema
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const anotherValidator = ({ schema, method, url, httpPart }) => {
							 | 
						||
| 
								 | 
							
								        return () => { return true } // always valid
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      instance.post('/three', {
							 | 
						||
| 
								 | 
							
								        validatorCompiler: anotherValidator,
							 | 
						||
| 
								 | 
							
								        handler (req, reply) {
							 | 
						||
| 
								 | 
							
								          t.same(instance.validatorCompiler, validator, 'the route validator does not change the instance one')
							 | 
						||
| 
								 | 
							
								          reply.send({ foo: 'three' })
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        schema: {
							 | 
						||
| 
								 | 
							
								          body: ajv.getSchema('urn:schema:response').schema
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      done()
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.register((instance, opts, done) => {
							 | 
						||
| 
								 | 
							
								    instance.post('/clean', function (req, reply) {
							 | 
						||
| 
								 | 
							
								      t.equal(instance.validatorCompiler, undefined)
							 | 
						||
| 
								 | 
							
								      reply.send({ foo: 'bar' })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/one',
							 | 
						||
| 
								 | 
							
								    payload: { foo: 1 }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { foo: 'one' })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/one',
							 | 
						||
| 
								 | 
							
								    payload: { wrongFoo: 'bar' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/two',
							 | 
						||
| 
								 | 
							
								    payload: { foo: 2 }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { foo: 'two' })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/two',
							 | 
						||
| 
								 | 
							
								    payload: { wrongFoo: 'bar' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/three',
							 | 
						||
| 
								 | 
							
								    payload: { wrongFoo: 'but works' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { foo: 'three' })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/clean',
							 | 
						||
| 
								 | 
							
								    payload: { wrongFoo: 'bar' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { foo: 'bar' })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Triple $ref with a simple $id', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(6)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  const ajv = new AJV()
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaA)
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaBRefToA)
							 | 
						||
| 
								 | 
							
								  ajv.addSchema(schemaCRefToB)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // the user must provide the schemas to fastify also
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaA)
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaBRefToA)
							 | 
						||
| 
								 | 
							
								  fastify.addSchema(schemaCRefToB)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
							 | 
						||
| 
								 | 
							
								    return ajv.compile(schema)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send({ foo: 105, bar: 'foo' }) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: ajv.getSchema('urn:schema:request').schema,
							 | 
						||
| 
								 | 
							
								      response: {
							 | 
						||
| 
								 | 
							
								        '2xx': ajv.getSchema('urn:schema:response').schema
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { foo: 43 }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { foo: 105 })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { fool: 'bar' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    t.same(res.json().message, "body should have required property 'foo'")
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Extending schema', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(4)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'address.id',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    definitions: {
							 | 
						||
| 
								 | 
							
								      address: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          city: { type: 'string' },
							 | 
						||
| 
								 | 
							
								          state: { type: 'string' }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        required: ['city', 'state']
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send('works') },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          billingAddress: { $ref: 'address.id#/definitions/address' },
							 | 
						||
| 
								 | 
							
								          shippingAddress: {
							 | 
						||
| 
								 | 
							
								            allOf: [
							 | 
						||
| 
								 | 
							
								              { $ref: 'address.id#/definitions/address' },
							 | 
						||
| 
								 | 
							
								              {
							 | 
						||
| 
								 | 
							
								                properties: { type: { enum: ['residential', 'business'] } },
							 | 
						||
| 
								 | 
							
								                required: ['type']
							 | 
						||
| 
								 | 
							
								              }
							 | 
						||
| 
								 | 
							
								            ]
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      shippingAddress: {
							 | 
						||
| 
								 | 
							
								        city: 'Forlì',
							 | 
						||
| 
								 | 
							
								        state: 'FC'
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      shippingAddress: {
							 | 
						||
| 
								 | 
							
								        city: 'Forlì',
							 | 
						||
| 
								 | 
							
								        state: 'FC',
							 | 
						||
| 
								 | 
							
								        type: 'business'
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Should work with nested ids', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(6)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      id: { type: 'number' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'greetings',
							 | 
						||
| 
								 | 
							
								    type: 'string'
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/:id', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send(typeof req.params.id) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      params: { $ref: 'test#' },
							 | 
						||
| 
								 | 
							
								      body: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          hello: { $ref: 'greetings#' }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/123',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      hello: 'world'
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.equal(res.payload, 'number')
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/abc',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      hello: 'world'
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    t.equal(res.json().message, 'params.id should be number')
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Use the same schema across multiple routes', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(8)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      id: { type: 'number' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/first/:id', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send(typeof req.params.id) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      params: { $ref: 'test#' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/second/:id', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send(typeof req.params.id) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      params: { $ref: 'test#' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ;[
							 | 
						||
| 
								 | 
							
								    '/first/123',
							 | 
						||
| 
								 | 
							
								    '/second/123'
							 | 
						||
| 
								 | 
							
								  ].forEach(url => {
							 | 
						||
| 
								 | 
							
								    fastify.inject({
							 | 
						||
| 
								 | 
							
								      url,
							 | 
						||
| 
								 | 
							
								      method: 'GET'
							 | 
						||
| 
								 | 
							
								    }, (err, res) => {
							 | 
						||
| 
								 | 
							
								      t.error(err)
							 | 
						||
| 
								 | 
							
								      t.equal(res.payload, 'number')
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ;[
							 | 
						||
| 
								 | 
							
								    '/first/abc',
							 | 
						||
| 
								 | 
							
								    '/second/abc'
							 | 
						||
| 
								 | 
							
								  ].forEach(url => {
							 | 
						||
| 
								 | 
							
								    fastify.inject({
							 | 
						||
| 
								 | 
							
								      url,
							 | 
						||
| 
								 | 
							
								      method: 'GET'
							 | 
						||
| 
								 | 
							
								    }, (err, res) => {
							 | 
						||
| 
								 | 
							
								      t.error(err)
							 | 
						||
| 
								 | 
							
								      t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('JSON Schema validation keywords', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(6)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      ip: {
							 | 
						||
| 
								 | 
							
								        type: 'string',
							 | 
						||
| 
								 | 
							
								        format: 'ipv4'
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/:ip', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send(typeof req.params.ip) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      params: { $ref: 'test#' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'GET',
							 | 
						||
| 
								 | 
							
								    url: '/127.0.0.1'
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.equal(res.payload, 'string')
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'GET',
							 | 
						||
| 
								 | 
							
								    url: '/localhost'
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), {
							 | 
						||
| 
								 | 
							
								      statusCode: 400,
							 | 
						||
| 
								 | 
							
								      error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								      message: 'params.ip should match format "ipv4"'
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Nested id calls', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(6)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      ip: {
							 | 
						||
| 
								 | 
							
								        type: 'string',
							 | 
						||
| 
								 | 
							
								        format: 'ipv4'
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'hello',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      host: { $ref: 'test#' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send(typeof req.body.host.ip) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: { $ref: 'hello#' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { host: { ip: '127.0.0.1' } }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.equal(res.payload, 'string')
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { host: { ip: 'localhost' } }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), {
							 | 
						||
| 
								 | 
							
								      error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								      message: 'body.host.ip should match format "ipv4"',
							 | 
						||
| 
								 | 
							
								      statusCode: 400
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Use the same schema id in different places', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(2)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      id: { type: 'number' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send({ id: req.body.id / 2 }) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: { $ref: 'test#' },
							 | 
						||
| 
								 | 
							
								      response: {
							 | 
						||
| 
								 | 
							
								        200: { $ref: 'test#' }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { id: 42 }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { id: 21 })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Use shared schema and $ref with $id ($ref to $id)', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(5)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'http://foo/test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      id: { type: 'number' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const body = {
							 | 
						||
| 
								 | 
							
								    $id: 'http://foo/user',
							 | 
						||
| 
								 | 
							
								    $schema: 'http://json-schema.org/draft-07/schema#',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    definitions: {
							 | 
						||
| 
								 | 
							
								      address: {
							 | 
						||
| 
								 | 
							
								        $id: '#address',
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          city: { type: 'string' }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    required: ['address'],
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      test: { $ref: 'http://foo/test#' }, // to external
							 | 
						||
| 
								 | 
							
								      address: { $ref: '#address' } // to local
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    handler (req, reply) { reply.send(req.body.test) },
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body,
							 | 
						||
| 
								 | 
							
								      response: {
							 | 
						||
| 
								 | 
							
								        200: { $ref: 'http://foo/test#' }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const id = Date.now()
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      address: { city: 'New Node' },
							 | 
						||
| 
								 | 
							
								      test: { id }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { id })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { test: { id } }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), {
							 | 
						||
| 
								 | 
							
								      error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								      message: "body should have required property 'address'",
							 | 
						||
| 
								 | 
							
								      statusCode: 400
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Use items with $ref', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(4)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'http://example.com/ref-to-external-validator.json',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      hello: { type: 'string' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const body = {
							 | 
						||
| 
								 | 
							
								    type: 'array',
							 | 
						||
| 
								 | 
							
								    items: { $ref: 'http://example.com/ref-to-external-validator.json#' },
							 | 
						||
| 
								 | 
							
								    default: []
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    schema: { body },
							 | 
						||
| 
								 | 
							
								    handler: (_, r) => { r.send('ok') }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: [{ hello: 'world' }]
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.payload, 'ok')
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: { hello: 'world' }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Use $ref to /definitions', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(6)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'test',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      id: { type: 'number' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const body = {
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    definitions: {
							 | 
						||
| 
								 | 
							
								      address: {
							 | 
						||
| 
								 | 
							
								        $id: '#otherId',
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          city: { type: 'string' }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      test: { $ref: 'test#' },
							 | 
						||
| 
								 | 
							
								      address: { $ref: '#/definitions/address' }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    required: ['address', 'test']
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body,
							 | 
						||
| 
								 | 
							
								      response: {
							 | 
						||
| 
								 | 
							
								        200: body
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    handler: (req, reply) => {
							 | 
						||
| 
								 | 
							
								      req.body.removeThis = 'it should not be serialized'
							 | 
						||
| 
								 | 
							
								      reply.send(req.body)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const payload = {
							 | 
						||
| 
								 | 
							
								    address: { city: 'New Node' },
							 | 
						||
| 
								 | 
							
								    test: { id: Date.now() }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), payload)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      address: { city: 'New Node' },
							 | 
						||
| 
								 | 
							
								      test: { id: 'wrong' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), {
							 | 
						||
| 
								 | 
							
								      error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								      message: 'body.test.id should be number',
							 | 
						||
| 
								 | 
							
								      statusCode: 400
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Custom AJV settings - pt1', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(4)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: { num: { type: 'integer' } }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    handler: (req, reply) => {
							 | 
						||
| 
								 | 
							
								      t.equal(req.body.num, 12)
							 | 
						||
| 
								 | 
							
								      reply.send(req.body)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      num: '12'
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 200)
							 | 
						||
| 
								 | 
							
								    t.same(res.json(), { num: 12 })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Custom AJV settings - pt2', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(2)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify({
							 | 
						||
| 
								 | 
							
								    ajv: {
							 | 
						||
| 
								 | 
							
								      customOptions: {
							 | 
						||
| 
								 | 
							
								        coerceTypes: false
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/', {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: { num: { type: 'integer' } }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    handler: (req, reply) => {
							 | 
						||
| 
								 | 
							
								      t.fail('the handler is not called because the "12" is not coerced to number')
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      num: '12'
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Custom AJV settings on different parameters - pt1', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(2)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.setValidatorCompiler(customValidatorCompiler)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/api/:id', {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      querystring: { id: { type: 'integer' } },
							 | 
						||
| 
								 | 
							
								      body: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          num: { type: 'number' }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        required: ['num']
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    handler: (req, reply) => {
							 | 
						||
| 
								 | 
							
								      t.fail('the handler is not called because the "12" is not coerced to number')
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/api/42',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      num: '12'
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, (err, res) => {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.equal(res.statusCode, 400)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('Custom AJV settings on different parameters - pt2', t => {
							 | 
						||
| 
								 | 
							
								  t.plan(4)
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.setValidatorCompiler(customValidatorCompiler)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.post('/api/:id', {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      params: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          id: { type: 'number' }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        required: ['id']
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      body: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          num: { type: 'number' }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        required: ['num']
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    handler: (req, reply) => {
							 | 
						||
| 
								 | 
							
								      t.same(typeof req.params.id, 'number')
							 | 
						||
| 
								 | 
							
								      t.same(typeof req.body.num, 'number')
							 | 
						||
| 
								 | 
							
								      t.same(req.params.id, 42)
							 | 
						||
| 
								 | 
							
								      t.same(req.body.num, 12)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.inject({
							 | 
						||
| 
								 | 
							
								    method: 'POST',
							 | 
						||
| 
								 | 
							
								    url: '/api/42',
							 | 
						||
| 
								 | 
							
								    payload: {
							 | 
						||
| 
								 | 
							
								      num: 12
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 |