Yup: How to access the "inner" propriety in ValidationError() method - javascript

Yup contain a method name validationError whose one of properties is "inner". Accordingly with the documentation:
in the case of aggregate errors, inner is an array of ValidationErrors
throw earlier in the validation chain. When the abortEarly option is
false this is where you can inspect each error thrown, alternatively,
errors will have all of the messages from each inner error.
However, it's properly working is not quite clear to me. How exactly I do to access this property and use it in my code.
Here, I'm trying to use in this application but it seems not working.
function validator (req, res, next) {
yup.setLocale({
mixed: {
default: 'Não é válido',
}
});
const schema = yup.object().shape({
name: yup.string().required("Legendary name is required"),
type: yup.string().required("Legendary type is required"),
description: yup.string().required("Legendary description is required").min(10)
});
let messageError = new yup.ValidationError([`${req.body.name}`, `${req.body.type}`, `${req.body.description}`]);
if(!schema.isValidSync(req.body, {abortEarly: false})) {
return res.status(400).json(messageError.inner);
}
When I run it with insomnia, I get a empty array only.
Can someone help me with this, please ?

ValidationError is thrown is by the validate* methods (validate, validateSync, validateAt, and validateSyncAt) when the validation fails. isValidSync returns a boolean and doesn't throw any errors. Use validateSync and add a catch block to access the validation errors.
messageError.inner returns an empty array since messageError is a standalone ValidationError object which isn't associated with the schema in any way.
try {
schema.validateSync(req.body, { abortEarly: false })
} catch (err) {
// err is of type ValidationError
return res.status(400).json(err.inner)
}
curl -s -X POST http://localhost:5000/test | jq
[
{
"name": "ValidationError",
"path": "name",
"type": "required",
"errors": [
"Legendary name is required"
],
"inner": [],
"message": "Legendary name is required",
"params": {
"path": "name"
}
},
{
"name": "ValidationError",
"path": "type",
"type": "required",
"errors": [
"Legendary type is required"
],
"inner": [],
"message": "Legendary type is required",
"params": {
"path": "type"
}
},
{
"name": "ValidationError",
"path": "description",
"type": "required",
"errors": [
"Legendary description is required"
],
"inner": [],
"message": "Legendary description is required",
"params": {
"path": "description"
}
}
]

Related

How to verify if a value is of format and/or type double using ajv schema validation?

Im using Ajv version 07.
I am trying to validate that the value of a property, returned by the JSON response body is of type and format double in postman, using ajv validation, however, I'm not being able to do it. I've tried searching it online, but still did not find anything about it.
I've tried typing the following:
"type" : "double",
"format": "double"
"type": "Double",
"format": "Double"
"type":"number"
"format":"double"
All the above attempts were unsuccessful as they all come with an error message saying either:
Error: unknown type "double" is used in schema
or
Error: unknown format "double" is used in schema
Would anyone be able to help me with this please?
schema
var Ajv = require ('ajv'),
ajv = new Ajv ({logger:console}),
expectedResponseSchema =
{
"items": {
"required": [
"payments"
],
"properties": {
"payments": {
"items": {
"required": [
"amount"
]
"properties": {
"amount": {
"$id": "#/items/properties/payments/items/properties/amount",
"type": "number",
"format": "double"
}
}
}
}
}
}
Postman test
var currentSchPmExpTest;
try{
currentSchPmExpTest = ' expectedResponseSchema variable';
pm.expect(ajv.validate(expectedResponseSchema, jsonData)).to.be.true;
pm.test('Test 1 - PASSED - expectedResponseSchema variable data matches schema returned by body response!', () => true);
} catch(e){
pm.test('Test 1 - FAILED - Expected data does not match response body data!', () => {throw new Error(e.message + " in " + currentSchPmExpTest)});
}
body response
[
{
"payments": [
{
"amount": 2.200000045367898,
}
]
}
]
I'm not sure where you're getting the type and format from but as per the AJV docs (could be out of date) that isn't a valid type.
EDIT:
From your update, I would recommend changing the test script to something like this so that you correct part of the schema is getting checked:
let schema = {
"type": "array",
"items": {
"type": "object",
"required": [
"payments"
],
"properties": {
"payments": {
"type": "array",
"items": {
"type": "object",
"required": [
"amount"
],
"properties": {
"amount": {
"type": "number",
}
}
}
}
}
}
}
pm.test("Check Schema", () => {
pm.response.to.have.jsonSchema(schema)
})
The try/catch block can be added around this if you need too.

JSON schema + relative JSON-pointers: how to verify "confirm password" field

Here's my JSON Schema:
{
"required": [
"username",
"password",
"confirmPassword"
],
"properties": {
"username": {
"minLength": 3,
"type": "string"
},
"password": {
"minLength": 6,
"type": "string"
},
"confirmPassword": {
"const": {
"$data": "1/password"
},
"type": "string"
}
},
"type": "object"
}
Here's my data:
{
"username": "abc",
"password": "asdfasdf",
"confirmPassword": "asdfasdf"
}
You can copy-paste those into this online validator to see what happens.
The confirmPassword field is failing validation with error message:
Value "asdfasdf" does not match const.
I believe there is a problem with my relative JSON pointer but I can't figure out what the correct syntax is.
AFAICT, 1/password means "go up one level, and then check the password property" but that doesn't appear to be the case. What's correct syntax?
The specific implementation I'm using is AJV which says it does support relative-JSON-pointers.
Turns out the only problem was that I forgot to set the $data option to true. e.g.
const ajv = new Ajv({
allErrors: true,
$data: true,
});

Node.js/Mongo schema validation error regardless of POST data

I have mongo and node playing together on AWS EC2. Node (w/ Express) can connect to Mongo so to start with I've setup a schema with two required fields "sesh" and "location".
This is the javascript that gets called for the post query:
app.post('/spotters', function(req,res){
var newSesh = new modelentry(req.body);
newSesh.save(function(err){
if(err)
res.send(err);
res.json(req.body);
});
});
modelentry is the schema of course.
I'm trying to POST the following raw/json data using Postman
{
sesh: 1,
location: [1,2]
}
However I always recieve a validation failed message, as follows:
{
"message": "hotuser validation failed",
"name": "ValidationError",
"errors": {
"location": {
"message": "Path `location` is required.",
"name": "ValidatorError",
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "location"
},
"kind": "required",
"path": "location"
},
"sesh": {
"message": "Path `sesh` is required.",
"name": "ValidatorError",
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "sesh"
},
"kind": "required",
"path": "sesh"
}
}
}
I have looked at a lot of example code and tried tinkering with the functions in app.post but I'm not making any progress. I would really appreciate any help.

