FileControllerTests.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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/FileController.js"
  7. SandboxedModule = require('sandboxed-module')
  8. describe "FileController", ->
  9. beforeEach ->
  10. @PersistorManager =
  11. sendStream: sinon.stub()
  12. copyFile: sinon.stub()
  13. deleteFile:sinon.stub()
  14. @settings =
  15. s3:
  16. buckets:
  17. user_files:"user_files"
  18. @FileHandler =
  19. getFile: sinon.stub()
  20. getFileSize: sinon.stub()
  21. deleteFile: sinon.stub()
  22. insertFile: sinon.stub()
  23. getDirectorySize: sinon.stub()
  24. @LocalFileWriter = {}
  25. @controller = SandboxedModule.require modulePath, requires:
  26. "./LocalFileWriter":@LocalFileWriter
  27. "./FileHandler": @FileHandler
  28. "./PersistorManager":@PersistorManager
  29. "./Errors": @Errors =
  30. NotFoundError: sinon.stub()
  31. "settings-sharelatex": @settings
  32. "metrics-sharelatex":
  33. inc:->
  34. "logger-sharelatex":
  35. log:->
  36. err:->
  37. @project_id = "project_id"
  38. @file_id = "file_id"
  39. @bucket = "user_files"
  40. @key = "#{@project_id}/#{@file_id}"
  41. @req =
  42. key:@key
  43. bucket:@bucket
  44. query:{}
  45. params:
  46. project_id:@project_id
  47. file_id:@file_id
  48. headers: {}
  49. @res =
  50. set: sinon.stub().returnsThis()
  51. status: sinon.stub().returnsThis()
  52. @fileStream = {}
  53. describe "getFile", ->
  54. it "should pipe the stream", (done)->
  55. @FileHandler.getFile.callsArgWith(3, null, @fileStream)
  56. @fileStream.pipe = (res)=>
  57. res.should.equal @res
  58. done()
  59. @controller.getFile @req, @res
  60. it "should send a 200 if the cacheWarm param is true", (done)->
  61. @req.query.cacheWarm = true
  62. @FileHandler.getFile.callsArgWith(3, null, @fileStream)
  63. @res.send = (statusCode)=>
  64. statusCode.should.equal 200
  65. done()
  66. @controller.getFile @req, @res
  67. it "should send a 500 if there is a problem", (done)->
  68. @FileHandler.getFile.callsArgWith(3, "error")
  69. @res.send = (code)=>
  70. code.should.equal 500
  71. done()
  72. @controller.getFile @req, @res
  73. describe "with a 'Range' header set", ->
  74. beforeEach ->
  75. @req.headers.range = 'bytes=0-8'
  76. it "should pass 'start' and 'end' options to FileHandler", (done) ->
  77. @FileHandler.getFile.callsArgWith(3, null, @fileStream)
  78. @fileStream.pipe = (res)=>
  79. expect(@FileHandler.getFile.lastCall.args[2].start).to.equal 0
  80. expect(@FileHandler.getFile.lastCall.args[2].end).to.equal 8
  81. done()
  82. @controller.getFile @req, @res
  83. describe "getFileHead", ->
  84. it "should return the file size in a Content-Length header", (done) ->
  85. expectedFileSize = 84921
  86. @FileHandler.getFileSize.yields(
  87. new Error("FileHandler.getFileSize: unexpected arguments")
  88. )
  89. @FileHandler.getFileSize.withArgs(@bucket, @key).yields(null, expectedFileSize)
  90. @res.end = () =>
  91. expect(@res.status.lastCall.args[0]).to.equal(200)
  92. expect(@res.set.calledWith("Content-Length", expectedFileSize)).to.equal(true)
  93. done()
  94. @controller.getFileHead(@req, @res)
  95. it "should return a 404 is the file is not found", (done) ->
  96. @FileHandler.getFileSize.yields(new @Errors.NotFoundError())
  97. @res.end = () =>
  98. expect(@res.status.lastCall.args[0]).to.equal(404)
  99. done()
  100. @controller.getFileHead(@req, @res)
  101. it "should return a 500 on internal errors", (done) ->
  102. @FileHandler.getFileSize.yields(new Error())
  103. @res.end = () =>
  104. expect(@res.status.lastCall.args[0]).to.equal(500)
  105. done()
  106. @controller.getFileHead(@req, @res)
  107. describe "insertFile", ->
  108. it "should send bucket name key and res to PersistorManager", (done)->
  109. @FileHandler.insertFile.callsArgWith(3)
  110. @res.send = =>
  111. @FileHandler.insertFile.calledWith(@bucket, @key, @req).should.equal true
  112. done()
  113. @controller.insertFile @req, @res
  114. describe "copyFile", ->
  115. beforeEach ->
  116. @oldFile_id = "old_file_id"
  117. @oldProject_id = "old_project_id"
  118. @req.body =
  119. source:
  120. project_id: @oldProject_id
  121. file_id: @oldFile_id
  122. it "should send bucket name and both keys to PersistorManager", (done)->
  123. @PersistorManager.copyFile.callsArgWith(3)
  124. @res.send = (code)=>
  125. code.should.equal 200
  126. @PersistorManager.copyFile.calledWith(@bucket, "#{@oldProject_id}/#{@oldFile_id}", @key).should.equal true
  127. done()
  128. @controller.copyFile @req, @res
  129. it "should send a 404 if the original file was not found", (done) ->
  130. @PersistorManager.copyFile.callsArgWith(3, new @Errors.NotFoundError())
  131. @res.send = (code)=>
  132. code.should.equal 404
  133. done()
  134. @controller.copyFile @req, @res
  135. it "should send a 500 if there was an error", (done)->
  136. @PersistorManager.copyFile.callsArgWith(3, "error")
  137. @res.send = (code)=>
  138. code.should.equal 500
  139. done()
  140. @controller.copyFile @req, @res
  141. describe "delete file", ->
  142. it "should tell the file handler", (done)->
  143. @FileHandler.deleteFile.callsArgWith(2)
  144. @res.send = (code)=>
  145. code.should.equal 204
  146. @FileHandler.deleteFile.calledWith(@bucket, @key).should.equal true
  147. done()
  148. @controller.deleteFile @req, @res
  149. it "should send a 500 if there was an error", (done)->
  150. @FileHandler.deleteFile.callsArgWith(2, "error")
  151. @res.send = (code)->
  152. code.should.equal 500
  153. done()
  154. @controller.deleteFile @req, @res
  155. describe "_get_range", ->
  156. it "should parse a valid Range header", (done) ->
  157. result = @controller._get_range('bytes=0-200')
  158. expect(result).to.not.equal null
  159. expect(result.start).to.equal 0
  160. expect(result.end).to.equal 200
  161. done()
  162. it "should return null for an invalid Range header", (done) ->
  163. result = @controller._get_range('wat')
  164. expect(result).to.equal null
  165. done()
  166. it "should return null for any type other than 'bytes'", (done) ->
  167. result = @controller._get_range('carrots=0-200')
  168. expect(result).to.equal null
  169. done()
  170. describe "directorySize", ->
  171. it "should return total directory size bytes", (done) ->
  172. @FileHandler.getDirectorySize.callsArgWith(2, null, 1024)
  173. @controller.directorySize @req, json:(result)=>
  174. expect(result['total bytes']).to.equal 1024
  175. done()
  176. it "should send a 500 if there was an error", (done)->
  177. @FileHandler.getDirectorySize.callsArgWith(2, "error")
  178. @res.send = (code)->
  179. code.should.equal 500
  180. done()
  181. @controller.directorySize @req, @res