Skip to content

Commit

Permalink
fix: correctly apply defaults after subdoc init
Browse files Browse the repository at this point in the history
Fix #12328
  • Loading branch information
vkarpov15 committed Sep 14, 2022
1 parent b46848d commit 47ce125
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
2 changes: 2 additions & 0 deletions lib/schema/SubdocumentPath.js
Expand Up @@ -9,6 +9,7 @@ const EventEmitter = require('events').EventEmitter;
const ObjectExpectedError = require('../error/objectExpected');
const SchemaSubdocumentOptions = require('../options/SchemaSubdocumentOptions');
const SchemaType = require('../schematype');
const applyDefaults = require('../helpers/document/applyDefaults');
const $exists = require('./operators/exists');
const castToNumber = require('./operators/helpers').castToNumber;
const discriminator = require('../helpers/model/discriminator');
Expand Down Expand Up @@ -172,6 +173,7 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
if (init) {
subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
subdoc.$init(val);
applyDefaults(subdoc, selected);
} else {
if (Object.keys(val).length === 0) {
return new Constructor({}, selected, doc, undefined, options);
Expand Down
15 changes: 12 additions & 3 deletions test/document.test.js
Expand Up @@ -11835,11 +11835,17 @@ describe('document', function() {
});

it('correct context for default functions in subdocuments with init (gh-12328)', async function() {
let called = 0;

const subSchema = new mongoose.Schema({
propertyA: { type: String },
propertyB: { type: String, default: function() {
return this.propertyA;
} }
propertyB: {
type: String,
default: function() {
++called;
return this.propertyA;
}
}
});

const testSchema = new mongoose.Schema(
Expand All @@ -11852,8 +11858,11 @@ describe('document', function() {
const Test = db.model('Test', testSchema);

await Test.collection.insertOne({ name: 'test', sub: { propertyA: 'foo' } });
assert.strictEqual(called, 0);

const doc = await Test.findOne({ name: 'test' });
assert.strictEqual(doc.sub.propertyB, 'foo');
assert.strictEqual(called, 1);
});
});

Expand Down

0 comments on commit 47ce125

Please sign in to comment.