Skip to content

Commit

Permalink
Merge pull request #11293 from noseworthy/add-defaults-for-subdoc-pro…
Browse files Browse the repository at this point in the history
…jections

fix: set default for dotted path projection
  • Loading branch information
vkarpov15 authored Feb 3, 2022
2 parents 2f2d532 + 24e4d80 commit 486e4f7
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ function $__applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSet
break;
}
} else if (exclude === false && fields && !included) {
if (curPath in fields) {
if (curPath in fields || type.$isSingleNested && hasIncludedChildren[curPath]) {
included = true;
} else if (!hasIncludedChildren[curPath]) {
break;
Expand Down
62 changes: 62 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10998,4 +10998,66 @@ describe('document', function() {
assert.equal(typeof doc.somethingElse, 'string');
delete String.type;
});

it('applies subdocument defaults when projecting dotted subdocument fields', async function() {
const grandChildSchema = new mongoose.Schema({
name: {
type: mongoose.Schema.Types.String,
default: () => 'grandchild'
}
});

const childSchema = new mongoose.Schema({
name: {
type: mongoose.Schema.Types.String,
default: () => 'child'
},
grandChild: {
type: grandChildSchema,
default: () => ({})
}
});

const parentSchema = new mongoose.Schema({
name: mongoose.Schema.Types.String,
child: {
type: childSchema,
default: () => ({})
}
});

const ParentModel = db.model('Parent', parentSchema);
// insert an object without mongoose adding missing defaults
const result = await db.collection('Parent').insertOne({ name: 'parent' });

// ensure that the defaults are populated when no projections are used
const doc = await ParentModel.findById(result.insertedId).exec();
assert.equal(doc.name, 'parent');
assert.equal(doc.child.name, 'child');
assert.equal(doc.child.grandChild.name, 'grandchild');

// ensure that defaults are populated when using an object projection
const projectedDoc = await ParentModel.findById(result.insertedId, {
name: 1,
child: {
name: 1,
grandChild: {
name: 1
}
}
}).exec();
assert.equal(projectedDoc.name, 'parent');
assert.equal(projectedDoc.child.name, 'child');
assert.equal(projectedDoc.child.grandChild.name, 'grandchild');

// ensure that defaults are populated when using dotted path projections
const dottedProjectedDoc = await ParentModel.findById(result.insertedId, {
name: 1,
'child.name': 1,
'child.grandChild.name': 1
}).exec();
assert.equal(dottedProjectedDoc.name, 'parent');
assert.equal(dottedProjectedDoc.child.name, 'child');
assert.equal(dottedProjectedDoc.child.grandChild.name, 'grandchild');
});
});

0 comments on commit 486e4f7

Please sign in to comment.