UNPKG

swagger-routes

Version:

Generate Express or Restify route handlers from a Swagger specification

233 lines (188 loc) 7.78 kB
'use strict' const expect = require('expect') const routeValidation = require('../src/routeValidation') const util = require('../src/swaggerSpec') const EMPTY_REQ = { params: {}, headers: {}, query: {}, body: {}, files: {}, accepts: () => true } const PARAM = { STRING: { name: 'STRING', in: 'path', type: 'string' }, INT: { name: 'INT', in: 'query', type: 'integer' }, NUM: { name: 'NUM', in: 'query', type: 'number' }, BOOL: { name: 'BOOL', in: 'query', type: 'bool' }, ARRAY: { name: 'ARRAY', in: 'query', type: 'array', items: { type: 'string' } }, FILE: { name: 'FILE', in: 'formData', type: 'file' } } const copy = (val, param) => Object.assign({}, param, val) function newReq(req) { return copy(req, EMPTY_REQ) } function newSpec(template, param) { const method = 'get' const info = {} param = copy(param, template) info[method] = { parameters: [ param ] } return util.createPathOperation(method, info, {}, {}) } describe('routeValidation', () => { describe('validateRequest', () => { const validateRequest = routeValidation.validateRequest it('should enforce required params', () => { const spec = newSpec(PARAM.STRING, { required: true }) const failure = validateRequest(EMPTY_REQ, spec) expect(failure).toExist() expect(failure.errors.length).toBe(1) expect(failure.errors[0].message).toBe('path requires property "STRING"') }) it('should allow params which are not required to be missing', () => { const spec = newSpec(PARAM.STRING, { required: false }) const failure = validateRequest(EMPTY_REQ, spec) expect(failure).toNotExist() }) it('should not allow an integer to have a decimal value', () => { const spec = newSpec(PARAM.INT) const req = newReq({ query: { INT: 2.3 } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.INT is not of a type(s) integer') }) it('should enforce that path param is a valid path segment id under express', () => { const spec = newSpec(PARAM.STRING) const req = newReq({ params: { 'wrong': 'value' } }) req.app = true // simulate express request const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('path.wrong is an invalid path segment') }) it('should respect allowEmptyValue in query parameters', () => { const spec = newSpec(PARAM.INT, { allowEmptyValue: true }) const req = newReq({ query: { 'INT': '' } }) const failure = validateRequest(req, spec) expect(failure).toNotExist() }) it('should respect allowEmptyValue in formData parameters', () => { const spec = newSpec(PARAM.INT, { allowEmptyValue: true, 'in': 'formData' }) const req = newReq({ formData: { 'INT': '' } }) const failure = validateRequest(req, spec) expect(failure).toNotExist() }) it('should ignore allowEmptyValue in parameters outside of formData or query', () => { const spec = newSpec(PARAM.INT, { allowEmptyValue: true, 'in': 'path' }) const req = newReq({ params: { 'INT': '' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('path.INT is not of a type(s) integer') }) it('should restrict values to enum set', () => { const spec = newSpec(PARAM.STRING, { enum:[ 'a', 'b', 'c' ] }) const req = newReq({ params: { 'STRING': 'd' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('path.STRING is not one of enum values: a,b,c') }) it('should restrict number to defined maximum', () => { const spec = newSpec(PARAM.INT, { maximum: 10 }) const req = newReq({ query: { 'INT': 11 } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.INT must have a maximum value of 10') }) it('should restrict number to defined exclusive maximum', () => { const spec = newSpec(PARAM.INT, { maximum: 10, exclusiveMaximum: true }) const req = newReq({ query: { 'INT': 10 } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.INT must have a maximum value of 10') }) it('should restrict number to defined minimum', () => { const spec = newSpec(PARAM.INT, { minimum: 10 }) const req = newReq({ query: { 'INT': 9 } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.INT must have a minimum value of 10') }) it('should restrict number to defined exclusive minimum', () => { const spec = newSpec(PARAM.INT, { minimum: 10, exclusiveMinimum: true }) const req = newReq({ query: { 'INT': 10 } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.INT must have a minimum value of 10') }) it('should restrict a string length to a defined maximum', () => { const spec = newSpec(PARAM.STRING, { maxLength: 2 }) const req = newReq({ params: { 'STRING': 'long' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('path.STRING does not meet maximum length of 2') }) it('should restrict a string length to a defined minimum', () => { const spec = newSpec(PARAM.STRING, { minLength: 2 }) const req = newReq({ params: { 'STRING': 'a' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('path.STRING does not meet minimum length of 2') }) it('should restrict a string to match a defined pattern', () => { const spec = newSpec(PARAM.STRING, { pattern: '^s' }) const req = newReq({ params: { 'STRING': 'oops' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('path.STRING does not match pattern "^s"') }) it('should restrict an array length to a defined maximum', () => { const spec = newSpec(PARAM.ARRAY, { maxItems: 2 }) const req = newReq({ query: { 'ARRAY': 'a,b,c' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.ARRAY does not meet maximum length of 2') }) it('should restrict an array length to a defined minimum', () => { const spec = newSpec(PARAM.ARRAY, { minItems: 5 }) const req = newReq({ query: { 'ARRAY': 'a,b,c' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.ARRAY does not meet minimum length of 5') }) it('should restrict an array to unique items', () => { const spec = newSpec(PARAM.ARRAY, { uniqueItems: true }) const req = newReq({ query: { 'ARRAY': 'a,a,c' } }) const failure = validateRequest(req, spec) expect(failure).toExist() expect(failure.errors[0].message).toBe('query.ARRAY contains duplicate item') }) it('should apply default values before validation', () => { const spec = newSpec(PARAM.INT, { default: 2 }) const req = newReq({}) const result = validateRequest(req, spec) expect(result).toNotExist() expect(req.query.INT).toBe(2) }) }) })