diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee index 1d3c16d8e2..eb5fd43e3c 100644 --- a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee +++ b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsController.coffee @@ -1,4 +1,5 @@ tpdsUpdateHandler = require('./TpdsUpdateHandler') +UpdateMerger = require "./UpdateMerger" logger = require('logger-sharelatex') Path = require('path') metrics = require("../../infrastructure/Metrics") @@ -31,6 +32,24 @@ module.exports = logger.log user_id:user_id, filePath:filePath, projectName:projectName, "telling tpds delete has been processed" res.send 200 req.session.destroy() + + updateProjectContents: (req, res, next = (error) ->) -> + {project_id} = req.params + path = req.params[0] + logger.log project_id: project_id, path: path, "received project contents update" + UpdateMerger.mergeUpdate project_id, path, req, (error) -> + return next(error) if error? + res.send(200) + req.session.destroy() + + deleteProjectContents: (req, res, next = (error) ->) -> + {project_id} = req.params + path = req.params[0] + logger.log project_id: project_id, path: path, "received project contents delete request" + UpdateMerger.deleteUpdate project_id, path, (error) -> + return next(error) if error? + res.send(200) + req.session.destroy() parseParams: parseParams = (req)-> path = req.params[0] diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 8019b6fb80..fb50bbaef6 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -157,6 +157,11 @@ module.exports = class Router app.del '/user/:user_id/update/*', httpAuth, TpdsController.deleteUpdate app.ignoreCsrf('post', '/user/:user_id/update/*') app.ignoreCsrf('delete', '/user/:user_id/update/*') + + app.post '/project/:project_id/contents/*', httpAuth, TpdsController.updateProjectContents + app.del '/project/:project_id/contents/*', httpAuth, TpdsController.deleteProjectContents + app.ignoreCsrf('post', '/project/:project_id/contents/*') + app.ignoreCsrf('delete', '/project/:project_id/contents/*') app.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi app.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi diff --git a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsControllerTests.coffee b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsControllerTests.coffee index e6a3fc6a55..0f7e5a9f71 100644 --- a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsControllerTests.coffee @@ -5,11 +5,12 @@ modulePath = require('path').join __dirname, '../../../../app/js/Features/ThirdP -describe 'third party data store', -> +describe 'TpdsController', -> beforeEach -> - @updateHandler = {} - @controller = SandboxedModule.require modulePath, requires: - './TpdsUpdateHandler':@updateHandler + @TpdsUpdateHandler = {} + @TpdsController = SandboxedModule.require modulePath, requires: + './TpdsUpdateHandler':@TpdsUpdateHandler + './UpdateMerger': @UpdateMerger = {} 'logger-sharelatex': log:-> err:-> @@ -24,11 +25,11 @@ describe 'third party data store', -> params:{0:path, "user_id":@user_id} session: destroy:-> - @updateHandler.newUpdate = sinon.stub().callsArg(5) + @TpdsUpdateHandler.newUpdate = sinon.stub().callsArg(5) res = send: => - @updateHandler.newUpdate.calledWith(@user_id, "projectName","/here.txt", req).should.equal true + @TpdsUpdateHandler.newUpdate.calledWith(@user_id, "projectName","/here.txt", req).should.equal true done() - @controller.mergeUpdate req, res + @TpdsController.mergeUpdate req, res describe 'getting a delete update', -> it 'should process the delete with the update reciver', (done)-> @@ -37,18 +38,18 @@ describe 'third party data store', -> params:{0:path, "user_id":@user_id} session: destroy:-> - @updateHandler.deleteUpdate = sinon.stub().callsArg(4) + @TpdsUpdateHandler.deleteUpdate = sinon.stub().callsArg(4) res = send: => - @updateHandler.deleteUpdate.calledWith(@user_id, "projectName", "/here.txt").should.equal true + @TpdsUpdateHandler.deleteUpdate.calledWith(@user_id, "projectName", "/here.txt").should.equal true done() - @controller.deleteUpdate req, res + @TpdsController.deleteUpdate req, res describe 'parseParams', -> it 'should take the project name off the start and replace with slash', -> path = "noSlashHere" req = params:{0:path, user_id:@user_id} - result = @controller.parseParams(req) + result = @TpdsController.parseParams(req) result.user_id.should.equal @user_id result.filePath.should.equal "/" result.projectName.should.equal path @@ -57,7 +58,7 @@ describe 'third party data store', -> it 'should take the project name off the start and return it with no slashes in', -> path = "/project/file.tex" req = params:{0:path, user_id:@user_id} - result = @controller.parseParams(req) + result = @TpdsController.parseParams(req) result.user_id.should.equal @user_id result.filePath.should.equal "/file.tex" result.projectName.should.equal "project" @@ -65,8 +66,57 @@ describe 'third party data store', -> it 'should take the project name of and return a slash for the file path', -> path = "/project_name" req = params:{0:path, user_id:@user_id} - result = @controller.parseParams(req) + result = @TpdsController.parseParams(req) result.projectName.should.equal "project_name" result.filePath.should.equal "/" + + describe 'updateProjectContents', -> + beforeEach -> + @UpdateMerger.mergeUpdate = sinon.stub().callsArg(3) + @req = + params: + 0: @path = "chapters/main.tex" + project_id: @project_id = "project-id-123" + session: + destroy: sinon.stub() + @res = + send: sinon.stub() + + @TpdsController.updateProjectContents @req, @res + + it "should merge the update", -> + @UpdateMerger.mergeUpdate + .calledWith(@project_id, @path, @req) + .should.equal true + + it "should return a success", -> + @res.send.calledWith(200).should.equal true + it "should clear the session", -> + @req.session.destroy.called.should.equal true + + describe 'deleteProjectContents', -> + beforeEach -> + @UpdateMerger.deleteUpdate = sinon.stub().callsArg(2) + @req = + params: + 0: @path = "chapters/main.tex" + project_id: @project_id = "project-id-123" + session: + destroy: sinon.stub() + @res = + send: sinon.stub() + + @TpdsController.deleteProjectContents @req, @res + + it "should delete the file", -> + @UpdateMerger.deleteUpdate + .calledWith(@project_id, @path) + .should.equal true + + it "should return a success", -> + @res.send.calledWith(200).should.equal true + + it "should clear the session", -> + @req.session.destroy.called.should.equal true