不要怂,就是干,撸起袖子干!

Commit 735b2a48 by Pavel Kabakin Committed by Sushant

feat(validation): improve validation for type(#9660)

1 parent 31113cec
...@@ -16,6 +16,7 @@ const BelongsToMany = require('../../associations/belongs-to-many'); ...@@ -16,6 +16,7 @@ const BelongsToMany = require('../../associations/belongs-to-many');
const HasMany = require('../../associations/has-many'); const HasMany = require('../../associations/has-many');
const QueryTypes = require('../../query-types'); const QueryTypes = require('../../query-types');
const Op = require('../../operators'); const Op = require('../../operators');
const sequelizeError = require('../../errors');
const QuoteHelper = require('./query-generator/helpers/quote'); const QuoteHelper = require('./query-generator/helpers/quote');
...@@ -1031,12 +1032,27 @@ class QueryGenerator { ...@@ -1031,12 +1032,27 @@ class QueryGenerator {
*/ */
validate(value, field, options) { validate(value, field, options) {
if (this.typeValidation && field.type.validate && value) { if (this.typeValidation && field.type.validate && value) {
if (options.isList && Array.isArray(value)) { try {
for (const item of value) { if (options.isList && Array.isArray(value)) {
field.type.validate(item, options); for (const item of value) {
field.type.validate(item, options);
}
} else {
field.type.validate(value, options);
} }
} else { } catch (error) {
field.type.validate(value, options); if (error instanceof sequelizeError.ValidationError) {
error.errors.push(new sequelizeError.ValidationErrorItem(
error.message,
'Validation error',
field.fieldName,
value,
null,
`${field.type.key} validator`
));
}
throw error;
} }
} }
} }
......
...@@ -132,6 +132,10 @@ class InstanceValidator { ...@@ -132,6 +132,10 @@ class InstanceValidator {
const value = this.modelInstance.dataValues[field]; const value = this.modelInstance.dataValues[field];
if (value instanceof Utils.SequelizeMethod) {
return;
}
if (!rawAttribute._autoGenerated && !rawAttribute.autoIncrement) { if (!rawAttribute._autoGenerated && !rawAttribute.autoIncrement) {
// perform validations based on schema // perform validations based on schema
this._validateSchema(rawAttribute, field, value); this._validateSchema(rawAttribute, field, value);
......
...@@ -546,6 +546,24 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => { ...@@ -546,6 +546,24 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => {
return expect(failingBar.validate({ skip: ['field'] })).not.to.be.rejected; return expect(failingBar.validate({ skip: ['field'] })).not.to.be.rejected;
}); });
it('skips validations for fields with value that is SequelizeMethod', function() {
const values = ['value1', 'value2'];
const Bar = this.sequelize.define('Bar' + config.rand(), {
field: {
type: Sequelize.ENUM,
values,
validate: {
isIn: [values]
}
}
});
const failingBar = Bar.build({ field: this.sequelize.literal('5 + 1') });
return expect(failingBar.validate()).not.to.be.rejected;
});
it('raises an error if saving a different value into an immutable field', function() { it('raises an error if saving a different value into an immutable field', function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
name: { name: {
......
...@@ -382,13 +382,37 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => { ...@@ -382,13 +382,37 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => {
it('should throw when passing string', () => { it('should throw when passing string', () => {
return expect(User.create({ return expect(User.create({
age: 'jan' age: 'jan'
})).to.be.rejectedWith(current.ValidationError); })).to.be.rejectedWith(current.ValidationError)
.which.eventually.have.property('errors')
.that.is.an('array')
.with.lengthOf(1)
.and.with.property(0)
.that.is.an.instanceOf(current.ValidationErrorItem)
.and.include({
type: 'Validation error',
path: 'age',
value: 'jan',
instance: null,
validatorKey: 'INTEGER validator'
});
}); });
it('should throw when passing decimal', () => { it('should throw when passing decimal', () => {
return expect(User.create({ return expect(User.create({
age: 4.5 age: 4.5
})).to.be.rejectedWith(current.ValidationError); })).to.be.rejectedWith(current.ValidationError)
.which.eventually.have.property('errors')
.that.is.an('array')
.with.lengthOf(1)
.and.with.property(0)
.that.is.an.instanceOf(current.ValidationErrorItem)
.and.include({
type: 'Validation error',
path: 'age',
value: 4.5,
instance: null,
validatorKey: 'INTEGER validator'
});
}); });
}); });
...@@ -396,13 +420,37 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => { ...@@ -396,13 +420,37 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), () => {
it('should throw when passing string', () => { it('should throw when passing string', () => {
return expect(User.update({ return expect(User.update({
age: 'jan' age: 'jan'
}, { where: {}})).to.be.rejectedWith(current.ValidationError); }, { where: {}})).to.be.rejectedWith(current.ValidationError)
.which.eventually.have.property('errors')
.that.is.an('array')
.with.lengthOf(1)
.and.with.property(0)
.that.is.an.instanceOf(current.ValidationErrorItem)
.and.include({
type: 'Validation error',
path: 'age',
value: 'jan',
instance: null,
validatorKey: 'INTEGER validator'
});
}); });
it('should throw when passing decimal', () => { it('should throw when passing decimal', () => {
return expect(User.update({ return expect(User.update({
age: 4.5 age: 4.5
}, { where: {}})).to.be.rejectedWith(current.ValidationError); }, { where: {}})).to.be.rejectedWith(current.ValidationError)
.which.eventually.have.property('errors')
.that.is.an('array')
.with.lengthOf(1)
.and.with.property(0)
.that.is.an.instanceOf(current.ValidationErrorItem)
.and.include({
type: 'Validation error',
path: 'age',
value: 4.5,
instance: null,
validatorKey: 'INTEGER validator'
});
}); });
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!