DocArchiveManager.coffee 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. assert = require("chai").assert
  2. sinon = require('sinon')
  3. chai = require('chai')
  4. should = chai.should()
  5. expect = chai.expect
  6. modulePath = "../../../app/js/DocArchiveManager.js"
  7. SandboxedModule = require('sandboxed-module')
  8. ObjectId = require("mongojs").ObjectId
  9. Errors = require "../../../app/js/Errors"
  10. crypto = require("crypto")
  11. describe "DocArchiveManager", ->
  12. beforeEach ->
  13. @settings =
  14. docstore:
  15. s3:
  16. secret: "secret"
  17. key: "this_key"
  18. bucket:"doc-archive-unit-test"
  19. @request =
  20. put: {}
  21. get: {}
  22. del: {}
  23. @archivedDocs = [{
  24. _id: ObjectId()
  25. inS3:true
  26. rev: 2
  27. }, {
  28. _id: ObjectId()
  29. inS3:true
  30. rev: 4
  31. }, {
  32. _id: ObjectId()
  33. inS3:true
  34. rev: 6
  35. }]
  36. @mongoDocs = [{
  37. _id: ObjectId()
  38. lines: ["one", "two", "three"]
  39. rev: 2
  40. }, {
  41. _id: ObjectId()
  42. lines: ["aaa", "bbb", "ccc"]
  43. rev: 4
  44. }, {
  45. _id: ObjectId()
  46. inS3: true
  47. rev: 6
  48. }, {
  49. _id: ObjectId()
  50. inS3: true
  51. rev: 6
  52. }, {
  53. _id: ObjectId()
  54. lines: ["111", "222", "333"]
  55. rev: 6
  56. }]
  57. @MongoManager =
  58. markDocAsArchived: sinon.stub().callsArgWith(2, null)
  59. upsertIntoDocCollection: sinon.stub().callsArgWith(3, null)
  60. getProjectsDocs: sinon.stub().callsArgWith(1, null, @mongoDocs)
  61. getArchivedProjectDocs: sinon.stub().callsArgWith(1, null, @mongoDocs)
  62. @requires =
  63. "settings-sharelatex": @settings
  64. "./MongoManager": @MongoManager
  65. "request": @request
  66. "logger-sharelatex":
  67. log:->
  68. err:->
  69. @error = "my errror"
  70. @project_id = ObjectId().toString()
  71. @stubbedError = new Errors.NotFoundError("Error in S3 request")
  72. @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires
  73. describe "archiveDoc", ->
  74. it "should use correct options", (done)->
  75. @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:""}})
  76. @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=>
  77. opts = @request.put.args[0][0]
  78. assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket})
  79. opts.json.should.equal @mongoDocs[0].lines
  80. opts.timeout.should.equal (30*1000)
  81. opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}"
  82. done()
  83. it "should return no md5 error", (done)->
  84. @md5 = crypto.createHash("md5").update(JSON.stringify(@mongoDocs[0].lines)).digest("hex")
  85. @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:@md5}})
  86. @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=>
  87. should.not.exist err
  88. done()
  89. it "should return the error", (done)->
  90. @request.put = sinon.stub().callsArgWith(1, @stubbedError, {statusCode:400,headers:{etag:""}})
  91. @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=>
  92. should.exist err
  93. done()
  94. describe "unarchiveDoc", ->
  95. it "should use correct options", (done)->
  96. @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @mongoDocs[0].lines)
  97. @request.del = sinon.stub().callsArgWith(1, null, statusCode:204, {})
  98. @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0]._id, (err)=>
  99. opts = @request.get.args[0][0]
  100. assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket})
  101. opts.json.should.equal true
  102. opts.timeout.should.equal (30*1000)
  103. opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}"
  104. done()
  105. it "should return the error", (done)->
  106. @request.get = sinon.stub().callsArgWith(1, @stubbedError, {}, {})
  107. @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0], (err)=>
  108. should.exist err
  109. done()
  110. describe "archiveAllDocs", ->
  111. it "should archive all project docs which are not in s3", (done)->
  112. @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @mongoDocs)
  113. @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null)
  114. @DocArchiveManager.archiveAllDocs @project_id, (err)=>
  115. @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[0]).should.equal true
  116. @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[1]).should.equal true
  117. @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[4]).should.equal true
  118. @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[2]).should.equal false
  119. @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[3]).should.equal false
  120. should.not.exist err
  121. done()
  122. it "should return error if have no docs", (done)->
  123. @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null)
  124. @DocArchiveManager.archiveAllDocs @project_id, (err)=>
  125. should.exist err
  126. done()
  127. it "should return the error", (done)->
  128. @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, @error, null)
  129. @DocArchiveManager.archiveAllDocs @project_id, (err)=>
  130. err.should.equal @error
  131. done()
  132. describe "when most have been already put in s3", ->
  133. beforeEach ->
  134. numberOfDocs = 10 * 1000
  135. @mongoDocs = []
  136. while --numberOfDocs != 0
  137. @mongoDocs.push({inS3:true, _id: ObjectId()})
  138. @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @mongoDocs)
  139. @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null)
  140. it "should not throw and error", (done)->
  141. @DocArchiveManager.archiveAllDocs @project_id, (err)=>
  142. should.not.exist err
  143. done()
  144. describe "unArchiveAllDocs", ->
  145. it "should unarchive all inS3 docs", (done)->
  146. @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, @archivedDocs)
  147. @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null)
  148. @DocArchiveManager.unArchiveAllDocs @project_id, (err)=>
  149. for doc in @archivedDocs
  150. @DocArchiveManager.unarchiveDoc.calledWith(@project_id, doc._id).should.equal true
  151. should.not.exist err
  152. done()
  153. it "should return error if have no docs", (done)->
  154. @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, null)
  155. @DocArchiveManager.unArchiveAllDocs @project_id, (err)=>
  156. should.exist err
  157. done()
  158. it "should return the error", (done)->
  159. @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, @error, null)
  160. @DocArchiveManager.unArchiveAllDocs @project_id, (err)=>
  161. err.should.equal @error
  162. done()