Skip to content

Commit

Permalink
fix: support upper-case pattern and default response keys (#125)
Browse files Browse the repository at this point in the history
* issue-124 - Support upper-case pattern and default response keys

* Update index.js

Signed-off-by: Frazer Smith <[email protected]>

---------

Signed-off-by: Frazer Smith <[email protected]>
Co-authored-by: n3rdy.me <[email protected]>
Co-authored-by: Frazer Smith <[email protected]>
  • Loading branch information
3 people authored Nov 3, 2024
1 parent f8c7bad commit 9dfecdc
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 3 deletions.
14 changes: 11 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,16 @@ function fastifyResponseValidation (fastify, opts, next) {

function buildHook (schema, responseStatusCodeValidation) {
const statusCodes = {}
for (const statusCode in schema) {
const responseSchema = schema[statusCode]
for (const originalCode in schema) {
/**
* Internally we are going to treat status codes as lower-case strings to preserve compatibility
* with previous versions of this plugin allowing 4xx/5xx status codes to be defined as strings
* even though the OpenAPI spec requires them to be upper-case or the word 'default'.
* @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object}
* @see {@link https://swagger.io/specification/#fixed-fields-14}
*/
const statusCode = originalCode.toLowerCase()
const responseSchema = schema[originalCode]

if (responseSchema.content !== undefined) {
statusCodes[statusCode] = {}
Expand All @@ -71,7 +79,7 @@ function fastifyResponseValidation (fastify, opts, next) {
return preSerialization

function preSerialization (req, reply, payload, next) {
let validate = statusCodes[reply.statusCode] || statusCodes[(reply.statusCode + '')[0] + 'xx']
let validate = statusCodes[reply.statusCode] || statusCodes[(reply.statusCode + '')[0] + 'xx'] || statusCodes.default

if (responseStatusCodeValidation && validate === undefined) {
next(new NoSchemaDefinedError(`status code ${reply.statusCode}`))
Expand Down
88 changes: 88 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,94 @@ test('Should check only the assigned status code', async t => {
t.assert.deepStrictEqual(JSON.parse(response.payload), { answer: '42' })
})

/**
* OpenAPI 3.1.0 - Responses Object - 2XX status filter in upper case
* https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object
*/
test('Should use response matching 5XX instead of default', async t => {
const fastify = Fastify()
await fastify.register(plugin)

fastify.route({
method: 'GET',
url: '/',
schema: {
response: {
'2XX': {
type: 'object',
properties: {
answer: { type: 'number' }
}
},
default: {
type: 'object',
properties: {
error_message: { type: 'string' }
},
required: [
'error_message'
]
}
}
},
handler: async (req, reply) => {
return { answer: 42 }
}
})

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

t.assert.strictEqual(response.statusCode, 200)
t.assert.deepStrictEqual(JSON.parse(response.payload), { answer: 42 })
})

/**
* OpenAPI 3.1.0 - Responses Object - default
* https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#responses-object
*/
test('Should fallback to default response if nothing matches', async t => {
const fastify = Fastify()
await fastify.register(plugin)

fastify.route({
method: 'GET',
url: '/',
schema: {
response: {
'2XX': {
type: 'object',
properties: {
answer: { type: 'number' }
}
},
default: {
type: 'object',
properties: {
error_message: { type: 'string' }
},
required: [
'error_message'
]
}
}
},
handler: async (req, reply) => {
reply.status(500).send({ error_message: 'the answer is 42' })
}
})

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

t.assert.strictEqual(response.statusCode, 500)
t.assert.deepStrictEqual(JSON.parse(response.payload), { error_message: 'the answer is 42' })
})

test('Should check media types', async t => {
const fastify = Fastify()
await fastify.register(plugin)
Expand Down

0 comments on commit 9dfecdc

Please sign in to comment.