This starts the rewrite of the dynamic badges. I've pulled into BaseService an initial version of the query param validation from #2325. I've extended from BaseJsonService to avoid duplicating the deserialization logic, though it means there is a bit of duplicated code among the three dynamic services. The way to unravel this would be to move the logic from `_requestJson` and friends from the base classes into functions so DynamicJson can inherit from BaseDynamic. Would that be worth it? This introduces a regression of #1446 for this badge. Close #2345
109 lines
3.1 KiB
JavaScript
109 lines
3.1 KiB
JavaScript
'use strict'
|
|
|
|
const Joi = require('joi')
|
|
const { expect } = require('chai')
|
|
const sinon = require('sinon')
|
|
const trace = require('../services/trace')
|
|
const { InvalidParameter } = require('../services/errors')
|
|
const validate = require('./validate')
|
|
|
|
describe('validate', function() {
|
|
const schema = Joi.object({
|
|
requiredString: Joi.string().required(),
|
|
}).required()
|
|
|
|
let sandbox
|
|
beforeEach(function() {
|
|
sandbox = sinon.createSandbox()
|
|
})
|
|
afterEach(function() {
|
|
sandbox.restore()
|
|
})
|
|
beforeEach(function() {
|
|
sandbox.stub(trace, 'logTrace')
|
|
})
|
|
|
|
const ErrorClass = InvalidParameter
|
|
const prettyErrorMessage = 'parameter does not match schema'
|
|
const traceErrorMessage = 'Params did not match schema'
|
|
const traceSuccessMessage = 'Params after validation'
|
|
|
|
const options = {
|
|
ErrorClass,
|
|
prettyErrorMessage,
|
|
traceErrorMessage,
|
|
traceSuccessMessage,
|
|
}
|
|
|
|
context('schema is not provided', function() {
|
|
it('throws the expected programmer error', function() {
|
|
try {
|
|
validate(options, { requiredString: 'bar' }, undefined)
|
|
expect.fail('Expected to throw')
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceof(Error)
|
|
expect(e.message).to.equal('A Joi schema is required')
|
|
}
|
|
})
|
|
})
|
|
|
|
context('data matches schema', function() {
|
|
it('logs the data', function() {
|
|
validate(options, { requiredString: 'bar' }, schema)
|
|
expect(trace.logTrace).to.be.calledWithMatch(
|
|
'validate',
|
|
sinon.match.string,
|
|
traceSuccessMessage,
|
|
{ requiredString: 'bar' },
|
|
{ deep: true }
|
|
)
|
|
})
|
|
})
|
|
|
|
context('data does not match schema', function() {
|
|
it('logs the data and throws the expected error', function() {
|
|
try {
|
|
validate(
|
|
options,
|
|
{ requiredString: ['this', "shouldn't", 'work'] },
|
|
schema
|
|
)
|
|
expect.fail('Expected to throw')
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceof(InvalidParameter)
|
|
expect(e.message).to.equal(
|
|
'Invalid Parameter: child "requiredString" fails because ["requiredString" must be a string]'
|
|
)
|
|
expect(e.prettyMessage).to.equal(prettyErrorMessage)
|
|
}
|
|
expect(trace.logTrace).to.be.calledWithMatch(
|
|
'validate',
|
|
sinon.match.string,
|
|
traceErrorMessage,
|
|
'child "requiredString" fails because ["requiredString" must be a string]'
|
|
)
|
|
})
|
|
|
|
context('with includeKeys: true', function() {
|
|
it('includes keys in the error text', function() {
|
|
try {
|
|
validate(
|
|
{ ...options, includeKeys: true },
|
|
{ requiredString: ['this', "shouldn't", 'work'] },
|
|
schema
|
|
)
|
|
expect.fail('Expected to throw')
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceof(InvalidParameter)
|
|
expect(e.message).to.equal(
|
|
'Invalid Parameter: child "requiredString" fails because ["requiredString" must be a string]'
|
|
)
|
|
expect(e.prettyMessage).to.equal(
|
|
`${prettyErrorMessage}: requiredString`
|
|
)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
})
|