diff --git a/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee b/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee index 9ecff2185e..a30ed7bdef 100644 --- a/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee +++ b/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee @@ -129,7 +129,7 @@ module.exports = DocumentUpdaterHandler = method: "POST" }, project_id, "resync-project-history", callback - updateProjectStructure : (project_id, userId, changes, callback = (error) ->)-> + updateProjectStructure: (project_id, projectHistoryId, userId, changes, callback = (error) ->)-> return callback() if !settings.apis.project_history?.sendProjectStructureOps Project.findOne {_id: project_id}, {version:true}, (err, currentProject) -> @@ -144,7 +144,13 @@ module.exports = DocumentUpdaterHandler = logger.log {project_id}, "updating project structure in doc updater" DocumentUpdaterHandler._makeRequest { path: "/project/#{project_id}" - json: { docUpdates, fileUpdates, userId, version: currentProject.version } + json: { + docUpdates, + fileUpdates, + userId, + version: currentProject.version + projectHistoryId + } method: "POST" }, project_id, "update-project-structure", callback diff --git a/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee index e3aea07456..788d1b40eb 100644 --- a/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEntityUpdateHandler.coffee @@ -48,6 +48,7 @@ module.exports = ProjectEntityUpdateHandler = self = # this doesn't need any locking because it's only called by ProjectDuplicator copyFileFromExistingProjectWithProject: (project, folder_id, originalProject_id, origonalFileRef, userId, callback = (error, fileRef, folder_id) ->)-> project_id = project._id + projectHistoryId = project.overleaf?.history?.id logger.log { project_id, folder_id, originalProject_id, origonalFileRef }, "copying file in s3 with project" return callback(err) if err? ProjectEntityMongoUpdateHandler._confirmFolder project, folder_id, (folder_id)=> @@ -72,7 +73,7 @@ module.exports = ProjectEntityUpdateHandler = self = path: result?.path?.fileSystem url: fileStoreUrl ] - DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newFiles}, (error) -> + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {newFiles}, (error) -> return callback(error) if error? callback null, fileRef, folder_id @@ -131,14 +132,15 @@ module.exports = ProjectEntityUpdateHandler = self = self.addDoc project_id, null, name, lines, callback addDoc: wrapWithLock (project_id, folder_id, docName, docLines, userId, callback = (error, doc, folder_id) ->)=> - self.addDocWithoutUpdatingHistory.withoutLock project_id, folder_id, docName, docLines, userId, (error, doc, folder_id, path) -> + self.addDocWithoutUpdatingHistory.withoutLock project_id, folder_id, docName, docLines, userId, (error, doc, folder_id, path, project) -> return callback(error) if error? + projectHistoryId = project.overleaf?.history?.id newDocs = [ doc: doc path: path docLines: docLines.join('\n') ] - DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newDocs}, (error) -> + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {newDocs}, (error) -> return callback(error) if error? callback null, doc, folder_id @@ -173,12 +175,13 @@ module.exports = ProjectEntityUpdateHandler = self = withLock: (project_id, folder_id, fileName, fsPath, linkedFileData, userId, fileRef, fileStoreUrl, callback = (error, fileRef, folder_id) ->)-> ProjectEntityUpdateHandler._addFileAndSendToTpds project_id, folder_id, fileName, fileRef, (err, result, project) -> return callback(err) if err? + projectHistoryId = project.overleaf?.history?.id newFiles = [ file: fileRef path: result?.path?.fileSystem url: fileStoreUrl ] - DocumentUpdaterHandler.updateProjectStructure project_id, userId, {newFiles}, (error) -> + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {newFiles}, (error) -> return callback(error) if error? callback(null, fileRef, folder_id) @@ -205,9 +208,10 @@ module.exports = ProjectEntityUpdateHandler = self = path: path.fileSystem url: fileStoreUrl ] + projectHistoryId = project.overleaf?.history?.id TpdsUpdateSender.addFile {project_id:project._id, file_id:newFileRef._id, path:path.fileSystem, rev:newFileRef.rev+1, project_name:project.name}, (err) -> return callback(err) if err? - DocumentUpdaterHandler.updateProjectStructure project_id, userId, {oldFiles, newFiles}, callback + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, {oldFiles, newFiles}, callback addDocWithoutUpdatingHistory: wrapWithLock (project_id, folder_id, docName, docLines, userId, callback = (error, doc, folder_id) ->)=> # This method should never be called directly, except when importing a project @@ -232,7 +236,7 @@ module.exports = ProjectEntityUpdateHandler = self = rev: 0 }, (err) -> return callback(err) if err? - callback(null, doc, folder_id, result?.path?.fileSystem) + callback(null, doc, folder_id, result?.path?.fileSystem, project) addFileWithoutUpdatingHistory: wrapWithLock # This method should never be called directly, except when importing a project @@ -363,10 +367,11 @@ module.exports = ProjectEntityUpdateHandler = self = logger.err {err: "No entityType set", project_id, entity_id} return callback("No entityType set") entityType = entityType.toLowerCase() - ProjectEntityMongoUpdateHandler.moveEntity project_id, entity_id, destFolderId, entityType, (err, project_name, startPath, endPath, rev, changes) -> + ProjectEntityMongoUpdateHandler.moveEntity project_id, entity_id, destFolderId, entityType, (err, project, startPath, endPath, rev, changes) -> return callback(err) if err? - TpdsUpdateSender.moveEntity { project_id, project_name, startPath, endPath, rev } - DocumentUpdaterHandler.updateProjectStructure project_id, userId, changes, callback + projectHistoryId = project.overleaf?.history?.id + TpdsUpdateSender.moveEntity { project_id, project_name: project.name, startPath, endPath, rev } + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback renameEntity: wrapWithLock (project_id, entity_id, entityType, newName, userId, callback)-> if not SafePath.isCleanFilename newName @@ -377,10 +382,11 @@ module.exports = ProjectEntityUpdateHandler = self = return callback("No entityType set") entityType = entityType.toLowerCase() - ProjectEntityMongoUpdateHandler.renameEntity project_id, entity_id, entityType, newName, (err, project_name, startPath, endPath, rev, changes) -> + ProjectEntityMongoUpdateHandler.renameEntity project_id, entity_id, entityType, newName, (err, project, startPath, endPath, rev, changes) -> return callback(err) if err? - TpdsUpdateSender.moveEntity({project_id, startPath, endPath, project_name, rev}) - DocumentUpdaterHandler.updateProjectStructure project_id, userId, changes, callback + projectHistoryId = project.overleaf?.history?.id + TpdsUpdateSender.moveEntity { project_id, project_name: project.name, startPath, endPath, rev } + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback # This doesn't directly update project structure but we need to take the lock # to prevent anything else being queued before the resync update @@ -433,16 +439,18 @@ module.exports = ProjectEntityUpdateHandler = self = DocstoreManager.deleteDoc project_id, doc_id, (error) -> return callback(error) if error? changes = oldDocs: [ {doc, path} ] - DocumentUpdaterHandler.updateProjectStructure project_id, userId, changes, callback + projectHistoryId = project.overleaf?.history?.id + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback _cleanUpFile: (project, file, path, userId, callback = (error) ->) -> ProjectEntityMongoUpdateHandler._insertDeletedFileReference project._id, file, (error) -> return callback(error) if error? project_id = project._id.toString() + projectHistoryId = project.overleaf?.history?.id changes = oldFiles: [ {file, path} ] # we are now keeping a copy of every file versio so we no longer delete # the file from the filestore - DocumentUpdaterHandler.updateProjectStructure project_id, userId, changes, callback + DocumentUpdaterHandler.updateProjectStructure project_id, projectHistoryId, userId, changes, callback _cleanUpFolder: (project, folder, folderPath, userId, callback = (error) ->) -> jobs = [] diff --git a/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee b/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee index 47010c2b9d..837a0f5b78 100644 --- a/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee +++ b/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee @@ -12,6 +12,7 @@ modulePath = path.join __dirname, '../../../../app/js/Features/DocumentUpdater/D describe 'DocumentUpdaterHandler', -> beforeEach -> @project_id = "project-id-923" + @projectHistoryId = "ol-project-id-1" @doc_id = "doc-id-394" @lines = ["one", "two", "three"] @version = 42 @@ -409,7 +410,7 @@ describe 'DocumentUpdaterHandler', -> describe "with project history disabled", -> beforeEach -> @settings.apis.project_history.sendProjectStructureOps = false - @handler.updateProjectStructure @project_id, @user_id, {}, @callback + @handler.updateProjectStructure @project_id, @projectHistoryId, @user_id, {}, @callback it 'does not make a web request', -> @request.called.should.equal false @@ -445,11 +446,11 @@ describe 'DocumentUpdaterHandler', -> newPathname: "/new_b" ] - @handler.updateProjectStructure @project_id, @user_id, @changes, () => + @handler.updateProjectStructure @project_id, @projectHistoryId, @user_id, @changes, () => @request.calledWith( url: @url, method: "POST" - json: {docUpdates, fileUpdates: [], userId: @user_id, @version} + json: {docUpdates, fileUpdates: [], userId: @user_id, @version, @projectHistoryId} ) .should.equal true done() @@ -468,11 +469,11 @@ describe 'DocumentUpdaterHandler', -> url: undefined ] - @handler.updateProjectStructure @project_id, @user_id, @changes, () => + @handler.updateProjectStructure @project_id, @projectHistoryId, @user_id, @changes, () => @request.calledWith( url: @url method: "POST" - json: {docUpdates, fileUpdates: [], userId: @user_id, @version} + json: {docUpdates, fileUpdates: [], userId: @user_id, @version, @projectHistoryId} ).should.equal true done() @@ -490,11 +491,11 @@ describe 'DocumentUpdaterHandler', -> docLines: undefined ] - @handler.updateProjectStructure @project_id, @user_id, @changes, () => + @handler.updateProjectStructure @project_id, @projectHistoryId, @user_id, @changes, () => @request.calledWith( url: @url method: "POST" - json: {docUpdates: [], fileUpdates, userId: @user_id, @version} + json: {docUpdates: [], fileUpdates, userId: @user_id, @version, @projectHistoryId} ).should.equal true done() @@ -511,10 +512,10 @@ describe 'DocumentUpdaterHandler', -> newPathname: '' ] - @handler.updateProjectStructure @project_id, @user_id, @changes, () => + @handler.updateProjectStructure @project_id, @projectHistoryId, @user_id, @changes, () => @request.calledWith( url: @url method: "POST" - json: {docUpdates, fileUpdates: [], userId: @user_id, @version} + json: {docUpdates, fileUpdates: [], userId: @user_id, @version, @projectHistoryId} ).should.equal true done() diff --git a/services/web/test/unit/coffee/Project/ProjectEntityMongoUpdateHandlerTests.coffee b/services/web/test/unit/coffee/Project/ProjectEntityMongoUpdateHandlerTests.coffee index 57911bd7d8..a79deb15a9 100644 --- a/services/web/test/unit/coffee/Project/ProjectEntityMongoUpdateHandlerTests.coffee +++ b/services/web/test/unit/coffee/Project/ProjectEntityMongoUpdateHandlerTests.coffee @@ -267,7 +267,7 @@ describe 'ProjectEntityMongoUpdateHandler', -> it "calls the callback", -> changes = { @oldDocs, @newDocs, @oldFiles, @newFiles } @callback.calledWith( - null, @project.name, @path.fileSystem, @pathAfterMove.fileSystem, @doc.rev, changes + null, @project, @path.fileSystem, @pathAfterMove.fileSystem, @doc.rev, changes ).should.equal true describe 'deleteEntity', -> @@ -349,7 +349,7 @@ describe 'ProjectEntityMongoUpdateHandler', -> it 'calls the callback', -> changes = { @oldDocs, @newDocs, @oldFiles, @newFiles } @callback.calledWith( - null, @project.name, '/old.tex', '/new.tex', @doc.rev, changes + null, @project, '/old.tex', '/new.tex', @doc.rev, changes ).should.equal true describe 'addFolder', -> diff --git a/services/web/test/unit/coffee/Project/ProjectEntityUpdateHandlerTests.coffee b/services/web/test/unit/coffee/Project/ProjectEntityUpdateHandlerTests.coffee index 09d0d274fb..d7fe7fc003 100644 --- a/services/web/test/unit/coffee/Project/ProjectEntityUpdateHandlerTests.coffee +++ b/services/web/test/unit/coffee/Project/ProjectEntityUpdateHandlerTests.coffee @@ -10,6 +10,7 @@ ObjectId = require("mongoose").Types.ObjectId describe 'ProjectEntityUpdateHandler', -> project_id = '4eecb1c1bffa66588e0000a1' + projectHistoryId = '123456' doc_id = '4eecb1c1bffa66588e0000a2' file_id = "4eecaffcbffa66588e000009" folder_id = "4eecaffcbffa66588e000008" @@ -18,7 +19,12 @@ describe 'ProjectEntityUpdateHandler', -> userId = 1234 beforeEach -> - @project = _id: project_id, name: 'project name' + @project = + _id: project_id, + name: 'project name' + overleaf: + history: + id: projectHistoryId @fileUrl = 'filestore.example.com/file' @FileStoreHandler = uploadFileFromDisk: sinon.stub().yields(null, @fileUrl) @@ -112,7 +118,7 @@ describe 'ProjectEntityUpdateHandler', -> newFile.url == @fileUrl @DocumentUpdaterHandler.updateProjectStructure - .calledWithMatch(project_id, userId, changesMatcher) + .calledWithMatch(project_id, projectHistoryId, userId, changesMatcher) .should.equal true describe 'updateDocLines', -> @@ -278,7 +284,7 @@ describe 'ProjectEntityUpdateHandler', -> @newDoc = _id: doc_id @ProjectEntityUpdateHandler.addDocWithoutUpdatingHistory = - withoutLock: sinon.stub().yields(null, @newDoc, folder_id, @path) + withoutLock: sinon.stub().yields(null, @newDoc, folder_id, @path, @project) @ProjectEntityUpdateHandler.addDoc project_id, folder_id, @docName, @docLines, userId, @callback it "creates the doc without history", () -> @@ -293,7 +299,7 @@ describe 'ProjectEntityUpdateHandler', -> docLines: @docLines.join('\n') ] @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, {newDocs}) + .calledWith(project_id, projectHistoryId, userId, {newDocs}) .should.equal true describe 'addFile', -> @@ -336,7 +342,7 @@ describe 'ProjectEntityUpdateHandler', -> url: @fileUrl ] @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, {newFiles}) + .calledWith(project_id, projectHistoryId, userId, {newFiles}) .should.equal true describe 'replaceFile', -> @@ -348,7 +354,6 @@ describe 'ProjectEntityUpdateHandler', -> @newFile = _id: new_file_id, name: "dummy-upload-filename", rev: 0 @oldFile = _id: file_id @path = "/path/to/file" - @project = _id: project_id, name: 'some project' @ProjectEntityMongoUpdateHandler._insertDeletedFileReference = sinon.stub().yields() @ProjectEntityMongoUpdateHandler.replaceFileWithNew = sinon.stub().yields(null, @oldFile, @project, fileSystem: @path) @ProjectEntityUpdateHandler.replaceFile project_id, file_id, @fileSystemPath, @linkedFileData, userId, @callback @@ -385,7 +390,7 @@ describe 'ProjectEntityUpdateHandler', -> url: @newFileUrl ] @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, {oldFiles, newFiles}) + .calledWith(project_id, projectHistoryId, userId, {oldFiles, newFiles}) .should.equal true describe 'addDocWithoutUpdatingHistory', -> @@ -725,7 +730,7 @@ describe 'ProjectEntityUpdateHandler', -> @rev = 2 @changes = newDocs: ['old-doc'], newFiles: ['old-file'] @ProjectEntityMongoUpdateHandler.moveEntity = sinon.stub().yields( - null, @project_name, @startPath, @endPath, @rev, @changes + null, @project, @startPath, @endPath, @rev, @changes ) @TpdsUpdateSender.moveEntity = sinon.stub() @DocumentUpdaterHandler.updateProjectStructure = sinon.stub() @@ -744,7 +749,7 @@ describe 'ProjectEntityUpdateHandler', -> it 'sends the changes in project structure to the doc updater', -> @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, @changes, @callback) + .calledWith(project_id, projectHistoryId, userId, @changes, @callback) .should.equal true describe "renameEntity", -> @@ -756,7 +761,7 @@ describe 'ProjectEntityUpdateHandler', -> @changes = newDocs: ['old-doc'], newFiles: ['old-file'] @newDocName = 'b.tex' @ProjectEntityMongoUpdateHandler.renameEntity = sinon.stub().yields( - null, @project_name, @startPath, @endPath, @rev, @changes + null, @project, @startPath, @endPath, @rev, @changes ) @TpdsUpdateSender.moveEntity = sinon.stub() @DocumentUpdaterHandler.updateProjectStructure = sinon.stub() @@ -775,7 +780,7 @@ describe 'ProjectEntityUpdateHandler', -> it 'sends the changes in project structure to the doc updater', -> @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, @changes, @callback) + .calledWith(project_id, projectHistoryId, userId, @changes, @callback) .should.equal true describe "resyncProjectHistory", -> @@ -791,7 +796,7 @@ describe 'ProjectEntityUpdateHandler', -> describe "a project without project-history enabled", -> beforeEach -> - @project.ovreleaf = {} + @project.overleaf = {} @ProjectGetter.getProject = sinon.stub().yields(null, @project) @ProjectEntityUpdateHandler.resyncProjectHistory project_id, @callback @@ -802,7 +807,6 @@ describe 'ProjectEntityUpdateHandler', -> describe "a project with project-history enabled", -> beforeEach -> - @project.overleaf = history: id: 4 @ProjectGetter.getProject = sinon.stub().yields(null, @project) docs = [ doc: _id: doc_id @@ -840,7 +844,7 @@ describe 'ProjectEntityUpdateHandler', -> url: "www.filestore.test/#{project_id}/#{file_id}" ] @DocumentUpdaterHandler.resyncProjectHistory - .calledWith(project_id, docs, files) + .calledWith(project_id, projectHistoryId, docs, files) .should.equal true it 'calls the callback', -> @@ -874,7 +878,7 @@ describe 'ProjectEntityUpdateHandler', -> it "should should send the update to the doc updater", -> oldFiles = [ file: @entity, path: @path ] @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, {oldFiles}) + .calledWith(project_id, projectHistoryId, userId, {oldFiles}) .should.equal true describe "a doc", -> @@ -924,8 +928,6 @@ describe 'ProjectEntityUpdateHandler', -> describe "_cleanUpDoc", -> beforeEach -> - @project = - _id: ObjectId(project_id) @doc = _id: ObjectId() name: "test.tex" @@ -963,7 +965,7 @@ describe 'ProjectEntityUpdateHandler', -> it "should should send the update to the doc updater", -> oldDocs = [ doc: @doc, path: @path ] @DocumentUpdaterHandler.updateProjectStructure - .calledWith(project_id, userId, {oldDocs}) + .calledWith(project_id, projectHistoryId, userId, {oldDocs}) .should.equal true it "should call the callback", ->