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.
		
		
		
		
		
			
		
			
				
					133 lines
				
				4.5 KiB
			
		
		
			
		
	
	
					133 lines
				
				4.5 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const { test } = require('tap')
							 | 
						||
| 
								 | 
							
								const Fastify = require('fastify')
							 | 
						||
| 
								 | 
							
								const Swagger = require('swagger-parser')
							 | 
						||
| 
								 | 
							
								const fastifySwagger = require('../../../index')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('support $ref schema', async t => {
							 | 
						||
| 
								 | 
							
								  t.plan(1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  fastify.addSchema({
							 | 
						||
| 
								 | 
							
								    $id: 'example',
							 | 
						||
| 
								 | 
							
								    type: 'object',
							 | 
						||
| 
								 | 
							
								    properties: {
							 | 
						||
| 
								 | 
							
								      hello: { type: 'string' }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.register(fastifySwagger, {
							 | 
						||
| 
								 | 
							
								    routePrefix: '/docs',
							 | 
						||
| 
								 | 
							
								    exposeRoute: true
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.register((instance, opts, next) => {
							 | 
						||
| 
								 | 
							
								    instance.addSchema({
							 | 
						||
| 
								 | 
							
								      $id: 'subschema-two',
							 | 
						||
| 
								 | 
							
								      type: 'object',
							 | 
						||
| 
								 | 
							
								      properties: {
							 | 
						||
| 
								 | 
							
								        hello: { type: 'string' }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    instance.register((subinstance, opts, next) => {
							 | 
						||
| 
								 | 
							
								      subinstance.addSchema({
							 | 
						||
| 
								 | 
							
								        $id: 'subschema-three',
							 | 
						||
| 
								 | 
							
								        type: 'object',
							 | 
						||
| 
								 | 
							
								        properties: {
							 | 
						||
| 
								 | 
							
								          hello: { type: 'string' }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      subinstance.post('/:hello', {
							 | 
						||
| 
								 | 
							
								        handler () {},
							 | 
						||
| 
								 | 
							
								        schema: {
							 | 
						||
| 
								 | 
							
								          body: { $ref: 'example#/properties/hello' },
							 | 
						||
| 
								 | 
							
								          querystring: { $ref: 'subschema-two#/properties/hello' },
							 | 
						||
| 
								 | 
							
								          params: { $ref: 'subschema-two#/properties/hello' },
							 | 
						||
| 
								 | 
							
								          headers: { $ref: 'subschema-three#/properties/hello' },
							 | 
						||
| 
								 | 
							
								          response: {
							 | 
						||
| 
								 | 
							
								            200: { $ref: 'example#/properties/hello' }
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      next()
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    next()
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const res = await fastify.inject('/docs/json')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await Swagger.validate(res.json())
							 | 
						||
| 
								 | 
							
								  t.pass('valid swagger object')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('support nested $ref schema : complex case', async (t) => {
							 | 
						||
| 
								 | 
							
								  const options = {
							 | 
						||
| 
								 | 
							
								    swagger: {},
							 | 
						||
| 
								 | 
							
								    refResolver: {
							 | 
						||
| 
								 | 
							
								      buildLocalReference: (json, baseUri, fragment, i) => {
							 | 
						||
| 
								 | 
							
								        return json.$id || `def-${i}`
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  fastify.register(fastifySwagger, options)
							 | 
						||
| 
								 | 
							
								  fastify.register(async (instance) => {
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaA', type: 'object', properties: { id: { type: 'integer' } } })
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaB', type: 'object', properties: { id: { type: 'string' } } })
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaC', type: 'object', properties: { a: { type: 'array', items: { $ref: 'schemaA' } } } })
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaD', type: 'object', properties: { b: { $ref: 'schemaB' }, c: { $ref: 'schemaC' } } })
							 | 
						||
| 
								 | 
							
								    instance.post('/url1', { schema: { body: { $ref: 'schemaD' }, response: { 200: { $ref: 'schemaB' } } } }, () => {})
							 | 
						||
| 
								 | 
							
								    instance.post('/url2', { schema: { body: { $ref: 'schemaC' }, response: { 200: { $ref: 'schemaA' } } } }, () => {})
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await fastify.ready()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const swaggerObject = fastify.swagger()
							 | 
						||
| 
								 | 
							
								  t.equal(typeof swaggerObject, 'object')
							 | 
						||
| 
								 | 
							
								  const definitions = swaggerObject.definitions
							 | 
						||
| 
								 | 
							
								  t.match(Object.keys(definitions), ['schemaA', 'schemaB', 'schemaC', 'schemaD'])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // ref must be prefixed by '#/definitions/'
							 | 
						||
| 
								 | 
							
								  t.equal(definitions.schemaC.properties.a.items.$ref, '#/definitions/schemaA')
							 | 
						||
| 
								 | 
							
								  t.equal(definitions.schemaD.properties.b.$ref, '#/definitions/schemaB')
							 | 
						||
| 
								 | 
							
								  t.equal(definitions.schemaD.properties.c.$ref, '#/definitions/schemaC')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await Swagger.validate(swaggerObject)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('support nested $ref schema : complex case without modifying buildLocalReference', async (t) => {
							 | 
						||
| 
								 | 
							
								  const fastify = Fastify()
							 | 
						||
| 
								 | 
							
								  fastify.register(fastifySwagger, {
							 | 
						||
| 
								 | 
							
								    routePrefix: '/docs',
							 | 
						||
| 
								 | 
							
								    exposeRoute: true
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								  fastify.register(async (instance) => {
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaA', type: 'object', properties: { id: { type: 'integer' } } })
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaB', type: 'object', properties: { id: { type: 'string' } } })
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaC', type: 'object', properties: { a: { type: 'array', items: { $ref: 'schemaA' } } } })
							 | 
						||
| 
								 | 
							
								    instance.addSchema({ $id: 'schemaD', type: 'object', properties: { b: { $ref: 'schemaB' }, c: { $ref: 'schemaC' } } })
							 | 
						||
| 
								 | 
							
								    instance.post('/url1', { schema: { body: { $ref: 'schemaD' }, response: { 200: { $ref: 'schemaB' } } } }, () => {})
							 | 
						||
| 
								 | 
							
								    instance.post('/url2', { schema: { body: { $ref: 'schemaC' }, response: { 200: { $ref: 'schemaA' } } } }, () => {})
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await fastify.ready()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const swaggerObject = fastify.swagger()
							 | 
						||
| 
								 | 
							
								  t.equal(typeof swaggerObject, 'object')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const definitions = swaggerObject.definitions
							 | 
						||
| 
								 | 
							
								  t.match(Object.keys(definitions), ['def-0', 'def-1', 'def-2', 'def-3'])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // ref must be prefixed by '#/definitions/'
							 | 
						||
| 
								 | 
							
								  t.equal(definitions['def-2'].properties.a.items.$ref, '#/definitions/def-0')
							 | 
						||
| 
								 | 
							
								  t.equal(definitions['def-3'].properties.b.$ref, '#/definitions/def-1')
							 | 
						||
| 
								 | 
							
								  t.equal(definitions['def-3'].properties.c.$ref, '#/definitions/def-2')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  await Swagger.validate(swaggerObject)
							 | 
						||
| 
								 | 
							
								})
							 |