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.
247 lines
5.7 KiB
247 lines
5.7 KiB
4 years ago
|
'use strict'
|
||
|
|
||
|
const t = require('tap')
|
||
|
const test = t.test
|
||
|
|
||
|
const Ajv = require('ajv')
|
||
|
const ajv = new Ajv({ coerceTypes: true })
|
||
|
|
||
|
const validation = require('../../lib/validation')
|
||
|
const { Schemas } = require('../../lib/schemas')
|
||
|
const symbols = require('../../lib/validation').symbols
|
||
|
|
||
|
test('Symbols', t => {
|
||
|
t.plan(5)
|
||
|
t.is(typeof symbols.responseSchema, 'symbol')
|
||
|
t.is(typeof symbols.bodySchema, 'symbol')
|
||
|
t.is(typeof symbols.querystringSchema, 'symbol')
|
||
|
t.is(typeof symbols.paramsSchema, 'symbol')
|
||
|
t.is(typeof symbols.headersSchema, 'symbol')
|
||
|
})
|
||
|
|
||
|
test('build schema - missing schema', t => {
|
||
|
t.plan(1)
|
||
|
const opts = {}
|
||
|
validation.build(opts)
|
||
|
t.is(typeof opts[symbols.responseSchema], 'undefined')
|
||
|
})
|
||
|
|
||
|
test('build schema - missing output schema', t => {
|
||
|
t.plan(1)
|
||
|
const opts = { schema: {} }
|
||
|
validation.build(opts, null, new Schemas())
|
||
|
t.is(typeof opts[symbols.responseSchema], 'undefined')
|
||
|
})
|
||
|
|
||
|
test('build schema - output schema', t => {
|
||
|
t.plan(2)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
response: {
|
||
|
'2xx': {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
},
|
||
|
201: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'number' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.is(typeof opts[symbols.responseSchema]['2xx'], 'function')
|
||
|
t.is(typeof opts[symbols.responseSchema]['201'], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - payload schema', t => {
|
||
|
t.plan(1)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
body: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.is(typeof opts[symbols.bodySchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - query schema', t => {
|
||
|
t.plan(2)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
query: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
||
|
t.is(typeof opts[symbols.querystringSchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - query schema abbreviated', t => {
|
||
|
t.plan(2)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
query: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
||
|
t.is(typeof opts[symbols.querystringSchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - querystring schema', t => {
|
||
|
t.plan(2)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
querystring: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
||
|
t.is(typeof opts[symbols.querystringSchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - querystring schema abbreviated', t => {
|
||
|
t.plan(2)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
querystring: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.type(opts[symbols.querystringSchema].schema.type, 'string')
|
||
|
t.is(typeof opts[symbols.querystringSchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - must throw if querystring and query schema exist', t => {
|
||
|
t.plan(2)
|
||
|
try {
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
query: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
},
|
||
|
querystring: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
} catch (err) {
|
||
|
t.is(err.code, 'FST_ERR_SCH_DUPLICATE')
|
||
|
t.is(err.message, 'FST_ERR_SCH_DUPLICATE: Schema with \'querystring\' already present!')
|
||
|
}
|
||
|
})
|
||
|
|
||
|
test('build schema - params schema', t => {
|
||
|
t.plan(1)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
params: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
hello: { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.is(typeof opts[symbols.paramsSchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - headers schema', t => {
|
||
|
t.plan(1)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
headers: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
'content-type': { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => ajv.compile(schema), new Schemas())
|
||
|
t.is(typeof opts[symbols.headersSchema], 'function')
|
||
|
})
|
||
|
|
||
|
test('build schema - headers are lowercase', t => {
|
||
|
t.plan(1)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
headers: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
'Content-Type': { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => {
|
||
|
t.ok(schema.properties['content-type'], 'lowercase content-type exists')
|
||
|
return () => {}
|
||
|
}, new Schemas())
|
||
|
})
|
||
|
|
||
|
test('build schema - headers are not lowercased in case of custom object', t => {
|
||
|
t.plan(1)
|
||
|
|
||
|
class Headers {}
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
headers: new Headers()
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => {
|
||
|
t.type(schema, Headers)
|
||
|
return () => {}
|
||
|
}, new Schemas())
|
||
|
})
|
||
|
|
||
|
test('build schema - uppercased headers are not included', t => {
|
||
|
t.plan(1)
|
||
|
const opts = {
|
||
|
schema: {
|
||
|
headers: {
|
||
|
type: 'object',
|
||
|
properties: {
|
||
|
'Content-Type': { type: 'string' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
validation.build(opts, schema => {
|
||
|
t.notOk('Content-Type' in schema.properties, 'uppercase does not exist')
|
||
|
return () => {}
|
||
|
}, new Schemas())
|
||
|
})
|