Skip to content

Commit

Permalink
fix(document): correctly handle inclusive/exclusive projections when …
Browse files Browse the repository at this point in the history
…applying subdocument defaults

Fix #13720
  • Loading branch information
vkarpov15 committed Aug 22, 2023
1 parent 0604133 commit 44f3f0d
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
4 changes: 3 additions & 1 deletion lib/schema/SubdocumentPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const geospatial = require('./operators/geospatial');
const getConstructor = require('../helpers/discriminator/getConstructor');
const handleIdOption = require('../helpers/schema/handleIdOption');
const internalToObjectOptions = require('../options').internalToObjectOptions;
const isExclusive = require('../helpers/projection/isExclusive');
const utils = require('../utils');

let Subdocument;
Expand Down Expand Up @@ -173,7 +174,8 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
delete subdoc.$__.defaults;
subdoc.$init(val);
applyDefaults(subdoc, selected);
const exclude = isExclusive(selected);
applyDefaults(subdoc, selected, exclude);
} else {
options = Object.assign({}, options, { priorDoc: priorVal });
if (Object.keys(val).length === 0) {
Expand Down
16 changes: 16 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12296,6 +12296,22 @@ describe('document', function() {
assert.strictEqual(test.polluted, undefined);
assert.strictEqual(Object.prototype.polluted, undefined);
});

it('sets defaults on subdocs with subdoc projection (gh-13720)', async function() {
const subSchema = new mongoose.Schema({
propertyA: { type: String, default: 'A' },
propertyB: { type: String, default: 'B' }
});
const userSchema = new mongoose.Schema({
name: String,
sub: { type: subSchema, default: () => ({}) }
});
const User = db.model('User', userSchema);
await User.insertMany([{ name: 'user' }]);
await User.updateMany({}, { $unset: { 'sub.propertyA': '' } });
const nestedProjectionDoc = await User.findOne({}, { name: 1, 'sub.propertyA': 1, 'sub.propertyB': 1 });
assert.strictEqual(nestedProjectionDoc.sub.propertyA, 'A');
});
});

describe('Check if instance function that is supplied in schema option is availabe', function() {
Expand Down
2 changes: 1 addition & 1 deletion types/augmentations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ declare module 'bson' {
/** Mongoose automatically adds a conveniency "_id" getter on the base ObjectId class */
_id: this;
}
}
}

0 comments on commit 44f3f0d

Please sign in to comment.