Merge pull request #16657 from overleaf/dp-mongoose-callback-project-update-handler

Promisify ProjectUpdateHandler and ProjectUpdateHandlerTests

GitOrigin-RevId: 312cbe71d431cf50932ab7d5501529d87f7827f2
This commit is contained in:
David 2024-02-08 11:14:17 +00:00 committed by Copybot
parent 68f011378d
commit 03bb99aeaa
4 changed files with 92 additions and 146 deletions

View file

@ -204,11 +204,11 @@ const ProjectEntityUpdateHandler = {
return callback(null, { rev }) return callback(null, { rev })
} }
// Don't need to block for marking as updated // Don't need to block for marking as updated
ProjectUpdateHandler.markAsUpdated( ProjectUpdateHandler.promises
projectId, .markAsUpdated(projectId, lastUpdatedAt, lastUpdatedBy)
lastUpdatedAt, .catch(error => {
lastUpdatedBy logger.error({ error }, 'failed to mark project as updated')
) })
TpdsUpdateSender.addDoc( TpdsUpdateSender.addDoc(
{ {
projectId, projectId,
@ -557,7 +557,11 @@ const ProjectEntityUpdateHandler = {
if (error != null) { if (error != null) {
return callback(error) return callback(error)
} }
ProjectUpdateHandler.markAsUpdated(projectId, new Date(), userId) ProjectUpdateHandler.promises
.markAsUpdated(projectId, new Date(), userId)
.catch(error => {
logger.error({ error }, 'failed to mark project as updated')
})
callback(null, fileRef, folderId) callback(null, fileRef, folderId)
} }
) )
@ -616,7 +620,11 @@ const ProjectEntityUpdateHandler = {
if (err != null) { if (err != null) {
return callback(err) return callback(err)
} }
ProjectUpdateHandler.markAsUpdated(projectId, new Date(), userId) ProjectUpdateHandler.promises
.markAsUpdated(projectId, new Date(), userId)
.catch(error => {
logger.error({ error }, 'failed to mark project as updated')
})
DocumentUpdaterHandler.updateProjectStructure( DocumentUpdaterHandler.updateProjectStructure(
projectId, projectId,

View file

@ -1,24 +1,9 @@
/* eslint-disable
n/handle-callback-err,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const { Project } = require('../../models/Project') const { Project } = require('../../models/Project')
const logger = require('@overleaf/logger') const { callbackify } = require('util')
const { promisifyAll } = require('@overleaf/promise-utils')
const ProjectUpdateHandler = { const ProjectUpdateHandler = {
markAsUpdated(projectId, lastUpdatedAt, lastUpdatedBy, callback) { async markAsUpdated(projectId, lastUpdatedAt, lastUpdatedBy) {
if (callback == null) { if (!lastUpdatedAt) {
callback = function () {}
}
if (lastUpdatedAt == null) {
lastUpdatedAt = new Date() lastUpdatedAt = new Date()
} }
@ -31,59 +16,32 @@ const ProjectUpdateHandler = {
lastUpdated: lastUpdatedAt || new Date().getTime(), lastUpdated: lastUpdatedAt || new Date().getTime(),
lastUpdatedBy, lastUpdatedBy,
} }
Project.updateOne(conditions, update, {}, callback) await Project.updateOne(conditions, update, {}).exec()
}, },
// like markAsUpdated but allows lastUpdatedAt to be reset to earlier time async markAsOpened(projectId) {
resetUpdated(projectId, lastUpdatedAt, lastUpdatedBy, callback) {
if (callback == null) {
callback = function () {}
}
if (lastUpdatedAt == null) {
lastUpdatedAt = new Date()
}
const conditions = {
_id: projectId,
}
const update = {
lastUpdated: lastUpdatedAt || new Date().getTime(),
lastUpdatedBy,
}
Project.updateOne(conditions, update, {}, callback)
},
markAsOpened(projectId, callback) {
const conditions = { _id: projectId } const conditions = { _id: projectId }
const update = { lastOpened: Date.now() } const update = { lastOpened: Date.now() }
Project.updateOne(conditions, update, {}, function (err) { await Project.updateOne(conditions, update, {}).exec()
if (callback != null) {
return callback()
}
})
}, },
markAsInactive(projectId, callback) { async markAsInactive(projectId) {
const conditions = { _id: projectId } const conditions = { _id: projectId }
const update = { active: false } const update = { active: false }
Project.updateOne(conditions, update, {}, function (err) { await Project.updateOne(conditions, update, {}).exec()
if (callback != null) {
return callback()
}
})
}, },
markAsActive(projectId, callback) { async markAsActive(projectId) {
const conditions = { _id: projectId } const conditions = { _id: projectId }
const update = { active: true } const update = { active: true }
Project.updateOne(conditions, update, {}, function (err) { await Project.updateOne(conditions, update, {}).exec()
if (callback != null) {
return callback()
}
})
}, },
} }
ProjectUpdateHandler.promises = promisifyAll(ProjectUpdateHandler) module.exports = {
module.exports = ProjectUpdateHandler markAsUpdated: callbackify(ProjectUpdateHandler.markAsUpdated),
markAsOpened: callbackify(ProjectUpdateHandler.markAsOpened),
markAsInactive: callbackify(ProjectUpdateHandler.markAsInactive),
markAsActive: callbackify(ProjectUpdateHandler.markAsActive),
promises: ProjectUpdateHandler,
}

View file

@ -103,7 +103,9 @@ describe('ProjectEntityUpdateHandler', function () {
findElementByPath: sinon.stub(), findElementByPath: sinon.stub(),
} }
this.ProjectUpdater = { this.ProjectUpdater = {
markAsUpdated: sinon.stub(), promises: {
markAsUpdated: sinon.stub().resolves(),
},
} }
this.ProjectEntityHandler = { this.ProjectEntityHandler = {
getDoc: sinon.stub(), getDoc: sinon.stub(),
@ -244,7 +246,7 @@ describe('ProjectEntityUpdateHandler', function () {
it('should mark the project as updated', function () { it('should mark the project as updated', function () {
sinon.assert.calledWith( sinon.assert.calledWith(
this.ProjectUpdater.markAsUpdated, this.ProjectUpdater.promises.markAsUpdated,
projectId, projectId,
this.lastUpdatedAt, this.lastUpdatedAt,
this.lastUpdatedBy this.lastUpdatedBy
@ -283,7 +285,7 @@ describe('ProjectEntityUpdateHandler', function () {
}) })
it('should not mark the project as updated', function () { it('should not mark the project as updated', function () {
this.ProjectUpdater.markAsUpdated.called.should.equal(false) this.ProjectUpdater.promises.markAsUpdated.called.should.equal(false)
}) })
it('should not send the doc the to the TPDS', function () { it('should not send the doc the to the TPDS', function () {
@ -326,7 +328,7 @@ describe('ProjectEntityUpdateHandler', function () {
}) })
it('should not mark the project as updated', function () { it('should not mark the project as updated', function () {
this.ProjectUpdater.markAsUpdated.called.should.equal(false) this.ProjectUpdater.promises.markAsUpdated.called.should.equal(false)
}) })
it('should not send the doc the to the TPDS', function () { it('should not send the doc the to the TPDS', function () {
@ -373,7 +375,7 @@ describe('ProjectEntityUpdateHandler', function () {
}) })
it('should not mark the project as updated', function () { it('should not mark the project as updated', function () {
this.ProjectUpdater.markAsUpdated.called.should.equal(false) this.ProjectUpdater.promises.markAsUpdated.called.should.equal(false)
}) })
it('should not send the doc the to the TPDS', function () { it('should not send the doc the to the TPDS', function () {
@ -658,7 +660,7 @@ describe('ProjectEntityUpdateHandler', function () {
}) })
it('should mark the project as updated', function () { it('should mark the project as updated', function () {
const args = this.ProjectUpdater.markAsUpdated.args[0] const args = this.ProjectUpdater.promises.markAsUpdated.args[0]
args[0].should.equal(projectId) args[0].should.equal(projectId)
args[1].should.exist args[1].should.exist
args[2].should.equal(userId) args[2].should.equal(userId)
@ -1066,7 +1068,7 @@ describe('ProjectEntityUpdateHandler', function () {
}) })
it('should mark the project as updated', function () { it('should mark the project as updated', function () {
const args = this.ProjectUpdater.markAsUpdated.args[0] const args = this.ProjectUpdater.promises.markAsUpdated.args[0]
args[0].should.equal(projectId) args[0].should.equal(projectId)
args[1].should.exist args[1].should.exist
args[2].should.equal(userId) args[2].should.equal(userId)

View file

@ -1,16 +1,3 @@
/* eslint-disable
n/handle-callback-err,
max-len,
no-return-assign,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const sinon = require('sinon') const sinon = require('sinon')
const modulePath = const modulePath =
'../../../../app/src/Features/Project/ProjectUpdateHandler.js' '../../../../app/src/Features/Project/ProjectUpdateHandler.js'
@ -27,98 +14,89 @@ describe('ProjectUpdateHandler', function () {
}) })
beforeEach(function () { beforeEach(function () {
let Project this.ProjectModel = class Project {}
this.ProjectModel = Project = class Project {} this.ProjectModel.updateOne = sinon.stub().returns({
this.ProjectModel.updateOne = sinon.stub().callsArg(3) exec: sinon.stub(),
return (this.handler = SandboxedModule.require(modulePath, { })
this.handler = SandboxedModule.require(modulePath, {
requires: { requires: {
'../../models/Project': { Project: this.ProjectModel }, '../../models/Project': { Project: this.ProjectModel },
}, },
})) })
}) })
describe('marking a project as recently updated', function () { describe('marking a project as recently updated', function () {
beforeEach(function () { beforeEach(function () {
this.project_id = 'project_id' this.project_id = 'project_id'
this.lastUpdatedAt = 987654321 this.lastUpdatedAt = 987654321
return (this.lastUpdatedBy = 'fake-last-updater-id') this.lastUpdatedBy = 'fake-last-updater-id'
}) })
it('should send an update to mongo', function (done) { it('should send an update to mongo', async function () {
return this.handler.markAsUpdated( await this.handler.promises.markAsUpdated(
this.project_id, this.project_id,
this.lastUpdatedAt, this.lastUpdatedAt,
this.lastUpdatedBy, this.lastUpdatedBy
err => { )
sinon.assert.calledWith(
this.ProjectModel.updateOne, sinon.assert.calledWith(
{ this.ProjectModel.updateOne,
_id: this.project_id, {
lastUpdated: { $lt: this.lastUpdatedAt }, _id: this.project_id,
}, lastUpdated: { $lt: this.lastUpdatedAt },
{ },
lastUpdated: this.lastUpdatedAt, {
lastUpdatedBy: this.lastUpdatedBy, lastUpdated: this.lastUpdatedAt,
} lastUpdatedBy: this.lastUpdatedBy,
)
return done()
} }
) )
}) })
it('should set smart fallbacks', function (done) { it('should set smart fallbacks', async function () {
return this.handler.markAsUpdated(this.project_id, null, null, err => { await this.handler.promises.markAsUpdated(this.project_id, null, null)
sinon.assert.calledWithMatch( sinon.assert.calledWithMatch(
this.ProjectModel.updateOne, this.ProjectModel.updateOne,
{ {
_id: this.project_id, _id: this.project_id,
lastUpdated: { $lt: this.fakeTime }, lastUpdated: { $lt: this.fakeTime },
}, },
{ {
lastUpdated: this.fakeTime, lastUpdated: this.fakeTime,
lastUpdatedBy: null, lastUpdatedBy: null,
} }
) )
return done()
})
}) })
}) })
describe('markAsOpened', function () { describe('markAsOpened', function () {
it('should send an update to mongo', function (done) { it('should send an update to mongo', async function () {
const projectId = 'project_id' const projectId = 'project_id'
return this.handler.markAsOpened(projectId, err => { await this.handler.promises.markAsOpened(projectId)
const args = this.ProjectModel.updateOne.args[0] const args = this.ProjectModel.updateOne.args[0]
args[0]._id.should.equal(projectId) args[0]._id.should.equal(projectId)
const date = args[1].lastOpened + '' const date = args[1].lastOpened + ''
const now = Date.now() + '' const now = Date.now() + ''
date.substring(0, 5).should.equal(now.substring(0, 5)) date.substring(0, 5).should.equal(now.substring(0, 5))
return done()
})
}) })
}) })
describe('markAsInactive', function () { describe('markAsInactive', function () {
it('should send an update to mongo', function (done) { it('should send an update to mongo', async function () {
const projectId = 'project_id' const projectId = 'project_id'
return this.handler.markAsInactive(projectId, err => { await this.handler.promises.markAsInactive(projectId)
const args = this.ProjectModel.updateOne.args[0] const args = this.ProjectModel.updateOne.args[0]
args[0]._id.should.equal(projectId) args[0]._id.should.equal(projectId)
args[1].active.should.equal(false) args[1].active.should.equal(false)
return done()
})
}) })
}) })
describe('markAsActive', function () { describe('markAsActive', function () {
it('should send an update to mongo', function (done) { it('should send an update to mongo', async function () {
const projectId = 'project_id' const projectId = 'project_id'
return this.handler.markAsActive(projectId, err => { await this.handler.promises.markAsActive(projectId)
const args = this.ProjectModel.updateOne.args[0] const args = this.ProjectModel.updateOne.args[0]
args[0]._id.should.equal(projectId) args[0]._id.should.equal(projectId)
args[1].active.should.equal(true) args[1].active.should.equal(true)
return done()
})
}) })
}) })
}) })