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

Commit f449abc9 by Mick Hansen

Merge pull request #1476 from thanpolas/refactor-dao-validator

Refactor dao validator
2 parents f435d6b3 0e112da3
...@@ -21,5 +21,6 @@ ...@@ -21,5 +21,6 @@
"laxcomma": true, "laxcomma": true,
"es5": true, "es5": true,
"quotmark": false, "quotmark": false,
"undef": true,
"strict": false "strict": false
} }
\ No newline at end of file
...@@ -7,6 +7,9 @@ Notice: All 1.7.x changes are present in 2.0.x aswell ...@@ -7,6 +7,9 @@ Notice: All 1.7.x changes are present in 2.0.x aswell
- [FEATURE] 1:1 and 1:m marks columns as foreign keys, and sets them to cascade on update and set null on delete. If you are working with an existing DB which does not allow null values, be sure to override those options, or disable them completely by passing constraints: false to your assocation call (`M1.belongsTo(M2, { constraints: false})`). - [FEATURE] 1:1 and 1:m marks columns as foreign keys, and sets them to cascade on update and set null on delete. If you are working with an existing DB which does not allow null values, be sure to override those options, or disable them completely by passing constraints: false to your assocation call (`M1.belongsTo(M2, { constraints: false})`).
#### Backwards compatability changes #### Backwards compatability changes
- The `notNull` validator has been removed, use the Schema's `allowNull` property.
- All Validation errors now return a sequelize.ValidationError which inherits from Error.
- selectedValues has been removed for performance reasons, if you depend on this, please open an issue and we will help you work around it. - selectedValues has been removed for performance reasons, if you depend on this, please open an issue and we will help you work around it.
- foreign keys will now correctly be based on the alias of the model - foreign keys will now correctly be based on the alias of the model
- if you have any 1:1 relations where both sides use an alias, you'll need to set the foreign key, or they'll each use a different foreign key based on their alias. - if you have any 1:1 relations where both sides use an alias, you'll need to set the foreign key, or they'll each use a different foreign key based on their alias.
......
...@@ -119,7 +119,7 @@ module.exports = (function() { ...@@ -119,7 +119,7 @@ module.exports = (function() {
} else { } else {
this.as = Utils.pluralize(this.target.name, this.target.options.language) this.as = Utils.pluralize(this.target.name, this.target.options.language)
} }
this.accessors = { this.accessors = {
get: Utils._.camelize('get_' + this.as), get: Utils._.camelize('get_' + this.as),
set: Utils._.camelize('set_' + this.as), set: Utils._.camelize('set_' + this.as),
...@@ -195,7 +195,8 @@ module.exports = (function() { ...@@ -195,7 +195,8 @@ module.exports = (function() {
if (primaryKeyDeleted) { if (primaryKeyDeleted) {
targetAttribute.primaryKey = sourceAttribute.primaryKey = true targetAttribute.primaryKey = sourceAttribute.primaryKey = true
} else {
} else {
var uniqueKey = [this.through.tableName, this.identifier, this.foreignIdentifier, 'unique'].join('_') var uniqueKey = [this.through.tableName, this.identifier, this.foreignIdentifier, 'unique'].join('_')
targetAttribute.unique = sourceAttribute.unique = uniqueKey targetAttribute.unique = sourceAttribute.unique = uniqueKey
} }
......
...@@ -126,7 +126,7 @@ module.exports = (function() { ...@@ -126,7 +126,7 @@ module.exports = (function() {
this._timestampAttributes.createdAt = Utils._.underscoredIf(this.options.createdAt, this.options.underscored) this._timestampAttributes.createdAt = Utils._.underscoredIf(this.options.createdAt, this.options.underscored)
} }
if (this.options.updatedAt) { if (this.options.updatedAt) {
this._timestampAttributes.updatedAt = Utils._.underscoredIf(this.options.updatedAt, this.options.underscored) this._timestampAttributes.updatedAt = Utils._.underscoredIf(this.options.updatedAt, this.options.underscored)
} }
if (this.options.paranoid && this.options.deletedAt) { if (this.options.paranoid && this.options.deletedAt) {
this._timestampAttributes.deletedAt = Utils._.underscoredIf(this.options.deletedAt, this.options.underscored) this._timestampAttributes.deletedAt = Utils._.underscoredIf(this.options.deletedAt, this.options.underscored)
...@@ -598,7 +598,7 @@ module.exports = (function() { ...@@ -598,7 +598,7 @@ module.exports = (function() {
DAOFactory.prototype.count = function(options) { DAOFactory.prototype.count = function(options) {
options = Utils._.clone(options || {}) options = Utils._.clone(options || {})
return new Utils.CustomEventEmitter(function (emitter) { return new Utils.CustomEventEmitter(function (emitter) {
var col = this.sequelize.col('*') var col = this.sequelize.col('*')
if (options.include) { if (options.include) {
...@@ -1332,13 +1332,24 @@ module.exports = (function() { ...@@ -1332,13 +1332,24 @@ module.exports = (function() {
} }
if (this._timestampAttributes.createdAt) { if (this._timestampAttributes.createdAt) {
tail[this._timestampAttributes.createdAt] = {type: DataTypes.DATE, allowNull: false} tail[this._timestampAttributes.createdAt] = {
type: DataTypes.DATE,
allowNull: false,
_autoGenerated: true,
}
} }
if (this._timestampAttributes.updatedAt) { if (this._timestampAttributes.updatedAt) {
tail[this._timestampAttributes.updatedAt] = {type: DataTypes.DATE, allowNull: false} tail[this._timestampAttributes.updatedAt] = {
type: DataTypes.DATE,
allowNull: false,
_autoGenerated: true,
}
} }
if (this._timestampAttributes.deletedAt) { if (this._timestampAttributes.deletedAt) {
tail[this._timestampAttributes.deletedAt] = {type: DataTypes.DATE} tail[this._timestampAttributes.deletedAt] = {
type: DataTypes.DATE,
_autoGenerated: true,
}
} }
var existingAttributes = Utils._.clone(self.rawAttributes) var existingAttributes = Utils._.clone(self.rawAttributes)
......
...@@ -11,7 +11,7 @@ var error = module.exports = {} ...@@ -11,7 +11,7 @@ var error = module.exports = {}
* @constructor * @constructor
*/ */
error.BaseError = function() { error.BaseError = function() {
Error.call(this) Error.apply(this, arguments)
}; };
util.inherits(error.BaseError, Error) util.inherits(error.BaseError, Error)
...@@ -22,6 +22,6 @@ util.inherits(error.BaseError, Error) ...@@ -22,6 +22,6 @@ util.inherits(error.BaseError, Error)
* @constructor * @constructor
*/ */
error.ValidationError = function() { error.ValidationError = function() {
error.BaseError.call(this) error.BaseError.apply(this, arguments)
}; };
util.inherits(error.ValidationError, error.BaseError) util.inherits(error.ValidationError, error.BaseError)
...@@ -627,7 +627,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -627,7 +627,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
username: DataTypes.STRING username: DataTypes.STRING
}).schema('acme', '_') }).schema('acme', '_')
, AcmeProject = self.sequelize.define('Project', { , AcmeProject = self.sequelize.define('Project', {
title: DataTypes.STRING, title: DataTypes.STRING,
active: DataTypes.BOOLEAN active: DataTypes.BOOLEAN
}).schema('acme', '_') }).schema('acme', '_')
, AcmeProjectUsers = self.sequelize.define('ProjectUsers', { , AcmeProjectUsers = self.sequelize.define('ProjectUsers', {
...@@ -835,7 +835,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -835,7 +835,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
this.Task.hasMany(this.User) this.Task.hasMany(this.User)
this.sequelize.sync({force: true}).success(function() { this.sequelize.sync({force: true}).success(function() {
done() done()
}) })
}) })
...@@ -938,7 +938,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -938,7 +938,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
describe('primary key handling for join table', function () { describe('primary key handling for join table', function () {
beforeEach(function (done) { beforeEach(function (done) {
var self = this var self = this
...@@ -966,7 +966,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -966,7 +966,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
it('keeps the primary key if it was added by the user', function () { it('keeps the primary key if it was added by the user', function () {
var self = this var self = this
, fk , fk
this.UserTasks = this.sequelize.define('usertasks', { this.UserTasks = this.sequelize.define('usertasks', {
id: { id: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
...@@ -980,14 +980,14 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -980,14 +980,14 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
autoincrement: true, autoincrement: true,
primaryKey: true primaryKey: true
} }
}); });
this.User.hasMany(this.Task, { through: this.UserTasks }) this.User.hasMany(this.Task, { through: this.UserTasks })
this.Task.hasMany(this.User, { through: this.UserTasks }) this.Task.hasMany(this.User, { through: this.UserTasks })
this.User.hasMany(this.Task, { through: this.UserTasks2 }) this.User.hasMany(this.Task, { through: this.UserTasks2 })
this.Task.hasMany(this.User, { through: this.UserTasks2 }) this.Task.hasMany(this.User, { through: this.UserTasks2 })
expect(Object.keys(self.UserTasks.primaryKeys)).to.deep.equal(['id']) expect(Object.keys(self.UserTasks.primaryKeys)).to.deep.equal(['id'])
expect(Object.keys(self.UserTasks2.primaryKeys)).to.deep.equal(['userTasksId']) expect(Object.keys(self.UserTasks2.primaryKeys)).to.deep.equal(['userTasksId'])
...@@ -997,7 +997,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -997,7 +997,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
}) })
}) })
}) })
describe('through', function () { describe('through', function () {
beforeEach(function (done) { beforeEach(function (done) {
this.User = this.sequelize.define('User', {}) this.User = this.sequelize.define('User', {})
......
...@@ -376,32 +376,42 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -376,32 +376,42 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
UserNull.create({ username: 'foo2', smth: null }).error(function(err) { UserNull.create({ username: 'foo2', smth: null }).error(function(err) {
expect(err).to.exist expect(err).to.exist
expect(err.smth[0].path).to.equal('smth');
if (Support.dialectIsMySQL()) { if (Support.dialectIsMySQL()) {
// We need to allow two different errors for MySQL, see: // We need to allow two different errors for MySQL, see:
// http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_trans_tables // http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_trans_tables
expect(err.message).to.match(/(Column 'smth' cannot be null|Field 'smth' doesn't have a default value)/) expect(err.smth[0].message).to.match(/notNull Violation/)
} }
else if (dialect === "sqlite") { else if (dialect === "sqlite") {
expect(err.message).to.match(/.*SQLITE_CONSTRAINT.*/) expect(err.smth[0].message).to.match(/notNull Violation/)
} else { } else {
expect(err.message).to.match(/.*column "smth" violates not-null.*/) expect(err.smth[0].message).to.match(/notNull Violation/)
} }
done()
})
})
})
it("raises an error if created object breaks definition contraints", function(done) {
var UserNull = this.sequelize.define('UserWithNonNullSmth', {
username: { type: Sequelize.STRING, unique: true },
smth: { type: Sequelize.STRING, allowNull: false }
})
UserNull.create({ username: 'foo', smth: 'foo' }).success(function() { this.sequelize.options.omitNull = false
UserNull.create({ username: 'foo', smth: 'bar' }).error(function(err) {
expect(err).to.exist
if (dialect === "sqlite") {
expect(err.message).to.match(/.*SQLITE_CONSTRAINT.*/)
}
else if (Support.dialectIsMySQL()) {
expect(err.message).to.match(/Duplicate entry 'foo' for key 'username'/)
} else {
expect(err.message).to.match(/.*duplicate key value violates unique constraint.*/)
}
done() UserNull.sync({ force: true }).success(function() {
}) UserNull.create({ username: 'foo', smth: 'foo' }).success(function() {
UserNull.create({ username: 'foo', smth: 'bar' }).error(function(err) {
expect(err).to.exist
if (dialect === "sqlite") {
expect(err.message).to.match(/.*SQLITE_CONSTRAINT.*/)
}
else if (Support.dialectIsMySQL()) {
expect(err.message).to.match(/Duplicate entry 'foo' for key 'username'/)
} else {
expect(err.message).to.match(/.*duplicate key value violates unique constraint.*/)
}
done()
}) })
}) })
}) })
...@@ -417,18 +427,16 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -417,18 +427,16 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
StringIsNullOrUrl.sync({ force: true }).success(function() { StringIsNullOrUrl.sync({ force: true }).success(function() {
StringIsNullOrUrl.create({ str: null }).success(function(str1) { StringIsNullOrUrl.create({ str: null }).success(function(str1) {
expect(str1.str).to.be.null expect(str1.str).to.be.null
StringIsNullOrUrl.create({ str: 'http://sequelizejs.org' }).success(function(str2) { StringIsNullOrUrl.create({ str: 'http://sequelizejs.org' }).success(function(str2) {
expect(str2.str).to.equal('http://sequelizejs.org') expect(str2.str).to.equal('http://sequelizejs.org')
StringIsNullOrUrl.create({ str: '' }).error(function(err) { StringIsNullOrUrl.create({ str: '' }).error(function(err) {
expect(err).to.exist expect(err).to.exist
expect(err.str[0]).to.match(/Validation isURL failed/) expect(err.str[0].message).to.match(/Validation isURL failed/)
done() done()
}) })
}) })
}) }).error(done)
}) })
}) })
...@@ -944,9 +952,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -944,9 +952,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
var Tasks = this.sequelize.define('Task', { var Tasks = this.sequelize.define('Task', {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
validate: { allowNull: false,
notNull: { args: true, msg: 'name cannot be null' }
}
}, },
code: { code: {
type: Sequelize.STRING, type: Sequelize.STRING,
...@@ -961,15 +967,15 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -961,15 +967,15 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
{name: 'foo', code: '123'}, {name: 'foo', code: '123'},
{code: '1234'}, {code: '1234'},
{name: 'bar', code: '1'} {name: 'bar', code: '1'}
], { validate: true }).error(function(errors) { ], { validate: true }).error(function(errors) {
expect(errors).to.not.be.null expect(errors).to.not.be.null
expect(errors).to.be.instanceof(Array) expect(errors).to.be.an('Array')
expect(errors).to.have.length(2) expect(errors).to.have.length(2)
expect(errors[0].record.code).to.equal('1234') expect(errors[0].record.code).to.equal('1234')
expect(errors[0].errors.name[0]).to.equal('name cannot be null') expect(errors[0].errors.name[0].message).to.equal('notNull Violation')
expect(errors[1].record.name).to.equal('bar') expect(errors[1].record.name).to.equal('bar')
expect(errors[1].record.code).to.equal('1') expect(errors[1].record.code).to.equal('1')
expect(errors[1].errors.code[0]).to.equal('Validation len failed') expect(errors[1].errors.code[0].message).to.equal('Validation len failed')
done() done()
}) })
}) })
...@@ -980,8 +986,8 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -980,8 +986,8 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
validate: { validate: {
notNull: { args: true, msg: 'name cannot be null' } notEmpty: true,
} },
}, },
code: { code: {
type: Sequelize.STRING, type: Sequelize.STRING,
......
...@@ -57,7 +57,9 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -57,7 +57,9 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
expect(u2.username).to.equal(bio) expect(u2.username).to.equal(bio)
done() done()
}) })
}) }).error(function(err) {
done(err);
});
}) })
}) })
...@@ -853,7 +855,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -853,7 +855,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
expect(err).to.be.instanceof(Object) expect(err).to.be.instanceof(Object)
expect(err.validateTest).to.be.instanceof(Array) expect(err.validateTest).to.be.instanceof(Array)
expect(err.validateTest[0]).to.exist expect(err.validateTest[0]).to.exist
expect(err.validateTest[0]).to.equal('Validation isInt failed') expect(err.validateTest[0].message).to.equal('Validation isInt failed')
done() done()
}) })
}) })
...@@ -866,7 +868,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -866,7 +868,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
expect(err.validateCustom).to.exist expect(err.validateCustom).to.exist
expect(err.validateCustom).to.be.instanceof(Array) expect(err.validateCustom).to.be.instanceof(Array)
expect(err.validateCustom[0]).to.exist expect(err.validateCustom[0]).to.exist
expect(err.validateCustom[0]).to.equal('Length failed.') expect(err.validateCustom[0].message).to.equal('Length failed.')
done() done()
}) })
}) })
...@@ -879,7 +881,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -879,7 +881,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
expect(err.validateTest).to.exist expect(err.validateTest).to.exist
expect(err.validateTest).to.be.instanceof(Array) expect(err.validateTest).to.be.instanceof(Array)
expect(err.validateTest[0]).to.exist expect(err.validateTest[0]).to.exist
expect(err.validateTest[0]).to.equal('Validation isInt failed') expect(err.validateTest[0].message).to.equal('Validation isInt failed')
done() done()
}) })
}) })
...@@ -1050,6 +1052,44 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -1050,6 +1052,44 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
}) })
}) })
}) })
describe('many to many relations', function() {
var udo;
beforeEach(function(done) {
var self = this
this.User = this.sequelize.define('UserWithUsernameAndAgeAndIsAdmin', {
username: DataTypes.STRING,
age: DataTypes.INTEGER,
isAdmin: DataTypes.BOOLEAN
}, {timestamps: false})
this.Project = this.sequelize.define('NiceProject',
{ title: DataTypes.STRING }, {timestamps: false})
this.Project.hasMany(this.User)
this.User.hasMany(this.Project)
this.User.sync({ force: true }).success(function() {
self.Project.sync({ force: true }).success(function() {
self.User.create({ username: 'fnord', age: 1, isAdmin: true })
.success(function(user) {
udo = user
done()
})
})
})
})
it.skip('Should assign a property to the instance', function(done) {
// @thanpolas rethink this test, it doesn't make sense, a relation has
// to be created first in the beforeEach().
var self = this;
this.User.find({id: udo.id})
.success(function(user) {
user.NiceProjectId = 1;
expect(user.NiceProjectId).to.equal(1);
done();
})
})
})
describe('toJSON', function() { describe('toJSON', function() {
beforeEach(function(done) { beforeEach(function(done) {
......
...@@ -68,10 +68,6 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -68,10 +68,6 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
fail: "a", fail: "a",
pass: "9.2" pass: "9.2"
} }
, notNull : {
fail: null,
pass: 0
}
, isNull : { , isNull : {
fail: 0, fail: 0,
pass: null pass: null
...@@ -201,8 +197,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -201,8 +197,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
failingUser.validate().done( function(err, _errors) { failingUser.validate().done( function(err, _errors) {
expect(_errors).to.not.be.null expect(_errors).to.not.be.null
expect(_errors).to.be.an.instanceOf(Error); expect(_errors).to.be.an.instanceOf(Error)
expect(_errors.name).to.deep.eql([message]) expect(_errors.name[0].message).to.equal(message)
done() done()
}) })
}) })
...@@ -231,7 +227,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -231,7 +227,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
expect(arguments).to.have.length(0) expect(arguments).to.have.length(0)
done() done()
}).error(function(err) { }).error(function(err) {
expect(err).to.be.deep.equal({}) expect(err).to.deep.equal({})
done() done()
}) })
}) })
...@@ -250,7 +246,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -250,7 +246,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
for (var i = 0; i < validatorDetails.fail.length; i++) { for (var i = 0; i < validatorDetails.fail.length; i++) {
applyFailTest(validatorDetails, i, validator); applyFailTest(validatorDetails, i, validator);
} }
for (var j = 0; j < validatorDetails.pass.length; j++) { for (var j = 0; j < validatorDetails.pass.length; j++) {
applyPassTest(validatorDetails, j, validator); applyPassTest(validatorDetails, j, validator);
} }
...@@ -291,8 +287,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -291,8 +287,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var Model = this.sequelize.define('model', { var Model = this.sequelize.define('model', {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: false,
validate: { validate: {
notNull: true, // won't allow null
notEmpty: true // don't allow empty strings notEmpty: true // don't allow empty strings
} }
} }
...@@ -301,8 +297,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -301,8 +297,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
Model.sync({ force: true }).success(function() { Model.sync({ force: true }).success(function() {
Model.create({name: 'World'}).success(function(model) { Model.create({name: 'World'}).success(function(model) {
model.updateAttributes({name: ''}).error(function(err) { model.updateAttributes({name: ''}).error(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.name).to.deep.equal(['Validation notEmpty failed']); expect(err.name[0].message).to.equal('Validation notEmpty failed');
done() done()
}) })
}) })
...@@ -313,18 +309,18 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -313,18 +309,18 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var Model = this.sequelize.define('model', { var Model = this.sequelize.define('model', {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: false,
validate: { validate: {
notNull: true, // won't allow null
notEmpty: true // don't allow empty strings notEmpty: true // don't allow empty strings
} }
} }
}) })
Model.sync({ force: true }).success(function() { Model.sync({ force: true }).success(function() {
Model.create({name: 'World'}).success(function(model) { Model.create({name: 'World'}).success(function() {
Model.update({name: ''}, {id: 1}).error(function(err) { Model.update({name: ''}, {id: 1}).error(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.name).to.deep.equal(['Validation notEmpty failed']); expect(err.name[0].message).to.equal('Validation notEmpty failed')
done() done()
}) })
}) })
...@@ -400,8 +396,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -400,8 +396,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({id: 'helloworld'}).error(function(err) { User.create({id: 'helloworld'}).error(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.id).to.deep.equal(['Validation isInt failed']); expect(err.id[0].message).to.equal('Validation isInt failed')
done() done()
}) })
}) })
...@@ -421,8 +417,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -421,8 +417,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({username: 'helloworldhelloworld'}).error(function(err) { User.create({username: 'helloworldhelloworld'}).error(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.username).to.deep.equal(['Username must be an integer!']); expect(err.username[0].message).to.equal('Username must be an integer!')
done() done()
}) })
}) })
...@@ -448,8 +444,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -448,8 +444,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
it('should emit an error when we try to enter in a string for the id key with validation arguments', function(done) { it('should emit an error when we try to enter in a string for the id key with validation arguments', function(done) {
this.User.create({id: 'helloworld'}).error(function(err) { this.User.create({id: 'helloworld'}).error(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.id).to.deep.equal(['ID must be an integer!']); expect(err.id[0].message).to.equal('ID must be an integer!')
done() done()
}) })
}) })
...@@ -458,8 +454,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -458,8 +454,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var user = this.User.build({id: 'helloworld'}) var user = this.User.build({id: 'helloworld'})
user.validate().success(function(err) { user.validate().success(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.id).to.deep.equal(['ID must be an integer!']); expect(err.id[0].message).to.equal('ID must be an integer!')
done() done()
}) })
}) })
...@@ -467,13 +463,59 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -467,13 +463,59 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
it('should emit an error when we try to .save()', function(done) { it('should emit an error when we try to .save()', function(done) {
var user = this.User.build({id: 'helloworld'}) var user = this.User.build({id: 'helloworld'})
user.save().error(function(err) { user.save().error(function(err) {
expect(err).to.be.instanceOf(Error) expect(err).to.be.an.instanceOf(Error)
expect(err.id).to.deep.equal(['ID must be an integer!']); expect(err.id[0].message).to.equal('ID must be an integer!')
done() done()
}) })
}) })
}) })
}) })
describe('Pass all paths when validating', function() {
beforeEach(function(done) {
var self = this
var Project = this.sequelize.define('Project', {
name: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isIn: [['unknown', 'hello', 'test']]
}
},
creatorName: {
type: Sequelize.STRING,
allowNull: false,
},
cost: {
type: Sequelize.INTEGER,
allowNull: false,
},
})
var Task = this.sequelize.define('Task', {
something: Sequelize.INTEGER
})
Project.hasOne(Task)
Task.belongsTo(Project)
Project.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
self.Project = Project
self.Task = Task
done()
})
})
})
it('produce 3 errors', function(done) {
this.Project.create({}).error(function(err) {
expect(err).to.be.an.instanceOf(Error)
expect(Object.keys(err)).to.have.length(3)
done()
})
})
})
}) })
it('correctly validates using custom validation methods', function(done) { it('correctly validates using custom validation methods', function(done) {
...@@ -495,15 +537,16 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -495,15 +537,16 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var failingUser = User.build({ name : "3" }) var failingUser = User.build({ name : "3" })
failingUser.validate().success(function(error) { failingUser.validate().success(function(error) {
expect(error).to.be.instanceOf(Error); expect(error).to.be.an.instanceOf(Error)
expect(error.name).to.deep.equal(["name should equal '2'"])
expect(error.name[0].message).to.equal("name should equal '2'")
var successfulUser = User.build({ name : "2" }) var successfulUser = User.build({ name : "2" })
successfulUser.validate().success(function() { successfulUser.validate().success(function() {
expect(arguments).to.have.length(0) expect(arguments).to.have.length(0)
done() done()
}).error(function(err) { }).error(function(err) {
expect(err).to.deep.equal({}) expect(err[0].message).to.equal()
done() done()
}) })
}) })
...@@ -525,8 +568,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -525,8 +568,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
.validate() .validate()
.success(function(error) { .success(function(error) {
expect(error).not.to.be.null expect(error).not.to.be.null
expect(error).to.be.instanceOf(Error); expect(error).to.be.an.instanceOf(Error)
expect(error.age).to.deep.equal(["must be positive"]) expect(error.age[0].message).to.equal("must be positive")
User.build({ age: null }).validate().success(function() { User.build({ age: null }).validate().success(function() {
User.build({ age: 1 }).validate().success(function() { User.build({ age: 1 }).validate().success(function() {
...@@ -563,9 +606,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -563,9 +606,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
.validate() .validate()
.success(function(error) { .success(function(error) {
expect(error).not.to.be.null expect(error).not.to.be.null
expect(error).to.be.instanceOf(Error) expect(error).to.be.an.instanceOf(Error)
expect(error.xnor).to.deep.equal(['xnor failed']); expect(error.xnor[0].message).to.equal('xnor failed');
Foo Foo
.build({ field1: 33, field2: null }) .build({ field1: 33, field2: null })
.validate() .validate()
...@@ -601,8 +643,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -601,8 +643,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
.validate() .validate()
.success(function(error) { .success(function(error) {
expect(error).not.to.be.null expect(error).not.to.be.null
expect(error).to.be.instanceOf(Error) expect(error).to.be.an.instanceOf(Error)
expect(error.xnor).to.deep.equal(['xnor failed']); expect(error.xnor[0].message).to.equal('xnor failed')
Foo Foo
.build({ field1: 33, field2: null }) .build({ field1: 33, field2: null })
...@@ -652,7 +694,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -652,7 +694,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
failingBar.validate().success(function(errors) { failingBar.validate().success(function(errors) {
expect(errors).not.to.be.null expect(errors).not.to.be.null
expect(errors.field).to.have.length(1) expect(errors.field).to.have.length(1)
expect(errors.field[0]).to.equal("Validation isIn failed") expect(errors.field[0].message).to.equal("Validation isIn failed")
}) })
}) })
......
...@@ -464,7 +464,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -464,7 +464,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('should return an error based on user', function(done) { it('should return an error based on user', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ]) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
...@@ -501,7 +501,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -501,7 +501,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('should return an error based on the hook', function(done) { it('should return an error based on the hook', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ]) expect(err.mood[0].message).to.equal( 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' )
done() done()
}) })
}) })
...@@ -552,7 +552,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -552,7 +552,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('should return an error based on user', function(done) { it('should return an error based on user', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ]) expect(err.mood[0].message).to.equal( 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' )
done() done()
}) })
}) })
...@@ -601,7 +601,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -601,7 +601,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('should return an error based on the hook', function(done) { it('should return an error based on the hook', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ]) expect(err.mood[0].message).to.equal( 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' )
done() done()
}) })
}) })
...@@ -698,7 +698,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -698,7 +698,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('should return the user from the callback', function(done) { it('should return the user from the callback', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ]) expect(err.mood[0].message).to.equal( 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' )
done() done()
}) })
}) })
...@@ -720,7 +720,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -720,7 +720,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('should return the error without the user within callback', function(done) { it('should return the error without the user within callback', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ]) expect(err.mood[0].message).to.equal( 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' )
done() done()
}) })
}) })
...@@ -835,7 +835,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -835,7 +835,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) { it('#create', function(done) {
this.User.create({mood: 'creative'}).error(function(err) { this.User.create({mood: 'creative'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] ) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
...@@ -859,7 +859,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -859,7 +859,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) { it('#create', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] ) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
...@@ -940,7 +940,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -940,7 +940,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] ) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
...@@ -954,7 +954,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -954,7 +954,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] ) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
...@@ -1061,7 +1061,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -1061,7 +1061,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) { it('#create', function(done) {
this.User.create({mood: 'creative'}).error(function(err) { this.User.create({mood: 'creative'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] ) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
...@@ -1085,7 +1085,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () { ...@@ -1085,7 +1085,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) { it('#create', function(done) {
this.User.create({mood: 'happy'}).error(function(err) { this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] ) expect(err.mood[0].message).to.equal('Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral')
done() done()
}) })
}) })
......
...@@ -124,11 +124,11 @@ if (Support.dialectIsMySQL()) { ...@@ -124,11 +124,11 @@ if (Support.dialectIsMySQL()) {
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({mood: 'happy'}).error(function(err) { User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "happy" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver' ]) expect(err.mood[0].message).to.equal('Value "happy" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver')
var u = User.build({mood: 'SAD'}) var u = User.build({mood: 'SAD'})
u.save().error(function(err) { u.save().error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "SAD" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver' ]) expect(err.mood[0].message).to.equal('Value "SAD" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver')
done() done()
}) })
}) })
......
...@@ -277,7 +277,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -277,7 +277,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(err).to.be.an("object") expect(err).to.be.an("object")
expect(err.validateTest).to.be.an("array") expect(err.validateTest).to.be.an("array")
expect(err.validateTest[0]).to.be.ok expect(err.validateTest[0]).to.be.ok
expect(err.validateTest[0]).to.equal('Validation isInt failed') expect(err.validateTest[0].message).to.equal('Validation isInt failed')
done() done()
}); });
}) })
...@@ -290,7 +290,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -290,7 +290,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(err.validateCustom).to.be.ok expect(err.validateCustom).to.be.ok
expect(err.validateCustom).to.be.an("array") expect(err.validateCustom).to.be.an("array")
expect(err.validateCustom[0]).to.be.ok expect(err.validateCustom[0]).to.be.ok
expect(err.validateCustom[0]).to.equal('Length failed.') expect(err.validateCustom[0].message).to.equal('Length failed.')
done() done()
}) })
}) })
...@@ -304,7 +304,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -304,7 +304,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(err.validateTest).to.be.ok expect(err.validateTest).to.be.ok
expect(err.validateTest).to.be.an("array") expect(err.validateTest).to.be.an("array")
expect(err.validateTest[0]).to.be.ok expect(err.validateTest[0]).to.be.ok
expect(err.validateTest[0]).to.equal('Validation isInt failed') expect(err.validateTest[0].message).to.equal('Validation isInt failed')
done() done()
}) })
}) })
...@@ -322,7 +322,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -322,7 +322,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(user.id).to.equal(1) expect(user.id).to.equal(1)
expect(arguments.length).to.equal(1) expect(arguments.length).to.equal(1)
done() done()
}) })
}) })
describe('with spread', function () { describe('with spread', function () {
...@@ -334,7 +334,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -334,7 +334,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(created).to.equal(false) expect(created).to.equal(false)
expect(arguments.length).to.equal(2) expect(arguments.length).to.equal(2)
done() done()
}) })
}) })
it('user created', function (done) { it('user created', function (done) {
this.User this.User
...@@ -344,7 +344,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -344,7 +344,7 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(created).to.equal(true) expect(created).to.equal(true)
expect(arguments.length).to.equal(2) expect(arguments.length).to.equal(2)
done() done()
}) })
}) })
it('works for functions with only one return value', function (done) { it('works for functions with only one return value', function (done) {
this.User this.User
...@@ -353,8 +353,8 @@ describe(Support.getTestDialectTeaser("Promise"), function () { ...@@ -353,8 +353,8 @@ describe(Support.getTestDialectTeaser("Promise"), function () {
expect(user.id).to.equal(1) expect(user.id).to.equal(1)
expect(arguments.length).to.equal(1) expect(arguments.length).to.equal(1)
done() done()
}) })
}) })
}) })
}) })
}) })
...@@ -86,6 +86,10 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () { ...@@ -86,6 +86,10 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
if (dialect === 'mariadb') { if (dialect === 'mariadb') {
expect(err.message).to.match(/Access denied for user/) expect(err.message).to.match(/Access denied for user/)
} else if (dialect === 'postgres') { } else if (dialect === 'postgres') {
// When the test is run with only it produces:
// Error: Error: Failed to authenticate for PostgresSQL. Please double check your settings.
// When its run with all the other tests it produces:
// Error: invalid port number: "99999"
expect(err.message).to.match(/invalid port number/) expect(err.message).to.match(/invalid port number/)
} else { } else {
expect(err.message).to.match(/Failed to authenticate/) expect(err.message).to.match(/Failed to authenticate/)
...@@ -713,7 +717,7 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () { ...@@ -713,7 +717,7 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
it("doesn't save an instance if value is not in the range of enums", function(done) { it("doesn't save an instance if value is not in the range of enums", function(done) {
this.Review.create({status: 'fnord'}).error(function(err) { this.Review.create({status: 'fnord'}).error(function(err) {
expect(err).to.be.instanceOf(Error); expect(err).to.be.instanceOf(Error);
expect(err.status).to.deep.equal([ 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished' ]) expect(err.status[0].message).to.equal('Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished')
done() done()
}) })
}) })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!