Skip to content

Commit

Permalink
fix(document): call pre('validate') hooks when modifying a path under…
Browse files Browse the repository at this point in the history
…neath triply nested subdoc

Fix #13876
  • Loading branch information
vkarpov15 committed Oct 1, 2023
1 parent 2acc3f5 commit 6447b97
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
11 changes: 9 additions & 2 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,13 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
if (last) {
if (obj instanceof Map) {
obj.set(parts[i], val);
} else if (obj.$isSingleNested) {
if (!(parts[i] in obj)) {
obj[parts[i]] = val;
obj._doc[parts[i]] = val;
} else {
obj._doc[parts[i]] = val;
}
} else {
obj[parts[i]] = val;
}
Expand All @@ -1705,7 +1712,7 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
} else if (value && value instanceof Embedded) {
obj = value;
} else if (value && !Array.isArray(value) && value.$isSingleNested) {
obj = value._doc;
obj = value;
} else if (value && Array.isArray(value)) {
obj = value;
} else if (value == null) {
Expand Down Expand Up @@ -2650,7 +2657,7 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
const modifiedPaths = doc.modifiedPaths();
for (const subdoc of subdocs) {
if (subdoc.$basePath) {
const fullPathToSubdoc = subdoc.$__fullPathWithIndexes();
const fullPathToSubdoc = subdoc.$isSingleNested ? subdoc.$__pathRelativeToParent() : subdoc.$__fullPathWithIndexes();

// Remove child paths for now, because we'll be validating the whole
// subdoc.
Expand Down
21 changes: 21 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12212,6 +12212,8 @@ describe('document', function() {

const x = new Test();
x.set('d.x.y', 1);
assert.strictEqual(x.d.x.y, 1);
assert.deepStrictEqual(x.get('d.x'), { y: 1 });
assert.strictEqual(x.get('d.x.y'), 1);
await x.save();

Expand Down Expand Up @@ -12527,6 +12529,25 @@ describe('document', function() {
assert.strictEqual(parent.get('child.concreteProp'), 123);
assert.strictEqual(parent.toObject().child.concreteProp, 123);
});

it('fires pre validate hooks on 4 level single nested subdocs (gh-13876)', async function() {
let attachmentSchemaPreValidateCalls = 0;
const attachmentSchema = new Schema({ name: String });
attachmentSchema.pre('validate', () => { ++attachmentSchemaPreValidateCalls; });

const richImageSchema = new Schema({ attachment: { type: attachmentSchema, required: false } });
const brandingSchema = new Schema({ logo: richImageSchema });
const instanceSchema = new Schema({ branding: brandingSchema });
const TestModel = db.model('Test', instanceSchema);

const instance = await TestModel.create({ branding: { logo: {} } });
assert.strictEqual(attachmentSchemaPreValidateCalls, 0);
const doc = await TestModel.findById(instance._id);

doc.set('branding.logo.attachment', { name: 'coolLogo' });
await doc.save();
assert.strictEqual(attachmentSchemaPreValidateCalls, 1);
});
});

describe('Check if instance function that is supplied in schema option is availabe', function() {
Expand Down
2 changes: 1 addition & 1 deletion test/query.middleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ describe('query middleware', function() {
assert.equal(postCount, 1);
});

it('error handlers XYZ (gh-2284)', async function() {
it('error handlers (gh-2284)', async function() {
const testSchema = new Schema({ title: { type: String, unique: true } });

testSchema.post('updateOne', function(error, res, next) {
Expand Down

0 comments on commit 6447b97

Please sign in to comment.