From 14112d69157cc94d40af851374d9c4299e278f3f Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 22 Mar 2023 11:15:27 -0400 Subject: [PATCH] fix(timestamps): set timestamps on empty `replaceOne()` Re: #9951 Re: #13170 --- lib/helpers/timestamps/setupTimestamps.js | 7 ++++++- test/timestamps.test.js | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/helpers/timestamps/setupTimestamps.js b/lib/helpers/timestamps/setupTimestamps.js index ed44e7d938c..ae3c29459b2 100644 --- a/lib/helpers/timestamps/setupTimestamps.js +++ b/lib/helpers/timestamps/setupTimestamps.js @@ -7,6 +7,11 @@ const handleTimestampOption = require('../schema/handleTimestampOption'); const setDocumentTimestamps = require('./setDocumentTimestamps'); const symbols = require('../../schema/symbols'); +const replaceOps = new Set([ + 'replaceOne', + 'findOneAndReplace' +]); + module.exports = function setupTimestamps(schema, timestamps) { const childHasTimestamp = schema.childSchemas.find(withTimestamp); function withTimestamp(s) { @@ -90,7 +95,7 @@ module.exports = function setupTimestamps(schema, timestamps) { currentTime() : this.model.base.now(); // Replacing with null update should still trigger timestamps - if (this.op === 'findOneAndReplace' && this.getUpdate() == null) { + if (replaceOps.has(this.op) && this.getUpdate() == null) { this.setUpdate({}); } applyTimestampsToUpdate(now, createdAt, updatedAt, this.getUpdate(), diff --git a/test/timestamps.test.js b/test/timestamps.test.js index 07b91201bcc..c00f6c04112 100644 --- a/test/timestamps.test.js +++ b/test/timestamps.test.js @@ -548,6 +548,19 @@ describe('timestamps', function() { assert.ok(doc.createdAt.getTime() === doc.updatedAt.getTime()); }); + it('sets timestamps on replaceOne (gh-9951)', async function() { + await Cat.deleteMany({}); + const { _id } = await Cat.create({ name: 'notexistname' }); + await Cat.replaceOne({ name: 'notexistname' }, {}); + const docs = await Cat.find({}); + assert.equal(docs.length, 1); + const [doc] = docs; + assert.equal(doc._id.toHexString(), _id.toHexString()); + assert.ok(doc.createdAt); + assert.ok(doc.updatedAt); + assert.ok(doc.createdAt.getTime() === doc.updatedAt.getTime()); + }); + it('should change updatedAt when save', async function() { const doc = await Cat.findOne({ name: 'newcat' }); const old = doc.updatedAt;