ValidatorError on adding records

I am trying to add a record to my mongodb database. I am sure that I am providing correct values, although mongoose is considering them missing. Here's my Schema -
var mongoose = require('mongoose');
var SocketUserSchema = new mongoose.Schema({
name: String,
username: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
devices: [{
name: String,
platform: String
}],
first_ip: {
type: String,
default: "0.0.0.0"
},
last_login_ip: {
type: String,
default: "0.0.0.0"
},
added_at: {
type: Date,
default: Date.now
},
});
module.exports = mongoose.model('SocketUser', SocketUserSchema);
Here's my create code snippet -
console.log('registered triggered ' + data);
/*var jsonData = data;
jsonData.first_ip = clientIpAddress;
jsonData.last_login_ip = clientIpAddress;*/
var user = new SocketUser({
username: data.username,
password: data.password,
devices: data.devices,
first_ip: clientIpAddress,
last_login_ip: clientIpAddress
});
SocketUser.create(user, function(err, post) {
if (err) {
console.log('error',err);
} else {
console.log('success');
}
});
Here's the sample user data I am sending -
{
"username": "nexus",
"password": "noob",
"devices": [
{
"name": "Nexus",
"platform": "android"
}
]
}
And here's the error I am getting -
{
"message": "SocketUser validation failed",
"name": "ValidationError",
"errors": {
"username": {
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "username"
},
"message": "Path `username` is required.",
"name": "ValidatorError",
"kind": "required",
"path": "username"
},
"password": {
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "password"
},
"message": "Path `password` is required.",
"name": "ValidatorError",
"kind": "required",
"path": "password"
}
}
}
As you can see, username and password both fields are there in the data, but still it's giving error. I have tried sending data json directly to Create method and also tried save method too. Both gives same error. Is there anything I am missing here?
Update:
I tried validating the record, before adding it to database and it gave same error -
user.validate(function(err) {
if (err) {
console.log("error "+err.message+"\nFull error: "+JSON.stringify(err));
}
else {
}
});
registered triggered {"username":"nexus","password":"noob","devices":[{"name":"N
exus","platform":"android"}]}
error SocketUser validation failed
Full error: {"message":"SocketUser validation failed","name":"ValidationError","
errors":{"password":{"properties":{"type":"required","message":"Path `{PATH}` is
required.","path":"password"},"message":"Path `password` is required.","name":"
ValidatorError","kind":"required","path":"password"},"username":{"properties":{"
type":"required","message":"Path `{PATH}` is required.","path":"username"},"mess
age":"Path `username` is required.","name":"ValidatorError","kind":"required","p
ath":"username"}}}
I am unable to find the issue with username and password. I want these fields as required fields for obvious reasons.
I found the issue, I checked if I am getting data.username and data.password properly or not. They were resulting in undefined. Then I realized that the data is actually a string, not an object. So I parsed it into json and then I got it working. Here's the code to do it, in case somebody get stuck at the same issue -
data = JSON.parse(data);

How to check the value is in object with Chai?

Is it possible to test the value is contained within certain array with Chai assertion library?
Example:
var myObject = {
a : 1,
b : 2,
c : 3
};
var myValue = 2;
I need to do something like this (however it is not working):
expect(myObject).values.to.contain(myValue);
//Error: Cannot read property 'to' of undefined
expect(myObject).to.contain(myValue);
//Error: Object #<Object> has no method 'indexOf'
How can I test this?
Alternatively if you want to check the value along with the property you can do
expect(myObject).to.have.property('b', myValue);
You won't need the plugin for this check.
The chai fuzzy plugin has the functionality you needed.
var myObject = {
a : 1,
b : 2,
c : 3
};
var myValue = 2;
myObject.should.containOneLike(myValue);
if the object is bit nested, like
{
"errors": {
"text": {
"message": "Path `text` is required.",
"name": "ValidatorError",
"properties": {
"message": "Path `{PATH}` is required.",
"type": "required",
"path": "text",
"value": ""
},
"kind": "required",
"path": "text",
"value": "",
"$isValidatorError": true
}
},
"_message": "todos validation failed",
"message": "todos validation failed: text: Path `text` is required.",
"name": "ValidationError"
}
then do an assertion on errors.text.message, we can do like
expect(res.body).to.have
.property('errors')
.property('text')
.property('message', 'Path text is required.');

Categories