2014-02-20 17:33:12 -05:00
|
|
|
assert = require("chai").assert
|
|
|
|
sinon = require('sinon')
|
|
|
|
chai = require('chai')
|
|
|
|
should = chai.should()
|
|
|
|
expect = chai.expect
|
|
|
|
modulePath = "../../../../app/js/Features/FileStore/FileStoreController.js"
|
|
|
|
SandboxedModule = require('sandboxed-module')
|
|
|
|
|
|
|
|
describe "FileStoreController", ->
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
@FileStoreHandler =
|
|
|
|
getFileStream: sinon.stub()
|
|
|
|
@ProjectLocator =
|
|
|
|
findElement: sinon.stub()
|
|
|
|
@controller = SandboxedModule.require modulePath, requires:
|
|
|
|
"settings-sharelatex": @settings
|
|
|
|
"logger-sharelatex" : @logger = {log:sinon.stub(), err:sinon.stub()}
|
|
|
|
"../Project/ProjectLocator": @ProjectLocator
|
|
|
|
"./FileStoreHandler": @FileStoreHandler
|
|
|
|
@stream = {}
|
|
|
|
@project_id = "2k3j1lk3j21lk3j"
|
|
|
|
@file_id = "12321kklj1lk3jk12"
|
2015-08-20 07:28:51 -04:00
|
|
|
@req =
|
2014-02-20 17:33:12 -05:00
|
|
|
params:
|
|
|
|
Project_id: @project_id
|
|
|
|
File_id: @file_id
|
|
|
|
query: "query string here"
|
2015-08-20 07:28:51 -04:00
|
|
|
get: (key) -> undefined
|
|
|
|
@res =
|
2014-02-20 17:33:12 -05:00
|
|
|
setHeader: sinon.stub()
|
2017-04-12 11:00:02 -04:00
|
|
|
setContentDisposition: sinon.stub()
|
2015-08-20 07:28:51 -04:00
|
|
|
@file =
|
2014-02-20 17:33:12 -05:00
|
|
|
name: "myfile.png"
|
|
|
|
|
|
|
|
describe "getFile", ->
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
@FileStoreHandler.getFileStream.callsArgWith(3, null, @stream)
|
|
|
|
@ProjectLocator.findElement.callsArgWith(1, null, @file)
|
|
|
|
|
|
|
|
it "should call the file store handler with the project_id file_id and any query string", (done)->
|
|
|
|
@stream.pipe = (des)=>
|
|
|
|
@FileStoreHandler.getFileStream.calledWith(@req.params.Project_id, @req.params.File_id, @req.query).should.equal true
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
|
|
|
|
|
|
|
it "should pipe to res", (done)->
|
|
|
|
@stream.pipe = (des)=>
|
|
|
|
des.should.equal @res
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
|
|
|
|
2015-08-20 09:03:12 -04:00
|
|
|
it "should get the file from the db", (done)->
|
2014-02-20 17:33:12 -05:00
|
|
|
@stream.pipe = (des)=>
|
|
|
|
opts =
|
|
|
|
project_id: @project_id
|
|
|
|
element_id: @file_id
|
|
|
|
type: "file"
|
|
|
|
@ProjectLocator.findElement.calledWith(opts).should.equal true
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
|
|
|
|
|
|
|
it "should set the Content-Disposition header", (done)->
|
|
|
|
@stream.pipe = (des)=>
|
2017-04-12 11:00:02 -04:00
|
|
|
@res.setContentDisposition.calledWith(
|
|
|
|
"attachment", {filename: @file.name}
|
2017-04-12 04:31:59 -04:00
|
|
|
).should.equal true
|
2014-02-20 17:33:12 -05:00
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
# Test behaviour around handling html files
|
|
|
|
['.html', '.htm', '.xhtml'].forEach (extension) ->
|
|
|
|
describe "with a '#{extension}' file extension", ->
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
beforeEach ->
|
|
|
|
@file.name = "bad#{extension}"
|
|
|
|
@req.get = (key) =>
|
|
|
|
if key == 'User-Agent'
|
2018-02-26 06:34:08 -05:00
|
|
|
return 'A generic browser'
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
describe "from a non-ios browser", ->
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
it "should not set Content-Type", (done) ->
|
|
|
|
@stream.pipe = (des) =>
|
|
|
|
@res.setHeader.calledWith("Content-Type", "text/plain").should.equal false
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
describe "from an iPhone", ->
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
beforeEach ->
|
2018-02-26 06:34:08 -05:00
|
|
|
@req.get = (key) =>
|
|
|
|
if key == 'User-Agent'
|
|
|
|
return "An iPhone browser"
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
it "should set Content-Type to 'text/plain'", (done) ->
|
|
|
|
@stream.pipe = (des) =>
|
|
|
|
@res.setHeader.calledWith("Content-Type", "text/plain").should.equal true
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
describe "from an iPad", ->
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
beforeEach ->
|
2018-02-26 06:34:08 -05:00
|
|
|
@req.get = (key) =>
|
|
|
|
if key == 'User-Agent'
|
|
|
|
return "An iPad browser"
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
it "should set Content-Type to 'text/plain'", (done) ->
|
|
|
|
@stream.pipe = (des) =>
|
|
|
|
@res.setHeader.calledWith("Content-Type", "text/plain").should.equal true
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|
|
|
|
|
|
|
|
# None of these should trigger the iOS/html logic
|
2015-08-20 10:58:36 -04:00
|
|
|
['x.html-is-rad', 'html.pdf', '.html-is-good-for-hidden-files', 'somefile'].forEach (filename) ->
|
2015-08-20 10:56:56 -04:00
|
|
|
describe "with filename as '#{filename}'", ->
|
2015-08-20 09:03:12 -04:00
|
|
|
|
2015-08-20 10:56:56 -04:00
|
|
|
beforeEach ->
|
|
|
|
@user_agent = 'A generic browser'
|
|
|
|
@file.name = filename
|
|
|
|
@req.get = (key) =>
|
|
|
|
if key == 'User-Agent'
|
|
|
|
@user_agent
|
|
|
|
|
|
|
|
['iPhone', 'iPad', 'Firefox', 'Chrome'].forEach (browser) ->
|
|
|
|
describe "downloaded from #{browser}", ->
|
|
|
|
beforeEach ->
|
|
|
|
@user_agent = "Some #{browser} thing"
|
|
|
|
|
|
|
|
it 'Should not set the Content-type', (done) ->
|
|
|
|
@stream.pipe = (des) =>
|
|
|
|
@res.setHeader.calledWith("Content-Type", "text/plain").should.equal false
|
|
|
|
done()
|
|
|
|
@controller.getFile @req, @res
|