Skip to content

Commit

Permalink
fix: unused shared schema to serializer (#1496)
Browse files Browse the repository at this point in the history
* fix: unused shared schema to serializer

* add: details on bool check
  • Loading branch information
Eomm authored and mcollina committed Mar 2, 2019
1 parent 563926f commit 9398dfa
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 3 deletions.
13 changes: 10 additions & 3 deletions lib/schemas.js
Expand Up @@ -24,7 +24,7 @@ Schemas.prototype.add = function (schema) {
throw new FST_ERR_SCH_ALREADY_PRESENT(id)
}

this.store[id] = schema
this.store[id] = this.resolveRefs(schema, true)
}

Schemas.prototype.resolve = function (id) {
Expand All @@ -34,7 +34,7 @@ Schemas.prototype.resolve = function (id) {
return this.store[id]
}

Schemas.prototype.resolveRefs = function (routeSchemas) {
Schemas.prototype.resolveRefs = function (routeSchemas, dontClearId) {
// let's check if our schemas have a custom prototype
for (const key of ['headers', 'querystring', 'params', 'body']) {
if (typeof routeSchemas[key] === 'object' && Object.getPrototypeOf(routeSchemas[key]) !== Object.prototype) {
Expand All @@ -46,7 +46,14 @@ Schemas.prototype.resolveRefs = function (routeSchemas) {
// this will work only for standard json schemas
// other compilers such as Joi will fail
this.traverse(routeSchemas)
this.cleanId(routeSchemas)

// when a plugin uses the 'skip-override' and call addSchema
// the same JSON will be pass throug all the avvio tree. In this case
// it is not possible clean the id. The id will be cleared
// in the startup phase by the call of validation.js. Details PR #1496
if (dontClearId !== true) {
this.cleanId(routeSchemas)
}
} catch (err) {
// if we have failed because `resolve has thrown
// let's rethrow the error and let avvio handle it
Expand Down
105 changes: 105 additions & 0 deletions test/shared-schemas.test.js
Expand Up @@ -1122,3 +1122,108 @@ test('Use shared schema and $ref to /definitions', t => {
t.deepEqual(JSON.parse(res.payload), payload)
})
})

test('Cross shared schema reference', t => {
t.plan(1)

const fastify = Fastify()
fastify.addSchema({ $id: 'item', type: 'object', properties: { foo: { type: 'string' } } })
fastify.addSchema({
$id: 'itemList',
type: 'array',
items: 'item#'
})

fastify.post('/post', { schema: { body: 'itemList#', response: { 200: 'item#' } } }, () => { })
fastify.get('/get', { schema: { body: 'itemList#', response: { 200: 'item#' } } }, () => { })

fastify.ready(t.error)
})

test('Cross shared schema reference with unused shared schema', t => {
t.plan(1)

const fastify = Fastify()
fastify.addSchema({ $id: 'item', type: 'object', properties: { foo: { type: 'string' } } })
fastify.addSchema({
$id: 'itemList',
type: 'array',
items: 'item#'
})

fastify.get('/get', { schema: { response: { 200: 'item#' } } }, () => { })
fastify.ready(t.error)
})

test('Cross shared schema reference with multiple references', t => {
t.plan(1)

const fastify = Fastify()
fastify.addSchema({ $id: 'item', type: 'object', properties: { foo: { type: 'string' } } })

// This schema is not used
fastify.addSchema({
$id: 'itemList',
type: 'array',
items: 'item#'
})

const multipleRefReplaceWay = {
type: 'object',
properties: {
a: 'item#',
b: 'item#'
}
}

fastify.get('/get', { schema: { response: { 200: multipleRefReplaceWay } } }, () => { })
fastify.post('/post', { schema: { body: multipleRefReplaceWay, response: { 200: multipleRefReplaceWay } } }, () => { })

fastify.ready(t.error)
})

test('Cross shared schema reference with encapsulation references', t => {
t.plan(1)

const fastify = Fastify()
fastify.addSchema({ $id: 'item', type: 'object', properties: { foo: { type: 'string' } } })
fastify.addSchema({
$id: 'itemList',
type: 'array',
items: 'item#'
})

fastify.register((instance, opts, next) => {
// this schema is not used
instance.addSchema({
$id: 'encapsulation',
type: 'object',
properties: {
id: { type: 'number' },
item: 'item#',
secondItem: 'item#'
}
})

const multipleRefReplaceWay = {
type: 'object',
properties: {
a: 'itemList#',
b: 'item#',
c: 'item#',
d: 'item#'
}
}

instance.post('/post', { schema: { body: multipleRefReplaceWay, response: { 200: multipleRefReplaceWay } } }, () => { })
instance.post('/double', { schema: { response: { 200: 'encapsulation#' } } }, () => { })
instance.get('/get', { schema: { response: { 200: multipleRefReplaceWay } } }, () => { })
instance.get('/double-get', { schema: { body: multipleRefReplaceWay, response: { 200: multipleRefReplaceWay } } }, () => { })
next()
}, { prefix: '/foo' })

fastify.post('/post', { schema: { body: 'item#', response: { 200: 'item#' } } }, () => { })
fastify.get('/get', { schema: { body: 'item#', response: { 200: 'item#' } } }, () => { })

fastify.ready(t.error)
})

0 comments on commit 9398dfa

Please sign in to comment.