Skip to content

Commit

Permalink
Fix issue with passing in non-draft 7 AJV instance. Issue 107 (#108)
Browse files Browse the repository at this point in the history
* fix(index): use base class of ajv to check if ajv is set

* test: add test for passing in 2019 and 2020 ajv instances
  • Loading branch information
nicobuzeta committed Mar 20, 2024
1 parent e760718 commit a7f445b
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 1 deletion.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

const fp = require('fastify-plugin')
const Ajv = require('ajv')
const AjvCore = require('ajv/dist/core')

function fastifyResponseValidation (fastify, opts, next) {
let ajv
if (opts.ajv && opts.ajv instanceof Ajv) {
if (opts.ajv && opts.ajv instanceof AjvCore.default) {
ajv = opts.ajv
} else {
const { plugins: ajvPlugins, ...ajvOptions } = Object.assign({
Expand Down
140 changes: 140 additions & 0 deletions test/ajv.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const test = require('tap').test
const Fastify = require('fastify')
const plugin = require('..')
const Ajv = require('ajv')
const Ajv2019 = require('ajv/dist/2019')
const Ajv2020 = require('ajv/dist/2020')
const ajvFormats = require('ajv-formats')
const ajvErrors = require('ajv-errors')

Expand Down Expand Up @@ -171,6 +173,144 @@ test('use ajv errors with Ajv instance', async t => {
t.equal(response.json().message, 'response should be an object with an integer property answer only')
})

test('use ajv formats with 2019 Ajv instance', async t => {
const fastify = Fastify()
const ajv = new Ajv2019()
ajvFormats(ajv)
await fastify.register(plugin, { ajv })

fastify.route({
method: 'GET',
url: '/',
schema: {
response: {
'2xx': {
type: 'object',
properties: {
answer: { type: 'number', format: 'float' }
}
}
}
},
handler: async (req, reply) => {
return { answer: 2.4 }
}
})

const response = await fastify.inject({
method: 'GET',
url: '/'
})

t.equal(response.statusCode, 200)
t.strictSame(JSON.parse(response.payload), { answer: 2.4 })
})

test('use ajv errors with 2019 Ajv instance', async t => {
const fastify = Fastify()
const ajv = new Ajv2019({ allErrors: true })
ajvErrors(ajv, { singleError: true })
await fastify.register(plugin, { ajv })

fastify.route({
method: 'GET',
url: '/',
schema: {
response: {
'2xx': {
type: 'object',
required: ['answer'],
properties: {
answer: { type: 'number' }
},
additionalProperties: false,
errorMessage: 'should be an object with an integer property answer only'
}
}
},
handler: async (req, reply) => {
return { notAnAnswer: 24 }
}
})

const response = await fastify.inject({
method: 'GET',
url: '/'
})

t.equal(response.statusCode, 500)
t.equal(response.json().message, 'response should be an object with an integer property answer only')
})

test('use ajv formats with 2020 Ajv instance', async t => {
const fastify = Fastify()
const ajv = new Ajv2020()
ajvFormats(ajv)
await fastify.register(plugin, { ajv })

fastify.route({
method: 'GET',
url: '/',
schema: {
response: {
'2xx': {
type: 'object',
properties: {
answer: { type: 'number', format: 'float' }
}
}
}
},
handler: async (req, reply) => {
return { answer: 2.4 }
}
})

const response = await fastify.inject({
method: 'GET',
url: '/'
})

t.equal(response.statusCode, 200)
t.strictSame(JSON.parse(response.payload), { answer: 2.4 })
})

test('use ajv errors with 2019 Ajv instance', async t => {
const fastify = Fastify()
const ajv = new Ajv2020({ allErrors: true })
ajvErrors(ajv, { singleError: true })
await fastify.register(plugin, { ajv })

fastify.route({
method: 'GET',
url: '/',
schema: {
response: {
'2xx': {
type: 'object',
required: ['answer'],
properties: {
answer: { type: 'number' }
},
additionalProperties: false,
errorMessage: 'should be an object with an integer property answer only'
}
}
},
handler: async (req, reply) => {
return { notAnAnswer: 24 }
}
})

const response = await fastify.inject({
method: 'GET',
url: '/'
})

t.equal(response.statusCode, 500)
t.equal(response.json().message, 'response should be an object with an integer property answer only')
})

test('should throw an error if ajv.plugins is not passed to instance and not array', async t => {
t.plan(1)
const fastify = Fastify()
Expand Down

0 comments on commit a7f445b

Please sign in to comment.