Skip to content

Commit

Permalink
fix(document): support validators on nested arrays
Browse files Browse the repository at this point in the history
Fix #7926
  • Loading branch information
vkarpov15 committed Jul 24, 2019
1 parent 9d2a224 commit 54a0bb7
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 deletions.
12 changes: 10 additions & 2 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -1988,10 +1988,18 @@ function _getPathsToValidate(doc) {
}

const val = doc.$__getValue(path);
if (val) {
_pushNestedArrayPaths(val, paths, path);
}

function _pushNestedArrayPaths(val, paths, path) {
if (val != null) {
const numElements = val.length;
for (let j = 0; j < numElements; ++j) {
paths.push(path + '.' + j);
if (Array.isArray(val[j])) {
_pushNestedArrayPaths(val[j], paths, path + '.' + j);
} else {
paths.push(path + '.' + j);
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,10 @@ function getPositionalPathType(self, path) {

// ignore if its just a position segment: path.0.subpath
if (!/\D/.test(subpath)) {
// Nested array
if (val instanceof MongooseTypes.Array && i !== last) {
val = val.caster;
}
continue;
}

Expand Down
16 changes: 12 additions & 4 deletions lib/schema/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,19 @@ SchemaArray.prototype.checkRequired = function checkRequired(value, doc) {
*/

SchemaArray.prototype.enum = function() {
const instance = get(this, 'caster.instance');
if (instance !== 'String') {
throw new Error('`enum` can only be set on an array of strings, not ' + instance);
let arr = this; /* eslint consistent-this: 0 */
while (true) { /* eslint no-constant-condition: 0 */
const instance = get(arr, 'caster.instance');
if (instance === 'Array') {
arr = arr.caster;
continue;
}
if (instance !== 'String') {
throw new Error('`enum` can only be set on an array of strings, not ' + instance);
}
break;
}
this.caster.enum.apply(this.caster, arguments);
arr.caster.enum.apply(arr.caster, arguments);
return this;
};

Expand Down
18 changes: 18 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7841,4 +7841,22 @@ describe('document', function() {
assert.ok(doc.testDecimal instanceof mongoose.Types.Decimal128);
});
});

it('allows enum on array of array of strings (gh-7926)', function() {
const schema = new Schema({
test: {
type: [[String]],
enum: ['bar']
}
});

const Model = db.model('gh7926', schema);

return Model.create({ test: [['foo']] }).then(() => assert.ok(false), err => {
assert.ok(err);
assert.ok(err.errors['test.0.0']);
assert.ok(err.errors['test.0.0'].message.indexOf('foo') !== -1,
err.errors['test.0.0'].message);
});
});
});

0 comments on commit 54a0bb7

Please sign in to comment.