Test to validate that two fields of a schema are equals
alexisab opened this issue ยท 5 comments
It would be nice if we could check that two fields are equals. Something like that :
v8n().schema({
password: v8n().string().minLength(8).maxLength(40),
confirmPassword: v8n().equalTo('password')
})
What do you think about ?
That's definitely a useful validation check. But we need to figure out a way to make it work in a clean way.
We should not couple a rule to its environment, like:
v8n().equalTo('password')
Because this would make our equalTo
very tied to the schema
, and we do not want something that.
What I think we could do is to make the rule schema
to also work with a function
as argument. That functio would take the validated object as its argument and return the schema object, like this:
v8n().schema(validatedObj => {
password: v8n().string().minLength(8),
confirmPassword: v8n().equal(validatedObj.password)
});
This looks much better to me. But it's definitely something we need to think about before implementing that.
It's exactly what I've done to validate my schema. I've used a function and the equal
rule, it works pretty well.
I think this can be achieved with current rules very well.
@alexisab Could you provide a sample of what you did?
In fact I've just encapsulate my validation logic in a function :
in validate.js
const _ = require('lodash')
const v8n = require('v8n')
const validate = (obj, specs) => {
try {
specs = specs instanceof Function ? specs(obj) : specs
const validation = v8n().schema(specs)
validation.check(obj)
return obj
} catch (error) {
const details = error.cause
.map(c => _.pick(c, 'rule.name', 'rule.args', 'target'))
.map(d => ({
target: d.target,
rule: d.rule.name,
requirements: d.rule.args,
}))
throw {
status: 400,
details,
}
}
}
module.exports = { validate }
In my signin
controller :
const { accessId, password } = validate(
ctx.request.body,
User.getValidShape(true)
)
where User.getValidShape
function is :
const getValidShape = (withConfirm = false) => {
const baseShape = {
accessId: v8n().string(),
password: v8n()
.string()
.minLength(8)
.maxLength(40),
}
if (withConfirm) {
return obj => ({
...baseShape,
confirmPassword: v8n().equal(obj.password),
})
}
return baseShape
}
Seems good! Closing this for now, I don't believe this is necessary as a standalone feature.