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

Commit 80e1774d by Rui Marinho Committed by Jan Aagaard Meier

Improve validation when dealing with non-strings (#5861)

* Improve validation when dealing with non-strings

validator@5.0.0+ has stopped coercing input values as strings and since
version 4, the library has been printing deprecation notices everytime a
non-string is passed to it.

All `validate` functions now correctly handle theses cases by delegating
this work to lodash functions.

* Coerce number values when validating
1 parent 45b9990e
# Future
- [FIXED] Type validation now works with non-strings due to updated validator@5.0.0 [#5861](https://github.com/sequelize/sequelize/pull/5861)
- [FIXED] Improved offset and limit support for SQL server 2008 [#5616](https://github.com/sequelize/sequelize/pull/5616)
# 3.23.1
......
......@@ -191,7 +191,7 @@ TEXT.prototype.toSql = function() {
}
};
TEXT.prototype.validate = function(value) {
if (typeof value !== 'string') {
if (!_.isString(value)) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid string', value));
}
......@@ -228,7 +228,7 @@ NUMBER.prototype.toSql = function() {
};
NUMBER.prototype.validate = function(value) {
if (!_.isNumber(value)) {
if (!Validator.isFloat(String(value))) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid number', value));
}
......@@ -267,7 +267,7 @@ var INTEGER = NUMBER.inherits(function(length) {
INTEGER.prototype.key = INTEGER.key = 'INTEGER';
INTEGER.prototype.validate = function(value) {
if (!Validator.isInt(value)) {
if (!Validator.isInt(String(value))) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid integer', value));
}
......@@ -294,7 +294,7 @@ var BIGINT = NUMBER.inherits(function(length) {
BIGINT.prototype.key = BIGINT.key = 'BIGINT';
BIGINT.prototype.validate = function(value) {
if (!Validator.isInt(value)) {
if (!Validator.isInt(String(value))) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid bigint', value));
}
......@@ -319,7 +319,7 @@ var FLOAT = NUMBER.inherits(function(length, decimals) {
FLOAT.prototype.key = FLOAT.key = 'FLOAT';
FLOAT.prototype.validate = function(value) {
if (!Validator.isFloat(value)) {
if (!Validator.isFloat(String(value))) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid float', value));
}
......@@ -387,7 +387,7 @@ DECIMAL.prototype.toSql = function() {
return 'DECIMAL';
};
DECIMAL.prototype.validate = function(value) {
if (!Validator.isDecimal(value)) {
if (!Validator.isDecimal(String(value))) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid decimal', value));
}
......@@ -419,7 +419,7 @@ BOOLEAN.prototype.toSql = function() {
return 'TINYINT(1)';
};
BOOLEAN.prototype.validate = function(value) {
if (!Validator.isBoolean(value)) {
if (!Validator.isBoolean(String(value))) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid boolean', value));
}
......@@ -458,7 +458,7 @@ DATE.prototype.toSql = function() {
return 'DATETIME';
};
DATE.prototype.validate = function(value) {
if (!Validator.isDate(value)) {
if (!_.isDate(value)) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid date', value));
}
......@@ -672,7 +672,7 @@ var UUID = ABSTRACT.inherits();
UUID.prototype.key = UUID.key = 'UUID';
UUID.prototype.validate = function(value, options) {
if (!Validator.isUUID(value) && (!options || !options.acceptStrings || typeof value !== 'string')) {
if (!_.isString(value) || !Validator.isUUID(value) && (!options || !options.acceptStrings)) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid uuid', value));
}
......@@ -692,7 +692,7 @@ util.inherits(UUIDV1, ABSTRACT);
UUIDV1.prototype.key = UUIDV1.key = 'UUIDV1';
UUIDV1.prototype.validate = function(value, options) {
if (!Validator.isUUID(value) && (!options || !options.acceptStrings || typeof value !== 'string')) {
if (!_.isString(value) || !Validator.isUUID(value) && (!options || !options.acceptStrings)) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid uuid', value));
}
......@@ -712,7 +712,7 @@ util.inherits(UUIDV4, ABSTRACT);
UUIDV4.prototype.key = UUIDV4.key = 'UUIDV4';
UUIDV4.prototype.validate = function(value, options) {
if (!Validator.isUUID(value, 4) && (!options || !options.acceptStrings || typeof value !== 'string')) {
if (!_.isString(value) || !Validator.isUUID(value, 4) && (!options || !options.acceptStrings)) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid uuidv4', value));
}
......@@ -815,7 +815,7 @@ ARRAY.prototype.toSql = function() {
return this.type.toSql() + '[]';
};
ARRAY.prototype.validate = function(value) {
if (!Array.isArray(value)) {
if (!_.isArray(value)) {
throw new sequelizeErrors.ValidationError(util.format('%j is not a valid array', value));
}
......
......@@ -4,6 +4,11 @@ var validator = require('validator')
, _ = require('lodash');
var extensions = {
extend: function(name, fn) {
this[name] = fn;
return this;
},
notEmpty: function(str) {
return !str.match(/^[\s\t\r\n]*$/);
},
......@@ -64,7 +69,7 @@ var extendModelValidations = function(modelInstance) {
};
_.forEach(extensions, function(extend, key) {
validator.extend(key, extend);
validator[key] = extend;
});
};
......@@ -75,7 +80,7 @@ validator.notNull = function() {
// https://github.com/chriso/validator.js/blob/1.5.0/lib/validators.js
_.forEach(extensions, function(extend, key) {
validator.extend(key, extend);
validator[key] = extend;
});
module.exports = {
......
......@@ -46,7 +46,7 @@
"shimmer": "1.1.0",
"terraformer-wkt-parser": "^1.1.0",
"toposort-class": "^1.0.1",
"validator": "^4.6.1",
"validator": "^5.2.0",
"wkx": "0.2.0"
},
"devDependencies": {
......
......@@ -162,6 +162,10 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(type.validate(true)).to.equal(true);
expect(type.validate(false)).to.equal(true);
expect(type.validate('1')).to.equal(true);
expect(type.validate('0')).to.equal(true);
expect(type.validate('true')).to.equal(true);
expect(type.validate('false')).to.equal(true);
});
});
});
......@@ -233,6 +237,10 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(function () {
type.validate('foobar');
}).to.throw(Sequelize.ValidationError, '"foobar" is not a valid uuid');
expect(function () {
type.validate(['foobar']);
}).to.throw(Sequelize.ValidationError, '["foobar"] is not a valid uuid');
});
test('should return `true` if `value` is an uuid', function() {
......@@ -261,6 +269,10 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(function () {
type.validate('foobar');
}).to.throw(Sequelize.ValidationError, '"foobar" is not a valid uuid');
expect(function () {
type.validate(['foobar']);
}).to.throw(Sequelize.ValidationError, '["foobar"] is not a valid uuid');
});
test('should return `true` if `value` is an uuid', function() {
......@@ -290,6 +302,10 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(function () {
type.validate(value);
}).to.throw(Sequelize.ValidationError, util.format('%j is not a valid uuidv4', value));
expect(function () {
type.validate(['foobar']);
}).to.throw(Sequelize.ValidationError, '["foobar"] is not a valid uuidv4');
});
test('should return `true` if `value` is an uuid', function() {
......@@ -377,11 +393,20 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(function () {
type.validate('foobar');
}).to.throw(Sequelize.ValidationError, '"foobar" is not a valid integer');
expect(function () {
type.validate('123.45');
}).to.throw(Sequelize.ValidationError, '"123.45" is not a valid integer');
expect(function () {
type.validate(123.45);
}).to.throw(Sequelize.ValidationError, '123.45 is not a valid integer');
});
test('should return `true` if `value` is a valid integer', function() {
var type = DataTypes.INTEGER();
expect(type.validate('12345')).to.equal(true);
expect(type.validate(12345)).to.equal(true);
});
});
......@@ -451,12 +476,16 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(function () {
type.validate('foobar');
}).to.throw(Sequelize.ValidationError, '"foobar" is not a valid bigint');
expect(function () {
type.validate(123.45);
}).to.throw(Sequelize.ValidationError, '123.45 is not a valid bigint');
});
test('should return `true` if `value` is an integer', function() {
var type = DataTypes.BIGINT();
expect(type.validate(12345)).to.equal(true);
expect(type.validate('9223372036854775807')).to.equal(true);
});
});
});
......@@ -730,12 +759,20 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
expect(function () {
type.validate('foobar');
}).to.throw(Sequelize.ValidationError, '"foobar" is not a valid float');
expect(function () {
type.validate('-.123');
}).to.throw(Sequelize.ValidationError, '"-.123" is not a valid float');
});
test('should return `true` if `value` is a float', function() {
var type = DataTypes.FLOAT();
expect(type.validate(1.2)).to.equal(true);
expect(type.validate('1')).to.equal(true);
expect(type.validate('1.2')).to.equal(true);
expect(type.validate('-0.123')).to.equal(true);
expect(type.validate('-0.22250738585072011e-307')).to.equal(true);
});
});
});
......@@ -770,6 +807,37 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
testsql('DECIMAL({ precision: 10 })', DataTypes.DECIMAL({ precision: 10 }), {
default: 'DECIMAL(10)'
});
suite('validate', function () {
test('should throw an error if `value` is invalid', function() {
var type = DataTypes.DECIMAL(10);
expect(function () {
type.validate('foobar');
}).to.throw(Sequelize.ValidationError, '"foobar" is not a valid decimal');
expect(function () {
type.validate('0.1a');
}).to.throw(Sequelize.ValidationError, '"0.1a" is not a valid decimal');
expect(function () {
type.validate(NaN);
}).to.throw(Sequelize.ValidationError, 'null is not a valid decimal');
});
test('should return `true` if `value` is a decimal', function() {
var type = DataTypes.DECIMAL(10);
expect(type.validate(123)).to.equal(true);
expect(type.validate(1.2)).to.equal(true);
expect(type.validate(-0.25)).to.equal(true);
expect(type.validate(0.0000000000001)).to.equal(true);
expect(type.validate('123')).to.equal(true);
expect(type.validate('1.2')).to.equal(true);
expect(type.validate('-0.25')).to.equal(true);
expect(type.validate('0.0000000000001')).to.equal(true);
});
});
});
suite('ENUM', function () {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!