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.
		
		
		
		
		
			
		
			
				
					333 lines
				
				8.5 KiB
			
		
		
			
		
	
	
					333 lines
				
				8.5 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const sget = require('simple-get').concat
							 | 
						||
| 
								 | 
							
								const Ajv = require('ajv')
							 | 
						||
| 
								 | 
							
								const Joi = require('@hapi/joi')
							 | 
						||
| 
								 | 
							
								const yup = require('yup')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports.payloadMethod = function (method, t) {
							 | 
						||
| 
								 | 
							
								  const test = t.test
							 | 
						||
| 
								 | 
							
								  const fastify = require('..')()
							 | 
						||
| 
								 | 
							
								  const upMethod = method.toUpperCase()
							 | 
						||
| 
								 | 
							
								  const loMethod = method.toLowerCase()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const opts = {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          hello: {
							 | 
						||
| 
								 | 
							
								            type: 'integer'
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const ajv = new Ajv({ coerceTypes: true, removeAdditional: true })
							 | 
						||
| 
								 | 
							
								  const optsWithCustomValidator = {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: {
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          hello: {
							 | 
						||
| 
								 | 
							
								            type: 'integer'
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        additionalProperties: false
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    validatorCompiler: function ({ schema, method, url, httpPart }) {
							 | 
						||
| 
								 | 
							
								      return ajv.compile(schema)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const optsWithJoiValidator = {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: Joi.object().keys({
							 | 
						||
| 
								 | 
							
								        hello: Joi.string().required()
							 | 
						||
| 
								 | 
							
								      }).required()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    validatorCompiler: function ({ schema, method, url, httpPart }) {
							 | 
						||
| 
								 | 
							
								      return schema.validate.bind(schema)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const yupOptions = {
							 | 
						||
| 
								 | 
							
								    strict: true, // don't coerce
							 | 
						||
| 
								 | 
							
								    abortEarly: false, // return all errors
							 | 
						||
| 
								 | 
							
								    stripUnknown: true, // remove additional properties
							 | 
						||
| 
								 | 
							
								    recursive: true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const optsWithYupValidator = {
							 | 
						||
| 
								 | 
							
								    schema: {
							 | 
						||
| 
								 | 
							
								      body: yup.object().shape({
							 | 
						||
| 
								 | 
							
								        hello: yup.string().required()
							 | 
						||
| 
								 | 
							
								      }).required()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    validatorCompiler: function ({ schema, method, url, httpPart }) {
							 | 
						||
| 
								 | 
							
								      return data => {
							 | 
						||
| 
								 | 
							
								        try {
							 | 
						||
| 
								 | 
							
								          const result = schema.validateSync(data, yupOptions)
							 | 
						||
| 
								 | 
							
								          return { value: result }
							 | 
						||
| 
								 | 
							
								        } catch (e) {
							 | 
						||
| 
								 | 
							
								          return { error: e }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  test(`${upMethod} can be created`, t => {
							 | 
						||
| 
								 | 
							
								    t.plan(1)
							 | 
						||
| 
								 | 
							
								    try {
							 | 
						||
| 
								 | 
							
								      fastify[loMethod]('/', opts, function (req, reply) {
							 | 
						||
| 
								 | 
							
								        reply.send(req.body)
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      fastify[loMethod]('/custom', optsWithCustomValidator, function (req, reply) {
							 | 
						||
| 
								 | 
							
								        reply.send(req.body)
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      fastify[loMethod]('/joi', optsWithJoiValidator, function (req, reply) {
							 | 
						||
| 
								 | 
							
								        reply.send(req.body)
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      fastify[loMethod]('/yup', optsWithYupValidator, function (req, reply) {
							 | 
						||
| 
								 | 
							
								        reply.send(req.body)
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      fastify.register(function (fastify2, opts, done) {
							 | 
						||
| 
								 | 
							
								        fastify2.setValidatorCompiler(function schema ({ schema, method, url, httpPart }) {
							 | 
						||
| 
								 | 
							
								          return body => ({ error: new Error('From custom schema compiler!') })
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								        const withInstanceCustomCompiler = {
							 | 
						||
| 
								 | 
							
								          schema: {
							 | 
						||
| 
								 | 
							
								            body: {
							 | 
						||
| 
								 | 
							
								              type: 'object',
							 | 
						||
| 
								 | 
							
								              properties: { },
							 | 
						||
| 
								 | 
							
								              additionalProperties: false
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        fastify2[loMethod]('/plugin', withInstanceCustomCompiler, (req, reply) => reply.send({ hello: 'never here!' }))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const optsWithCustomValidator2 = {
							 | 
						||
| 
								 | 
							
								          schema: {
							 | 
						||
| 
								 | 
							
								            body: {
							 | 
						||
| 
								 | 
							
								              type: 'object',
							 | 
						||
| 
								 | 
							
								              properties: { },
							 | 
						||
| 
								 | 
							
								              additionalProperties: false
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          },
							 | 
						||
| 
								 | 
							
								          validatorCompiler: function ({ schema, method, url, httpPart }) {
							 | 
						||
| 
								 | 
							
								            return function (body) {
							 | 
						||
| 
								 | 
							
								              return { error: new Error('Always fail!') }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        fastify2[loMethod]('/plugin/custom', optsWithCustomValidator2, (req, reply) => reply.send({ hello: 'never here!' }))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        done()
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								      t.pass()
							 | 
						||
| 
								 | 
							
								    } catch (e) {
							 | 
						||
| 
								 | 
							
								      t.fail()
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.listen(0, function (err) {
							 | 
						||
| 
								 | 
							
								    if (err) {
							 | 
						||
| 
								 | 
							
								      t.error(err)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    fastify.server.unref()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - correctly replies`, t => {
							 | 
						||
| 
								 | 
							
								      if (upMethod === 'HEAD') {
							 | 
						||
| 
								 | 
							
								        t.plan(2)
							 | 
						||
| 
								 | 
							
								        sget({
							 | 
						||
| 
								 | 
							
								          method: upMethod,
							 | 
						||
| 
								 | 
							
								          url: 'http://localhost:' + fastify.server.address().port
							 | 
						||
| 
								 | 
							
								        }, (err, response) => {
							 | 
						||
| 
								 | 
							
								          t.error(err)
							 | 
						||
| 
								 | 
							
								          t.equal(response.statusCode, 200)
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        t.plan(3)
							 | 
						||
| 
								 | 
							
								        sget({
							 | 
						||
| 
								 | 
							
								          method: upMethod,
							 | 
						||
| 
								 | 
							
								          url: 'http://localhost:' + fastify.server.address().port,
							 | 
						||
| 
								 | 
							
								          body: {
							 | 
						||
| 
								 | 
							
								            hello: 42
							 | 
						||
| 
								 | 
							
								          },
							 | 
						||
| 
								 | 
							
								          json: true
							 | 
						||
| 
								 | 
							
								        }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								          t.error(err)
							 | 
						||
| 
								 | 
							
								          t.equal(response.statusCode, 200)
							 | 
						||
| 
								 | 
							
								          t.same(body, { hello: 42 })
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - 400 on bad parameters`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port,
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: 'world'
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 400)
							 | 
						||
| 
								 | 
							
								        t.same(body, {
							 | 
						||
| 
								 | 
							
								          error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								          message: 'body.hello should be integer',
							 | 
						||
| 
								 | 
							
								          statusCode: 400
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation coerce`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port,
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: '42'
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 200)
							 | 
						||
| 
								 | 
							
								        t.same(body, { hello: 42 })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation custom schema compiler`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/custom',
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: '42',
							 | 
						||
| 
								 | 
							
								          world: 55
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 200)
							 | 
						||
| 
								 | 
							
								        t.same(body, { hello: 42 })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation joi schema compiler ok`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/joi',
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: '42'
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 200)
							 | 
						||
| 
								 | 
							
								        t.same(body, { hello: 42 })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation joi schema compiler ko`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/joi',
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: 44
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 400)
							 | 
						||
| 
								 | 
							
								        t.same(body, {
							 | 
						||
| 
								 | 
							
								          error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								          message: '"hello" must be a string',
							 | 
						||
| 
								 | 
							
								          statusCode: 400
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation yup schema compiler ok`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/yup',
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: '42'
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 200)
							 | 
						||
| 
								 | 
							
								        t.same(body, { hello: 42 })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation yup schema compiler ko`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/yup',
							 | 
						||
| 
								 | 
							
								        body: {
							 | 
						||
| 
								 | 
							
								          hello: 44
							 | 
						||
| 
								 | 
							
								        },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 400)
							 | 
						||
| 
								 | 
							
								        t.same(body, {
							 | 
						||
| 
								 | 
							
								          error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								          message: 'hello must be a `string` type, but the final value was: `44`.',
							 | 
						||
| 
								 | 
							
								          statusCode: 400
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation instance custom schema compiler encapsulated`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/plugin',
							 | 
						||
| 
								 | 
							
								        body: { },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 400)
							 | 
						||
| 
								 | 
							
								        t.same(body, {
							 | 
						||
| 
								 | 
							
								          error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								          message: 'From custom schema compiler!',
							 | 
						||
| 
								 | 
							
								          statusCode: '400'
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test(`${upMethod} - input-validation custom schema compiler encapsulated`, t => {
							 | 
						||
| 
								 | 
							
								      t.plan(3)
							 | 
						||
| 
								 | 
							
								      sget({
							 | 
						||
| 
								 | 
							
								        method: upMethod,
							 | 
						||
| 
								 | 
							
								        url: 'http://localhost:' + fastify.server.address().port + '/plugin/custom',
							 | 
						||
| 
								 | 
							
								        body: { },
							 | 
						||
| 
								 | 
							
								        json: true
							 | 
						||
| 
								 | 
							
								      }, (err, response, body) => {
							 | 
						||
| 
								 | 
							
								        t.error(err)
							 | 
						||
| 
								 | 
							
								        t.equal(response.statusCode, 400)
							 | 
						||
| 
								 | 
							
								        t.same(body, {
							 | 
						||
| 
								 | 
							
								          error: 'Bad Request',
							 | 
						||
| 
								 | 
							
								          message: 'Always fail!',
							 | 
						||
| 
								 | 
							
								          statusCode: '400'
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 |