FileStoreControllerTests.coffee 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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/Features/FileStore/FileStoreController.js"
  7. SandboxedModule = require('sandboxed-module')
  8. describe "FileStoreController", ->
  9. beforeEach ->
  10. @FileStoreHandler =
  11. getFileStream: sinon.stub()
  12. @ProjectLocator =
  13. findElement: sinon.stub()
  14. @controller = SandboxedModule.require modulePath, requires:
  15. "settings-sharelatex": @settings
  16. "logger-sharelatex" : @logger = {log:sinon.stub(), err:sinon.stub()}
  17. "../Project/ProjectLocator": @ProjectLocator
  18. "./FileStoreHandler": @FileStoreHandler
  19. @stream = {}
  20. @project_id = "2k3j1lk3j21lk3j"
  21. @file_id = "12321kklj1lk3jk12"
  22. @req =
  23. params:
  24. Project_id: @project_id
  25. File_id: @file_id
  26. query: "query string here"
  27. get: (key) -> undefined
  28. @res =
  29. setHeader: sinon.stub()
  30. setContentDisposition: sinon.stub()
  31. @file =
  32. name: "myfile.png"
  33. describe "getFile", ->
  34. beforeEach ->
  35. @FileStoreHandler.getFileStream.callsArgWith(3, null, @stream)
  36. @ProjectLocator.findElement.callsArgWith(1, null, @file)
  37. it "should call the file store handler with the project_id file_id and any query string", (done)->
  38. @stream.pipe = (des)=>
  39. @FileStoreHandler.getFileStream.calledWith(@req.params.Project_id, @req.params.File_id, @req.query).should.equal true
  40. done()
  41. @controller.getFile @req, @res
  42. it "should pipe to res", (done)->
  43. @stream.pipe = (des)=>
  44. des.should.equal @res
  45. done()
  46. @controller.getFile @req, @res
  47. it "should get the file from the db", (done)->
  48. @stream.pipe = (des)=>
  49. opts =
  50. project_id: @project_id
  51. element_id: @file_id
  52. type: "file"
  53. @ProjectLocator.findElement.calledWith(opts).should.equal true
  54. done()
  55. @controller.getFile @req, @res
  56. it "should set the Content-Disposition header", (done)->
  57. @stream.pipe = (des)=>
  58. @res.setContentDisposition.calledWith(
  59. "attachment", {filename: @file.name}
  60. ).should.equal true
  61. done()
  62. @controller.getFile @req, @res
  63. # Test behaviour around handling html files
  64. ['.html', '.htm', '.xhtml'].forEach (extension) ->
  65. describe "with a '#{extension}' file extension", ->
  66. beforeEach ->
  67. @file.name = "bad#{extension}"
  68. @req.get = (key) =>
  69. if key == 'User-Agent'
  70. return 'A generic browser'
  71. describe "from a non-ios browser", ->
  72. it "should not set Content-Type", (done) ->
  73. @stream.pipe = (des) =>
  74. @res.setHeader.calledWith("Content-Type", "text/plain").should.equal false
  75. done()
  76. @controller.getFile @req, @res
  77. describe "from an iPhone", ->
  78. beforeEach ->
  79. @req.get = (key) =>
  80. if key == 'User-Agent'
  81. return "An iPhone browser"
  82. it "should set Content-Type to 'text/plain'", (done) ->
  83. @stream.pipe = (des) =>
  84. @res.setHeader.calledWith("Content-Type", "text/plain").should.equal true
  85. done()
  86. @controller.getFile @req, @res
  87. describe "from an iPad", ->
  88. beforeEach ->
  89. @req.get = (key) =>
  90. if key == 'User-Agent'
  91. return "An iPad browser"
  92. it "should set Content-Type to 'text/plain'", (done) ->
  93. @stream.pipe = (des) =>
  94. @res.setHeader.calledWith("Content-Type", "text/plain").should.equal true
  95. done()
  96. @controller.getFile @req, @res
  97. # None of these should trigger the iOS/html logic
  98. ['x.html-is-rad', 'html.pdf', '.html-is-good-for-hidden-files', 'somefile'].forEach (filename) ->
  99. describe "with filename as '#{filename}'", ->
  100. beforeEach ->
  101. @user_agent = 'A generic browser'
  102. @file.name = filename
  103. @req.get = (key) =>
  104. if key == 'User-Agent'
  105. @user_agent
  106. ['iPhone', 'iPad', 'Firefox', 'Chrome'].forEach (browser) ->
  107. describe "downloaded from #{browser}", ->
  108. beforeEach ->
  109. @user_agent = "Some #{browser} thing"
  110. it 'Should not set the Content-type', (done) ->
  111. @stream.pipe = (des) =>
  112. @res.setHeader.calledWith("Content-Type", "text/plain").should.equal false
  113. done()
  114. @controller.getFile @req, @res