VersioningApiHandlerTests.coffee 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. assert = require('chai').assert
  2. chai = require('chai')
  3. should = chai.should()
  4. sinon = require("sinon")
  5. modulePath = "../../../../app/js/Features/Versioning/VersioningApiHandler"
  6. SandboxedModule = require('sandboxed-module')
  7. tk = require 'timekeeper'
  8. describe "VersioningApiHandler", ->
  9. beforeEach ->
  10. tk.freeze(Date.now())
  11. @fakeHttp ={}
  12. @requestQueuer = {}
  13. @thirdParyDataStoreManager = {}
  14. @documentUpdaterHandler =
  15. flushProjectToMongo : (project_id, sl_req_id, callback) -> callback()
  16. @projectEntityHandler = {}
  17. @ProjectModel =
  18. getProject : (project_id, fields, callback)=>
  19. callback(null, @project)
  20. @rclient =
  21. auth:->
  22. srem: sinon.stub().callsArg(2)
  23. set: sinon.stub().callsArg(2)
  24. @settings =
  25. apis:
  26. versioning:
  27. snapshotwaitInMs:100
  28. url: "http://localhost:4000"
  29. username:"username"
  30. password:"password"
  31. redis:
  32. web: {}
  33. fairy: {}
  34. @versioningApi = SandboxedModule.require modulePath,
  35. requires:
  36. '../../models/Project':{Project:@ProjectModel}
  37. '../../Features/DocumentUpdater/DocumentUpdaterHandler' : @documentUpdaterHandler
  38. '../../Features/Project/ProjectEntityHandler' : @projectEntityHandler
  39. 'fairy':{connect:=>{queue:=>@requestQueuer}}
  40. 'request': @fakeHttp
  41. 'settings-sharelatex' : @settings
  42. 'logger-sharelatex':
  43. log:->
  44. err:->
  45. 'redis' : createClient: () => @rclient
  46. globals:
  47. Date: Date
  48. @project = _id:"123456", existsInVersioningApi : false
  49. @callback = sinon.stub()
  50. afterEach -> tk.reset()
  51. it 'should create project in versioning api using request queuer', (done)->
  52. @requestQueuer.enqueue = (project_id, method, options, callback)=>
  53. project_id.should.equal @project._id
  54. method.should.equal "standardHttpRequest"
  55. options.method.should.equal "post"
  56. options.url.should.equal("#{@settings.apis.versioning.url}/project/#{@project._id}")
  57. done()
  58. @versioningApi.createProject(@project._id)
  59. describe "takeSnapshot", ->
  60. beforeEach ->
  61. @message = "finished chapter"
  62. @requestQueuer.enqueue = (project_id, method, options, callback) -> callback()
  63. sinon.spy @requestQueuer, "enqueue"
  64. sinon.spy @documentUpdaterHandler, "flushProjectToMongo"
  65. @versioningApi.takeSnapshot(@project._id, @message)
  66. afterEach ->
  67. @documentUpdaterHandler.flushProjectToMongo.restore()
  68. it 'should flush the document to the third party datastore', ->
  69. @documentUpdaterHandler.flushProjectToMongo.calledWith(@project._id).should.equal true
  70. @documentUpdaterHandler.flushProjectToMongo.calledBefore(@requestQueuer.enqueue)
  71. it 'should queue a request for the versioning api', ->
  72. @requestQueuer.enqueue.calledWith(@project._id, "standardHttpRequest").should.equal true
  73. options = @requestQueuer.enqueue.args[0][2]
  74. options.method.should.equal "post"
  75. options.url.should.equal("#{@settings.apis.versioning.url}/project/#{@project._id}/version")
  76. assert.deepEqual options.json, {version: {message: @message}}
  77. it "should remove the project from the set needing snapshotting", ->
  78. @rclient.srem.calledWith("projects_to_snapshot", @project._id).should.equal true
  79. it "should set the project's last snapshot date", ->
  80. @rclient.set.calledWith("project_last_snapshot:#{@project._id}", Date.now()).should.equal true
  81. it 'proxyToVersioningApi pipes to url passed', (done)->
  82. res = {some:"stuff"}
  83. req = url : "/somewhere"
  84. @fakeHttp.get = (options)=>
  85. options.url.should.equal("#{@settings.apis.versioning.url}#{req.url}")
  86. return {
  87. pipe:(pipedResponse)->
  88. pipedResponse.should.deep.equal res
  89. done()
  90. on: () ->
  91. }
  92. @versioningApi.proxyToVersioningApi req, res
  93. describe "enableVersioning", ->
  94. beforeEach ->
  95. @projectEntityHandler.flushProjectToThirdPartyDataStore = sinon.stub().callsArg(1)
  96. @versioningApi.createProject = sinon.stub().callsArg(1)
  97. @ProjectModel.update = sinon.stub().callsArg(3)
  98. describe "successfully", ->
  99. beforeEach ->
  100. @versioningApi.enableVersioning @project._id, ->
  101. it "should flush the project to the TPDS", ->
  102. @projectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(@project._id)
  103. .should.equal true
  104. it "should create the project in the versioning api", ->
  105. @versioningApi.createProject.calledWith(@project._id)
  106. .should.equal true
  107. it "should set the existsInVersioningApi flag to true", ->
  108. @ProjectModel.update.calledWith({_id: @project._id}, {existsInVersioningApi: true})
  109. .should.equal true
  110. describe "with a non existant project id", ->
  111. beforeEach ->
  112. @ProjectModel.getProject = (project_id, fields, callback)->
  113. callback null, null
  114. @versioningApi.enableVersioning @project._id, @callback
  115. it "should return an error", ->
  116. should.exist @callback.args[0][0]
  117. it "should not try to enable versioning", ->
  118. @projectEntityHandler.flushProjectToThirdPartyDataStore.called.should.equal false
  119. @versioningApi.createProject.called.should.equal false
  120. @ProjectModel.update.called.should.equal false
  121. describe "when versioning API request fails", ->
  122. beforeEach ->
  123. @versioningApi.createProject = sinon.stub().callsArgWith(1, new Error("something went wrong"))
  124. @versioningApi.enableVersioning @project._id, @callback
  125. it "should return an error", ->
  126. should.exist @callback.args[0][0]
  127. it "should not try to flush the project or save the change", ->
  128. @projectEntityHandler.flushProjectToThirdPartyDataStore.called.should.equal false
  129. @ProjectModel.update.called.should.equal false
  130. describe "when the project already has versioning enabled", ->
  131. beforeEach ->
  132. @project.existsInVersioningApi = true
  133. @versioningApi.enableVersioning @project._id, @callback
  134. it "should not return an error", ->
  135. @callback.calledWithExactly().should.equal true
  136. it "should not try to enable versioning again", ->
  137. @projectEntityHandler.flushProjectToThirdPartyDataStore.called.should.equal false
  138. @versioningApi.createProject.called.should.equal false
  139. @ProjectModel.update.called.should.equal false