From 1e80548bdf2ccf846e4c473602e47bf9f3535db9 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Tue, 11 Nov 2014 16:00:48 +0000 Subject: [PATCH 1/3] Experimental work for running validators on array elements --- lib/document.js | 10 ++++++++++ test/schema.validation.test.js | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/document.js b/lib/document.js index 6370aa55b65..33061ff9416 100644 --- a/lib/document.js +++ b/lib/document.js @@ -975,6 +975,16 @@ Document.prototype.validate = function (cb) { var validating = {} , total = 0; + for (var i = 0; i < paths.length; ++i) { + var path = paths[i]; + var val = self.getValue(path); + if (val instanceof Array && !Buffer.isBuffer(val)) { + for (var i = 0; i < val.length; ++i) { + paths.push(path + '.' + i); + } + } + } + paths.forEach(validatePath); return promise; diff --git a/test/schema.validation.test.js b/test/schema.validation.test.js index bdef5151d49..4d4252e42c3 100644 --- a/test/schema.validation.test.js +++ b/test/schema.validation.test.js @@ -652,5 +652,26 @@ describe('schema', function(){ }); }); }); + + it('should allow an array of enums (gh-661)', function(done) { + var validBreakfastFoods = ['bacon', 'eggs', 'steak', 'coffee', 'butter']; + var breakfastSchema = new Schema({ + foods: [{ type: String, enum: validBreakfastFoods }] + }); + var Breakfast = mongoose.model('gh-661', breakfastSchema, 'gh-661'); + + var goodBreakfast = new Breakfast({ foods: ['eggs', 'bacon'] }); + goodBreakfast.validate(function(error) { + assert.ifError(error); + + var badBreakfast = new Breakfast({ foods: ['tofu', 'waffles', 'coffee'] }); + //badBreakfast.markModified('foods.0'); + badBreakfast.validate(function(error) { + assert.ok(error); + + done(); + }); + }); + }); }); }); From bd9d373f1b20b07e2e78f8c9d202a6b7f8c07358 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 26 Nov 2014 09:54:12 -0500 Subject: [PATCH 2/3] Fix #661 --- lib/document.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/document.js b/lib/document.js index 7073cbfa5a7..d528ed40c91 100644 --- a/lib/document.js +++ b/lib/document.js @@ -975,16 +975,18 @@ Document.prototype.validate = function (cb) { var validating = {} , total = 0; + // gh-661: if a whole array is modified, make sure to run validation on all + // the children as well for (var i = 0; i < paths.length; ++i) { var path = paths[i]; var val = self.getValue(path); if (val instanceof Array && !Buffer.isBuffer(val)) { - for (var i = 0; i < val.length; ++i) { - paths.push(path + '.' + i); + var numElements = val.length; + for (var j = 0; j < numElements; ++j) { + paths.push(path + '.' + j); } } } - paths.forEach(validatePath); return promise; From 9e240b84bdf43fbdd2e481bc39bfd6d63b30311a Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 26 Nov 2014 09:58:51 -0500 Subject: [PATCH 3/3] More robust assertions for #661 --- test/schema.validation.test.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/schema.validation.test.js b/test/schema.validation.test.js index 3e29d94ef9d..b894017f598 100644 --- a/test/schema.validation.test.js +++ b/test/schema.validation.test.js @@ -707,9 +707,15 @@ describe('schema', function(){ assert.ifError(error); var badBreakfast = new Breakfast({ foods: ['tofu', 'waffles', 'coffee'] }); - //badBreakfast.markModified('foods.0'); badBreakfast.validate(function(error) { assert.ok(error); + assert.ok(error.errors['foods.0']); + assert.equal(error.errors['foods.0'].message, + '`tofu` is not a valid enum value for path `foods`.'); + assert.ok(error.errors['foods.1']); + assert.equal(error.errors['foods.1'].message, + '`waffles` is not a valid enum value for path `foods`.'); + assert.ok(!error.errors['foods.2']); done(); });