UNPKG

@trigo/atrix-swagger

Version:

Swagger API Language intigration

575 lines (504 loc) 17.7 kB
'use strict'; /* eslint-env node, mocha */ /* eslint no-unused-expressions: 0, arrow-body-style: 0 */ const {expect} = require('chai'); const Joi = require('joi'); const uuid = require('uuid'); const {createParameterValidator} = require('./create-validator'); describe('createParameterValidation', () => { function getSchema(def) { const config = {}; config[def.name] = createParameterValidator(def); const schema = Joi.object(config); return { schema, ok: obj => { Joi.assert(obj, schema); }, fail: (obj, msg) => { try { expect(() => Joi.assert(obj, schema)).to.throw(Error, msg); } catch (e) { console.error(e); // eslint-disable-line throw e; } }, }; } it('can omit attribute "type" to allow any value', () => { const schema = getSchema({ name: 'test', }); schema.ok({test: true}); schema.ok({test: false}); schema.ok({test: 0}); schema.ok({test: 1.2}); schema.ok({test: [1, '12']}); schema.ok({test: {prop: 1, sub: {p: '12'}}}); }); describe('"boolean" properties', () => { it('creates boolean validator', () => { const schema = getSchema({ name: 'test', type: 'boolean', }); schema.ok({test: true}); schema.ok({test: false}); schema.fail({test: 0}); schema.fail({test: 1}); }); }); describe('attribute "required"', () => { it('make property required', () => { const schema = getSchema({ name: 'test', type: 'string', required: true, }); schema.ok({test: 'true'}); schema.fail({}); }); }); it('handles attribute "default"', () => { const schema = getSchema({ name: 'test', type: 'string', default: 'uuid', }); const parsedValue = Joi.validate({}, schema.schema); expect(parsedValue.value.test).to.equal('uuid'); }); it('handles attribute "nullable"', () => { const schema1 = getSchema({ name: 'test', type: 'string', nullable: true, required: true, }); const schema2 = getSchema({ name: 'test', type: 'string', nullable: false, }); const schema3 = getSchema({ name: 'test', type: 'string', }); schema1.ok({test: 'asdf'}); schema1.ok({test: null}); schema1.fail({test: undefined}); schema2.fail({test: null}); schema3.fail({test: null}); }); describe('handles "enum" attribute', () => { it('string property', () => { const schema = getSchema({ name: 'test', type: 'string', enum: ['v1', 'v2', 'v3'], }); schema.ok({test: 'v1'}); schema.ok({test: 'v2'}); schema.ok({test: 'v3'}); schema.fail({test: 'adg'}, /must be one of/); }); it('number property', () => { const schema = getSchema({ name: 'test', type: 'number', enum: [42, 21, null], }); schema.ok({test: 42}); schema.ok({test: 21}); schema.ok({test: null}); schema.fail({test: 32}, /must be one of/); }); }); describe('"number" properties & options', () => { it('creates integer validator', () => { const schema = getSchema({ name: 'test', type: 'integer', }); schema.ok({test: 100}); schema.fail({test: 'asd'}, /must be a number/); schema.fail({test: 1.2}, /must be an integer/); }); it('creates number validator', () => { const schema = getSchema({ name: 'test', type: 'number', }); schema.ok({test: 100}); schema.ok({test: -100.3}); schema.fail({test: 'asd'}, /must be a number/); schema.fail({test: false}, /must be a number/); }); it('handles "maximum" attribute', () => { const schema = getSchema({ name: 'test', type: 'number', maximum: 42, }); schema.ok({test: 12}); schema.ok({test: -100}); schema.ok({test: 42}); schema.fail({test: 43}, /must be less than or equal to/); schema.fail({test: 42.00001}, /must be less than or equal to/); }); it('handles "exclusiveMaximum" attribute', () => { const schema = getSchema({ name: 'test', type: 'number', maximum: 42, exclusiveMaximum: true, }); schema.ok({test: 12}); schema.ok({test: -100}); schema.fail({test: 42}, /must be less than 42/); schema.fail({test: 42.00001}, /must be less than 42/); }); it('handles "minimum" attribute', () => { const schema = getSchema({ name: 'test', type: 'number', minimum: 42, }); schema.ok({test: 1122}); schema.ok({test: 1030}); schema.ok({test: 42}); schema.fail({test: -14}, /must be larger than or equal/); schema.fail({test: 41.99999999}, /must be larger than or equal/); }); it('handles "exclusiveMinimum" attibute', () => { const schema = getSchema({ name: 'test', type: 'number', minimum: 42, exclusiveMinimum: true, }); schema.ok({test: 1122}); schema.ok({test: 1030}); schema.fail({test: 42}, /must be greater than 42/); schema.fail({test: 41.99999999}, /must be greater than 42/); }); it('handles "multipleOf" attribute', () => { const schema = getSchema({ name: 'test', type: 'number', multipleOf: 5, }); schema.ok({test: 0}); schema.ok({test: 5}); schema.ok({test: 20}); schema.fail({test: 21}, /must be a multiple of 5/); }); it('handles attribute "default"', () => { const schema = getSchema({ name: 'test', type: 'number', default: 5, }); const parsedValue = Joi.validate({}, schema.schema); expect(parsedValue.value.test).to.equal(5); }); }); describe('"string" properties & options', () => { it('creates string validator', () => { const schema = getSchema({ name: 'test', type: 'string', }); schema.ok({test: '100'}); schema.ok({test: 'asdgasg'}); schema.fail({test: 12}, /must be a string/); schema.fail({test: false}, /must be a string/); }); it('string validator allows empty strings', () => { const schema = getSchema({ name: 'test', type: 'string', }); schema.ok({test: ''}); }); it('empty string not allowd with "pattern" attribute', () => { const schema = getSchema({ name: 'test', type: 'string', pattern: '^start', }); schema.ok({test: 'start'}); schema.fail({test: ''}); }); it('empty string not allowed with minLength attribute', () => { const schema = getSchema({ name: 'test', type: 'string', minLength: 1, }); schema.ok({test: 's'}); schema.fail({test: ''}); }); it('handles "pattern" attribute', () => { const schema = getSchema({ name: 'test', type: 'string', pattern: '^start', }); schema.ok({test: 'start'}); schema.fail({test: 'notstart'}); }); it('handles "minLength" attribute', () => { const schema = getSchema({ name: 'test', type: 'string', minLength: 4, }); schema.ok({test: 'start'}); schema.fail({test: 'i12'}, /length must be at least 4 character/); }); it('handles "maxLength" attribute', () => { const schema = getSchema({ name: 'test', type: 'string', maxLength: 4, }); schema.ok({test: 'stat'}); schema.fail({test: 'i12as'}, /length must be less than or equal to 4 characters/); }); it('handles attribute "format=date"', () => { const schema = getSchema({ name: 'test', type: 'string', format: 'date', }); schema.ok({test: '1980-05-14'}); schema.fail({test: new Date().toISOString()}); }); it('handles attribute "format=date-time"', () => { const schema = getSchema({ name: 'test', type: 'string', format: 'date-time', }); schema.ok({test: new Date().toISOString()}); schema.ok({test: new Date()}); schema.fail({test: 'ka date'}); }); it('handles attribute "format=uuid"', () => { const schema = getSchema({ name: 'test', type: 'string', format: 'uuid', }); schema.ok({test: uuid()}); schema.fail({test: 'ka date'}); }); }); describe('array properties', () => { it('handle "string" array', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'string', }, }); schema.ok({test: []}); schema.ok({test: ['1', '2', '1asf']}); schema.fail({test: 'ka date'}, /must be an array/); schema.fail({test: [1, 2]}); }); it('handle "number" array', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'number', }, }); schema.ok({test: []}); schema.ok({test: [1, 2, 12.2]}); schema.fail({test: 'ka date'}, /must be an array/); schema.fail({test: ['1s', 2]}); }); it('handles "minItems" attribute', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'number', }, minItems: 3, }); schema.ok({test: [1, 213, 412, 12]}); schema.ok({test: [1, 2, 12.2]}); schema.fail({test: [2]}, /must contain at least 3 items/); }); it('handles "maxItems" attribute', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'number', }, maxItems: 3, }); schema.ok({test: [213, 412, 12]}); schema.ok({test: [1]}); schema.fail({test: [1, 2, 3, 4, 5]}, /must contain less than or equal to 3 items/); }); it('handles "uniqueItems" attribute', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'number', }, uniqueItems: true, }); schema.ok({test: [213, 412, 12]}); schema.ok({test: [1]}); schema.fail({test: [1, 2, 3, 1, 5]}, /contains a duplicate value/); }); it('handles empty arrays with "required" attribute', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'object', required: ['id', 'name'], properties: { id: { type: 'string', }, name: { type: 'string', }, }, }, }); schema.ok({test: [{id: '1', name: 'obj1'}, {id: '2', name: 'obj2'}]}); schema.ok({test: []}); schema.fail({test: [{id: '1'}]}, /is required/); }); it('handles arrays with "required" object items', () => { const schema = getSchema({ name: 'test', type: 'array', items: { type: 'object', required: true, properties: { id: { type: 'string', }, name: { type: 'string', }, }, }, }); schema.ok({test: [{id: '1', name: 'obj1'}, {id: '2', name: 'obj2'}]}); schema.ok({test: [{id: '1'}]}); schema.fail({test: []}, /does not contain 1 required/); }); it('in query: array can also be a single value', () => { const schema = getSchema({ in: 'query', name: 'test', type: 'array', items: { type: 'string', }, }); schema.ok({test: 'ka date'}); schema.ok({test: []}); schema.ok({test: ['1', '2', '1asf']}); schema.fail({test: [1, 2]}); }); }); describe('"object" properties', () => { it('primitive type property', () => { const schema = getSchema({ name: 'test', type: 'object', description: 'desc', properties: { name: { type: 'string', }, }, }); schema.ok({test: {name: 'AtrixSwagger'}}); schema.ok({test: {}}); schema.fail({test: 0}); }); it('object type property', () => { const schema = getSchema({ name: 'test', type: 'object', description: 'desc', properties: { name: { type: 'object', description: 'test nested obj', properties: { id: { type: 'number', minimum: 0, }, }, }, }, }); schema.ok({test: {name: {id: 12}}}); schema.ok({test: {}}); schema.fail({test: {name: {id: -1}}}, /must be larger than or equal to 0/); }); it('"required" property', () => { const schema = getSchema({ name: 'test', type: 'object', description: 'desc', properties: { name: { type: 'string', }, }, required: ['name'], }); schema.ok({test: {name: 'AtrixSwagger'}}); schema.fail({test: {}}, /is required/); schema.fail({test: 0}); }); it('"description" property', () => { const schema = getSchema({ name: 'test', type: 'object', description: 'desc', properties: {}, required: ['name'], }); expect(schema.schema._inner.children[0].schema._description).to.equal('desc'); // eslint-disable-line }); it('"additionalProperties" = true allows undeclared properties', () => { const schema = getSchema({ name: 'test', type: 'object', description: 'desc', properties: { name: { type: 'string', }, }, required: ['name'], additionalProperties: true, }); schema.ok({test: {name: 'AtrixSwagger'}}); schema.ok({test: {name: 'AtrixSwagger', ndn: 'asdf', asd: {a: [1, 3]}}}); schema.fail({test: {}}, /is required/); expect(schema.schema._inner.children[0].schema._description).to.equal('desc'); // eslint-disable-line }); }); });