From 75f5fbcdbfa31dff651517dc53dc98f3d5faa360 Mon Sep 17 00:00:00 2001 From: Hayden Faulds Date: Fri, 9 Mar 2018 10:23:48 +0000 Subject: [PATCH] refactor DocumentUpdaterHandler --- .../DocumentUpdaterHandler.coffee | 229 ++++++------------ .../DocumentUpdaterHandlerTests.coffee | 177 ++++++++------ 2 files changed, 170 insertions(+), 236 deletions(-) diff --git a/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee b/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee index 966996a364..c9e51484f9 100644 --- a/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee +++ b/services/web/app/coffee/Features/DocumentUpdater/DocumentUpdaterHandler.coffee @@ -5,26 +5,15 @@ _ = require 'underscore' async = require 'async' logger = require('logger-sharelatex') metrics = require('metrics-sharelatex') -FileStoreHandler = require("../FileStore/FileStoreHandler") Project = require("../../models/Project").Project -ProjectGetter = require "../Project/ProjectGetter" module.exports = DocumentUpdaterHandler = flushProjectToMongo: (project_id, callback = (error) ->)-> logger.log project_id:project_id, "flushing project from document updater" - timer = new metrics.Timer("flushing.mongo.project") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/flush" - request.post url, (error, res, body)-> - if error? - logger.error err: error, project_id: project_id, "error flushing project from document updater" - return callback(error) - else if res.statusCode >= 200 and res.statusCode < 300 - logger.log project_id: project_id, "flushed project from document updater" - return callback(null) - else - error = new Error("document updater returned a failure status code: #{res.statusCode}") - logger.error err: error, project_id: project_id, "document updater returned failure status code: #{res.statusCode}" - return callback(error) + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/flush" + method: "POST" + }, project_id, "flushing.mongo.project", callback flushMultipleProjectsToMongo: (project_ids, callback = (error) ->) -> jobs = [] @@ -35,94 +24,46 @@ module.exports = DocumentUpdaterHandler = async.series jobs, callback flushProjectToMongoAndDelete: (project_id, callback = ()->) -> - logger.log project_id:project_id, "deleting project from document updater" timer = new metrics.Timer("delete.mongo.project") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}" - request.del url, (error, res, body)-> - if error? - logger.error err: error, project_id: project_id, "error deleting project from document updater" - return callback(error) - else if res.statusCode >= 200 and res.statusCode < 300 - logger.log project_id: project_id, "deleted project from document updater" - return callback(null) - else - error = new Error("document updater returned a failure status code: #{res.statusCode}") - logger.error err: error, project_id: project_id, "document updater returned failure status code: #{res.statusCode}" - return callback(error) + url = "#{settings.apis.documentupdater.url}" + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}" + method: "DELETE" + }, project_id, "flushing.mongo.project", callback flushDocToMongo: (project_id, doc_id, callback = (error) ->) -> logger.log project_id:project_id, doc_id: doc_id, "flushing doc from document updater" - timer = new metrics.Timer("flushing.mongo.doc") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}/flush" - request.post url, (error, res, body)-> - if error? - logger.error err: error, project_id: project_id, doc_id: doc_id, "error flushing doc from document updater" - return callback(error) - else if res.statusCode >= 200 and res.statusCode < 300 - logger.log project_id: project_id, doc_id: doc_id, "flushed doc from document updater" - return callback(null) - else - error = new Error("document updater returned a failure status code: #{res.statusCode}") - logger.error err: error, project_id: project_id, doc_id: doc_id, "document updater returned failure status code: #{res.statusCode}" - return callback(error) - + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/doc/#{doc_id}/flush" + method: "POST" + }, project_id, "flushing.mongo.doc", callback + deleteDoc : (project_id, doc_id, callback = ()->)-> logger.log project_id:project_id, doc_id: doc_id, "deleting doc from document updater" - timer = new metrics.Timer("delete.mongo.doc") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}" - request.del url, (error, res, body)-> - if error? - logger.error err: error, project_id: project_id, doc_id: doc_id, "error deleting doc from document updater" - return callback(error) - else if res.statusCode >= 200 and res.statusCode < 300 - logger.log project_id: project_id, doc_id: doc_id, "deleted doc from document updater" - return callback(null) - else - error = new Error("document updater returned a failure status code: #{res.statusCode}") - logger.error err: error, project_id: project_id, doc_id: doc_id, "document updater returned failure status code: #{res.statusCode}" - return callback(error) + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/doc/#{doc_id}" + method: "DELETE" + }, project_id, "delete.mongo.doc", callback getDocument: (project_id, doc_id, fromVersion, callback = (error, doclines, version, ranges, ops) ->) -> - timer = new metrics.Timer("get-document") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}?fromVersion=#{fromVersion}" logger.log project_id:project_id, doc_id: doc_id, "getting doc from document updater" - request.get url, (error, res, body)-> - timer.done() - if error? - logger.error err:error, url:url, project_id:project_id, doc_id:doc_id, "error getting doc from doc updater" - return callback(error) - if res.statusCode >= 200 and res.statusCode < 300 - logger.log project_id:project_id, doc_id:doc_id, "got doc from document document updater" - try - body = JSON.parse(body) - catch error - return callback(error) - callback null, body.lines, body.version, body.ranges, body.ops - else - logger.error project_id:project_id, doc_id:doc_id, url: url, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/doc/#{doc_id}?fromVersion=#{fromVersion}" + json: true + }, project_id, "get-document", (error, doc) -> + return callback(error) if error? + callback null, doc.lines, doc.version, doc.ranges, doc.ops setDocument : (project_id, doc_id, user_id, docLines, source, callback = (error) ->)-> - timer = new metrics.Timer("set-document") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}" - body = - url: url + logger.log project_id:project_id, doc_id: doc_id, source: source, user_id: user_id, "setting doc in document updater" + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/doc/#{doc_id}" + method: "POST" json: lines: docLines source: source user_id: user_id - logger.log project_id:project_id, doc_id: doc_id, source: source, user_id: user_id, "setting doc in document updater" - request.post body, (error, res, body)-> - timer.done() - if error? - logger.error err:error, url:url, project_id:project_id, doc_id:doc_id, "error setting doc in doc updater" - return callback(error) - if res.statusCode >= 200 and res.statusCode < 300 - logger.log project_id: project_id, doc_id: doc_id, "set doc in document updater" - return callback(null) - else - logger.error project_id:project_id, doc_id:doc_id, url: url, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + }, project_id, "set-document", callback getProjectDocsIfMatch: (project_id, projectStateHash, callback = (error, docs) ->) -> # If the project state hasn't changed, we can get all the latest @@ -155,74 +96,42 @@ module.exports = DocumentUpdaterHandler = callback new Error("doc updater returned a non-success status code: #{res.statusCode}") clearProjectState: (project_id, callback = (error) ->) -> - timer = new metrics.Timer("clear-project-state") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/clearState" logger.log project_id:project_id, "clearing project state from document updater" - request.post url, (error, res)-> - timer.done() - if error? - logger.error err:error, url:url, project_id:project_id, "error clearing project state from doc updater" - return callback(error) - else if res.statusCode is 200 - logger.log project_id:project_id, "cleared project state from doc updater" - callback() - else - logger.error project_id:project_id, url: url, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/clearState" + method: "POST" + }, project_id, "clear-project-state", callback acceptChanges: (project_id, doc_id, change_ids = [], callback = (error) ->) -> - timer = new metrics.Timer("accept-changes") - reqSettings = - url: "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}/change/accept" + logger.log {project_id, doc_id }, "accepting #{ change_ids.length } changes" + + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/doc/#{doc_id}/change/accept" json: change_ids: change_ids - logger.log {project_id, doc_id }, "accepting #{ change_ids.length } changes" - request.post reqSettings, (error, res, body)-> - timer.done() - if error? - logger.error {err:error, project_id, doc_id }, "error accepting #{ change_ids.length } changes in doc updater" - return callback(error) - if res.statusCode >= 200 and res.statusCode < 300 - logger.log {project_id, doc_id }, "accepted #{ change_ids.length } changes in document updater" - return callback(null) - else - logger.error {project_id, doc_id }, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + method: "POST" + }, project_id, "accept-changes", callback deleteThread: (project_id, doc_id, thread_id, callback = (error) ->) -> timer = new metrics.Timer("delete-thread") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}/comment/#{thread_id}" logger.log {project_id, doc_id, thread_id}, "deleting comment range in document updater" - request.del url, (error, res, body)-> - timer.done() - if error? - logger.error {err:error, project_id, doc_id, thread_id}, "error deleting comment range in doc updater" - return callback(error) - if res.statusCode >= 200 and res.statusCode < 300 - logger.log {project_id, doc_id, thread_id}, "deleted comment rangee in document updater" - return callback(null) - else - logger.error {project_id, doc_id, thread_id}, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/doc/#{doc_id}/comment/#{thread_id}" + method: "DELETE" + }, project_id, "delete-thread", callback resyncProjectHistory: (project_id, docs, files, callback) -> logger.info {project_id}, "resyncing project in doc updater" - request.post - url: "#{settings.apis.documentupdater.url}/project/#{project_id}/history/resync" + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}/history/resync" json: { docs, files } - , (error, res, body) -> - if error? - logger.error {error, project_id}, "error resyncing project in doc updater" - callback(error) - else if res.statusCode >= 200 and res.statusCode < 300 - logger.log {project_id}, "resynced project in doc updater" - callback() - else - logger.error {project_id, doc_id}, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + method: "POST" + }, project_id, "resync-project-history", callback updateProjectStructure : (project_id, userId, changes, callback = (error) ->)-> return callback() if !settings.apis.project_history?.sendProjectStructureOps + Project.findOne {_id: project_id}, {version:true}, (err, currentProject) -> return callback(err) if err? return callback new Error("project not found") if !currentProject? @@ -230,25 +139,31 @@ module.exports = DocumentUpdaterHandler = docUpdates = DocumentUpdaterHandler._getUpdates('doc', changes.oldDocs, changes.newDocs) fileUpdates = DocumentUpdaterHandler._getUpdates('file', changes.oldFiles, changes.newFiles) - timer = new metrics.Timer("set-document") - url = "#{settings.apis.documentupdater.url}/project/#{project_id}" - body = - url: url - json: { docUpdates, fileUpdates, userId, version: currentProject.version } - return callback() if (docUpdates.length + fileUpdates.length) < 1 - request.post body, (error, res, body)-> - timer.done() - if error? - logger.error {error, url, project_id}, "error update project structure in doc updater" - callback(error) - else if res.statusCode >= 200 and res.statusCode < 300 - logger.log {project_id}, "updated project structure in doc updater" - callback(null) - else - logger.error {project_id, url}, "doc updater returned a non-success status code: #{res.statusCode}" - callback new Error("doc updater returned a non-success status code: #{res.statusCode}") + DocumentUpdaterHandler._makeRequest { + path: "/project/#{project_id}" + json: { docUpdates, fileUpdates, userId, version: currentProject.version } + method: "POST" + }, project_id, "update-project-structure", callback + + _makeRequest: (options, project_id, metricsKey, callback) -> + timer = new metrics.Timer(metricsKey) + request { + url: "#{settings.apis.documentupdater.url}#{options.path}" + json: options.json + method: options.method || "GET" + }, (error, res, body)-> + timer.done() + if error? + logger.error {error, project_id}, "error making request to document updater" + callback error + else if res.statusCode >= 200 and res.statusCode < 300 + callback null, body + else + error = new Error("document updater returned a failure status code: #{res.statusCode}") + logger.error {error, project_id}, "document updater returned failure status code: #{res.statusCode}" + callback error _getUpdates: (entityType, oldEntities, newEntities) -> oldEntities ||= [] diff --git a/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee b/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee index 8db9ed4830..47010c2b9d 100644 --- a/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee +++ b/services/web/test/unit/coffee/DocumentUpdater/DocumentUpdaterHandlerTests.coffee @@ -19,7 +19,7 @@ describe 'DocumentUpdaterHandler', -> @project = _id: @project_id - @request = {} + @request = sinon.stub() @projectEntityHandler = {} @settings = apis: @@ -43,19 +43,21 @@ describe 'DocumentUpdaterHandler', -> describe 'flushProjectToMongo', -> describe "successfully", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "") + @request.callsArgWith(1, null, {statusCode: 204}, "") @handler.flushProjectToMongo @project_id, @callback it 'should flush the document from the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/flush" - @request.post.calledWith(url).should.equal true + @request.calledWithMatch( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/flush" + method: "POST" + ).should.equal true it "should call the callback with no error", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.flushProjectToMongo @project_id, @callback it "should return an error to the callback", -> @@ -63,7 +65,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.flushProjectToMongo @project_id, @callback it "should return the callback with an error", -> @@ -74,19 +76,21 @@ describe 'DocumentUpdaterHandler', -> describe 'flushProjectToMongoAndDelete', -> describe "successfully", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "") + @request.callsArgWith(1, null, {statusCode: 204}, "") @handler.flushProjectToMongoAndDelete @project_id, @callback it 'should delete the project from the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}" - @request.del.calledWith(url).should.equal true + @request.calledWithMatch( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}" + method: "DELETE" + ).should.equal true it "should call the callback with no error", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.flushProjectToMongoAndDelete @project_id, @callback it "should return an error to the callback", -> @@ -94,7 +98,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.flushProjectToMongoAndDelete @project_id, @callback it "should return the callback with an error", -> @@ -105,19 +109,21 @@ describe 'DocumentUpdaterHandler', -> describe 'flushDocToMongo', -> describe "successfully", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "") + @request.callsArgWith(1, null, {statusCode: 204}, "") @handler.flushDocToMongo @project_id, @doc_id, @callback it 'should flush the document from the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}/flush" - @request.post.calledWith(url).should.equal true + @request.calledWithMatch( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}/flush" + method: "POST" + ).should.equal true it "should call the callback with no error", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.flushDocToMongo @project_id, @doc_id, @callback it "should return an error to the callback", -> @@ -125,7 +131,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.flushDocToMongo @project_id, @doc_id, @callback it "should return the callback with an error", -> @@ -136,19 +142,21 @@ describe 'DocumentUpdaterHandler', -> describe "deleteDoc", -> describe "successfully", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "") + @request.callsArgWith(1, null, {statusCode: 204}, "") @handler.deleteDoc @project_id, @doc_id, @callback it 'should delete the document from the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}" - @request.del.calledWith(url).should.equal true + @request.calledWithMatch( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}" + method: "DELETE" + ).should.equal true it "should call the callback with no error", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.deleteDoc @project_id, @doc_id, @callback it "should return an error to the callback", -> @@ -156,7 +164,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.deleteDoc @project_id, @doc_id, @callback it "should return the callback with an error", -> @@ -170,27 +178,25 @@ describe 'DocumentUpdaterHandler', -> describe "successfully", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "") + @request.callsArgWith(1, null, {statusCode: 204}, "") @handler.setDocument @project_id, @doc_id, @user_id, @lines, @source, @callback it 'should set the document in the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}" - @request.post - .calledWith({ - url: url - json: - lines: @lines - source: @source - user_id: @user_id - }) - .should.equal true + @request.calledWith( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}" + json: + lines: @lines + source: @source + user_id: @user_id + method: "POST" + ).should.equal true it "should call the callback with no error", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.setDocument @project_id, @doc_id, @user_id, @lines, @source, @callback it "should return an error to the callback", -> @@ -198,7 +204,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.setDocument @project_id, @doc_id, @user_id, @lines, @source, @callback it "should return the callback with an error", -> @@ -209,25 +215,28 @@ describe 'DocumentUpdaterHandler', -> describe "getDocument", -> describe "successfully", -> beforeEach -> - @body = JSON.stringify + @body = lines: @lines version: @version ops: @ops = ["mock-op-1", "mock-op-2"] ranges: @ranges = {"mock":"ranges"} @fromVersion = 2 - @request.get = sinon.stub().callsArgWith(1, null, {statusCode: 200}, @body) + @request.callsArgWith(1, null, {statusCode: 200}, @body) @handler.getDocument @project_id, @doc_id, @fromVersion, @callback it 'should get the document from the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}?fromVersion=#{@fromVersion}" - @request.get.calledWith(url).should.equal true + @request.calledWith( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}?fromVersion=#{@fromVersion}" + method: "GET" + json: true + ).should.equal true it "should call the callback with the lines and version", -> @callback.calledWith(null, @lines, @version, @ranges, @ops).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.get = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.getDocument @project_id, @doc_id, @fromVersion, @callback it "should return an error to the callback", -> @@ -235,7 +244,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.get = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.getDocument @project_id, @doc_id, @fromVersion, @callback it "should return the callback with an error", -> @@ -258,7 +267,7 @@ describe 'DocumentUpdaterHandler', -> @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 200}, @body) @handler.getProjectDocsIfMatch @project_id, @project_state_hash, @callback - it 'should get the documenst from the document updater', -> + it 'should get the documents from the document updater', -> url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/get_and_flush_if_old?state=#{@project_state_hash}" @request.post.calledWith(url).should.equal true @@ -283,36 +292,37 @@ describe 'DocumentUpdaterHandler', -> .alwaysCalledWithExactly() .should.equal true - describe "clearProjectState", -> describe "successfully", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 200}) + @request.callsArgWith(1, null, {statusCode: 200}) @handler.clearProjectState @project_id, @callback it 'should clear the project state from the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/clearState" - @request.post.calledWith(url).should.equal true + @request.calledWithMatch( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/clearState" + method: "POST" + ).should.equal true it "should call the callback", -> - @callback.calledWithExactly().should.equal true + @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) - @handler.getProjectDocsIfMatch @project_id, @project_state_hash, @callback + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) + @handler.clearProjectState @project_id, @callback it "should return an error to the callback", -> @callback.calledWith(@error).should.equal true - describe "when the document updater returns a conflict error code", -> + describe "when the document updater returns an error code", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, { statusCode: 409 }, "Conflict") - @handler.getProjectDocsIfMatch @project_id, @project_state_hash, @callback + @request.callsArgWith(1, null, { statusCode: 500 }, null) + @handler.clearProjectState @project_id, @callback it "should return the callback with no documents", -> @callback - .alwaysCalledWithExactly() + .calledWith(new Error("doc updater returned failure status code: 500")) .should.equal true @@ -322,22 +332,23 @@ describe 'DocumentUpdaterHandler', -> describe "successfully", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 200}, @body) + @request.callsArgWith(1, null, {statusCode: 200}, @body) @handler.acceptChanges @project_id, @doc_id, [ @change_id ], @callback it 'should accept the change in the document updater', -> - req = + @request.calledWith( url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}/change/accept" json: change_ids: [ @change_id ] - @request.post.calledWith(req).should.equal true + method: "POST" + ).should.equal true it "should call the callback", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.acceptChanges @project_id, @doc_id, [ @change_id ], @callback it "should return an error to the callback", -> @@ -345,7 +356,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.post = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.acceptChanges @project_id, @doc_id, [ @change_id ], @callback it "should return the callback with an error", -> @@ -359,19 +370,21 @@ describe 'DocumentUpdaterHandler', -> describe "successfully", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, {statusCode: 200}, @body) + @request.callsArgWith(1, null, {statusCode: 200}, @body) @handler.deleteThread @project_id, @doc_id, @thread_id, @callback it 'should delete the thread in the document updater', -> - url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}/comment/#{@thread_id}" - @request.del.calledWith(url).should.equal true + @request.calledWithMatch( + url: "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}/comment/#{@thread_id}" + method: "DELETE" + ).should.equal true it "should call the callback", -> @callback.calledWith(null).should.equal true describe "when the document updater API returns an error", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null) + @request.callsArgWith(1, @error = new Error("something went wrong"), null, null) @handler.deleteThread @project_id, @doc_id, @thread_id, @callback it "should return an error to the callback", -> @@ -379,7 +392,7 @@ describe 'DocumentUpdaterHandler', -> describe "when the document updater returns a failure error code", -> beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "") + @request.callsArgWith(1, null, { statusCode: 500 }, "") @handler.deleteThread @project_id, @doc_id, @thread_id, @callback it "should return the callback with an error", -> @@ -396,12 +409,10 @@ describe 'DocumentUpdaterHandler', -> describe "with project history disabled", -> beforeEach -> @settings.apis.project_history.sendProjectStructureOps = false - @request.post = sinon.stub() - @handler.updateProjectStructure @project_id, @user_id, {}, @callback it 'does not make a web request', -> - @request.post.called.should.equal false + @request.called.should.equal false it 'calls the callback', -> @callback.called.should.equal true @@ -410,7 +421,7 @@ describe 'DocumentUpdaterHandler', -> beforeEach -> @settings.apis.project_history.sendProjectStructureOps = true @url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}" - @request.post = sinon.stub().callsArgWith(1, null, {statusCode: 204}, "") + @request.callsArgWith(1, null, {statusCode: 204}, "") describe "when an entity has changed name", -> it 'should send the structure update to the document updater', (done) -> @@ -435,9 +446,12 @@ describe 'DocumentUpdaterHandler', -> ] @handler.updateProjectStructure @project_id, @user_id, @changes, () => - @request.post - .calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id, version:@version}) - .should.equal true + @request.calledWith( + url: @url, + method: "POST" + json: {docUpdates, fileUpdates: [], userId: @user_id, @version} + ) + .should.equal true done() describe "when a doc has been added", -> @@ -455,9 +469,11 @@ describe 'DocumentUpdaterHandler', -> ] @handler.updateProjectStructure @project_id, @user_id, @changes, () => - @request.post - .calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id, version:@version}) - .should.equal true + @request.calledWith( + url: @url + method: "POST" + json: {docUpdates, fileUpdates: [], userId: @user_id, @version} + ).should.equal true done() describe "when a file has been added", -> @@ -475,9 +491,11 @@ describe 'DocumentUpdaterHandler', -> ] @handler.updateProjectStructure @project_id, @user_id, @changes, () => - @request.post - .calledWith(url: @url, json: {docUpdates: [], fileUpdates, userId: @user_id, version:@version}) - .should.equal true + @request.calledWith( + url: @url + method: "POST" + json: {docUpdates: [], fileUpdates, userId: @user_id, @version} + ).should.equal true done() describe "when an entity has been deleted", -> @@ -494,8 +512,9 @@ describe 'DocumentUpdaterHandler', -> ] @handler.updateProjectStructure @project_id, @user_id, @changes, () => - @request.post - .calledWith(url: @url, json: {docUpdates, fileUpdates: [], userId: @user_id, version:@version}) - .should.equal true + @request.calledWith( + url: @url + method: "POST" + json: {docUpdates, fileUpdates: [], userId: @user_id, @version} + ).should.equal true done() -