diff --git a/lib/helpers/update/applyTimestampsToChildren.js b/lib/helpers/update/applyTimestampsToChildren.js index 67f1b0c38f6..5b8e7deb5b4 100644 --- a/lib/helpers/update/applyTimestampsToChildren.js +++ b/lib/helpers/update/applyTimestampsToChildren.js @@ -82,12 +82,15 @@ function applyTimestampsToChildren(now, update, schema) { function applyTimestampsToDocumentArray(arr, schematype, now) { const timestamps = schematype.schema.options.timestamps; + const len = arr.length; + if (!timestamps) { + for (let i = 0; i < len; ++i) { + applyTimestampsToChildren(now, arr[i], schematype.schema); + } return; } - const len = arr.length; - const createdAt = handleTimestampOption(timestamps, 'createdAt'); const updatedAt = handleTimestampOption(timestamps, 'updatedAt'); for (let i = 0; i < len; ++i) { @@ -105,6 +108,7 @@ function applyTimestampsToDocumentArray(arr, schematype, now) { function applyTimestampsToSingleNested(subdoc, schematype, now) { const timestamps = schematype.schema.options.timestamps; if (!timestamps) { + applyTimestampsToChildren(now, subdoc, schematype.schema); return; } diff --git a/test/timestamps.test.js b/test/timestamps.test.js index ec39fd39731..fdb60a0707e 100644 --- a/test/timestamps.test.js +++ b/test/timestamps.test.js @@ -964,6 +964,37 @@ describe('timestamps', function() { assert.ok(updatedParent.child.created instanceof Date); assert.strictEqual(updatedParent.child.created.valueOf(), date.valueOf()); }); + + it('sets timestamps on sub-schema if parent schema does not have timestamps: true (gh-12119)', async function() { + // `timestamps` option set to true on deepest sub document + const ConditionSchema = new mongoose.Schema({ + kind: String, + amount: Number + }, { timestamps: true }); + + // no `timestamps` option defined + const ProfileSchema = new mongoose.Schema({ + conditions: [ConditionSchema] + }); + + const UserSchema = new mongoose.Schema({ + name: String, + profile: { + type: ProfileSchema + } + }, { timestamps: true }); + + const User = db.model('User', UserSchema); + + const res = await User.findOneAndUpdate( + { name: 'test' }, + { $set: { profile: { conditions: [{ kind: 'price', amount: 10 }] } } }, + { upsert: true, returnDocument: 'after' } + ); + + assert.ok(res.profile.conditions[0].createdAt); + assert.ok(res.profile.conditions[0].updatedAt); + }); }); async function delay(ms) {