Skip to content

Commit

Permalink
feat(model): correctly handle hydrated documents in applyDefaults()
Browse files Browse the repository at this point in the history
Re: #11945
  • Loading branch information
vkarpov15 committed Jul 6, 2022
1 parent ae73d8b commit dd49bc1
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 12 deletions.
20 changes: 11 additions & 9 deletions lib/helpers/document/applyDefaults.js
Expand Up @@ -44,16 +44,18 @@ module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildre
break;
}

if (typeof type.defaultValue === 'function') {
if (!type.defaultValue.$runBeforeSetters && isBeforeSetters) {
break;
}
if (type.defaultValue.$runBeforeSetters && !isBeforeSetters) {
break;
if (isBeforeSetters != null) {
if (typeof type.defaultValue === 'function') {
if (!type.defaultValue.$runBeforeSetters && isBeforeSetters) {
break;
}
if (type.defaultValue.$runBeforeSetters && !isBeforeSetters) {
break;
}
} else if (!isBeforeSetters) {
// Non-function defaults should always run **before** setters
continue;
}
} else if (!isBeforeSetters) {
// Non-function defaults should always run **before** setters
continue;
}

if (pathsToSkip && pathsToSkip[curPath]) {
Expand Down
8 changes: 7 additions & 1 deletion lib/model.js
Expand Up @@ -3695,7 +3695,13 @@ function handleSuccessfulWrite(document, resolve, reject) {

Model.applyDefaults = function applyDefaults(doc) {
if (doc.$__ != null) {
return applyDefaultsHelper(doc, doc.$__.fields, doc.$__.exclude);
applyDefaultsHelper(doc, doc.$__.fields, doc.$__.exclude);

for (const subdoc of doc.$getAllSubdocs()) {
applyDefaults(subdoc, subdoc.$__.fields, subdoc.$__.exclude);
}

return doc;
}

applyDefaultsToPOJO(doc, this.schema);
Expand Down
74 changes: 72 additions & 2 deletions test/model.test.js
Expand Up @@ -8512,6 +8512,10 @@ describe('Model', function() {
type: String,
default: 'John Smith'
},
age: {
type: Number,
default: 29
},
nestedName: {
first: {
type: String,
Expand All @@ -8520,6 +8524,10 @@ describe('Model', function() {
last: {
type: String,
default: 'Smith'
},
middle: {
type: String,
default: ''
}
},
subdoc: {
Expand All @@ -8541,12 +8549,74 @@ describe('Model', function() {
}]
}));

const obj = { docArr: [{}] };
const obj = { age: 31, nestedName: { middle: 'James' }, docArr: [{}] };
Test.applyDefaults(obj);

assert.deepStrictEqual(obj, {
name: 'John Smith',
nestedName: { first: 'John', last: 'Smith' },
age: 31,
nestedName: { first: 'John', last: 'Smith', middle: 'James' },
subdoc: {
test: 'subdoc default'
},
docArr: [{
test: 'doc array default'
}]
});
});

it('applies defaults to documents', function() {
const Test = db.model('Test', mongoose.Schema({
_id: false,
name: {
type: String,
default: 'John Smith'
},
age: {
type: Number,
default: 29
},
nestedName: {
first: {
type: String,
default: 'John'
},
last: {
type: String,
default: 'Smith'
},
middle: {
type: String,
default: ''
}
},
subdoc: {
type: mongoose.Schema({
_id: false,
test: {
type: String,
default: 'subdoc default'
}
}),
default: () => ({})
},
docArr: [{
_id: false,
test: {
type: String,
default: 'doc array default'
}
}]
}));

const obj = { age: 31, nestedName: { middle: 'James' }, docArr: [{}] };
const doc = new Test(obj, null, { defaults: false });
Test.applyDefaults(doc);

assert.deepStrictEqual(doc.toObject(), {
name: 'John Smith',
age: 31,
nestedName: { first: 'John', last: 'Smith', middle: 'James' },
subdoc: {
test: 'subdoc default'
},
Expand Down

0 comments on commit dd49bc1

Please sign in to comment.