2014-02-12 05:23:40 -05:00
|
|
|
assert = require("chai").assert
|
|
|
|
sinon = require('sinon')
|
|
|
|
chai = require('chai')
|
|
|
|
should = chai.should()
|
|
|
|
expect = chai.expect
|
|
|
|
modulePath = "../../../../app/js/Features/FileStore/FileStoreHandler.js"
|
|
|
|
SandboxedModule = require('sandboxed-module')
|
|
|
|
|
|
|
|
describe "FileStoreHandler", ->
|
|
|
|
beforeEach ->
|
|
|
|
@fs =
|
|
|
|
createReadStream : sinon.stub()
|
2016-03-12 10:05:29 -05:00
|
|
|
lstat: sinon.stub().callsArgWith(1, null, {
|
|
|
|
isFile:=> @isSafeOnFileSystem
|
|
|
|
isDirectory:-> return false
|
|
|
|
})
|
2014-02-14 13:13:22 -05:00
|
|
|
@writeStream =
|
|
|
|
my:"writeStream"
|
|
|
|
on: (type, cb)->
|
2017-03-09 05:11:45 -05:00
|
|
|
if type == "response"
|
|
|
|
cb({statusCode: 200})
|
2016-03-23 11:13:32 -04:00
|
|
|
@readStream = {my:"readStream", on: sinon.stub()}
|
2014-02-12 05:23:40 -05:00
|
|
|
@request = sinon.stub()
|
|
|
|
@settings = apis:{filestore:{url:"http//filestore.sharelatex.test"}}
|
|
|
|
@handler = SandboxedModule.require modulePath, requires:
|
|
|
|
"settings-sharelatex":@settings
|
|
|
|
"request":@request
|
|
|
|
"logger-sharelatex" : @logger = {log:sinon.stub(), err:sinon.stub()}
|
|
|
|
"fs" : @fs
|
|
|
|
@file_id = "file_id_here"
|
|
|
|
@project_id = "1312312312"
|
|
|
|
@fsPath = "uploads/myfile.eps"
|
|
|
|
@handler._buildUrl = sinon.stub().returns("http://filestore.stubbedBuilder.com")
|
|
|
|
|
|
|
|
describe "uploadFileFromDisk", ->
|
|
|
|
beforeEach ->
|
|
|
|
@request.returns(@writeStream)
|
2016-03-12 10:05:29 -05:00
|
|
|
@isSafeOnFileSystem = true
|
2014-02-12 05:23:40 -05:00
|
|
|
|
|
|
|
it "should create read stream", (done)->
|
|
|
|
@fs.createReadStream.returns
|
|
|
|
pipe:->
|
2017-05-15 08:46:01 -04:00
|
|
|
on: (type, cb)->
|
|
|
|
if type == "open"
|
2014-02-12 05:23:40 -05:00
|
|
|
cb()
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
|
|
|
@fs.createReadStream.calledWith(@fsPath).should.equal true
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "should pipe the read stream to request", (done)->
|
|
|
|
@request.returns(@writeStream)
|
|
|
|
@fs.createReadStream.returns
|
|
|
|
on: (type, cb)->
|
2017-05-15 08:46:01 -04:00
|
|
|
if type == "open"
|
2014-02-12 05:23:40 -05:00
|
|
|
cb()
|
|
|
|
pipe:(o)=>
|
|
|
|
@writeStream.should.equal o
|
|
|
|
done()
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
|
|
|
|
|
|
|
it "should pass the correct options to request", (done)->
|
|
|
|
@fs.createReadStream.returns
|
|
|
|
pipe:->
|
|
|
|
on: (type, cb)->
|
2017-05-15 08:46:01 -04:00
|
|
|
if type == "open"
|
2014-02-12 05:23:40 -05:00
|
|
|
cb()
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
|
|
|
@request.args[0][0].method.should.equal "post"
|
|
|
|
@request.args[0][0].uri.should.equal @handler._buildUrl()
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "builds the correct url", (done)->
|
|
|
|
@fs.createReadStream.returns
|
|
|
|
pipe:->
|
|
|
|
on: (type, cb)->
|
2017-05-15 08:46:01 -04:00
|
|
|
if type == "open"
|
2014-02-12 05:23:40 -05:00
|
|
|
cb()
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
|
|
|
@handler._buildUrl.calledWith(@project_id, @file_id).should.equal true
|
|
|
|
done()
|
|
|
|
|
2017-03-09 05:11:45 -05:00
|
|
|
it 'should callback with null', (done) ->
|
|
|
|
@fs.createReadStream.returns
|
|
|
|
pipe:->
|
|
|
|
on: (type, cb)->
|
2017-05-15 08:46:01 -04:00
|
|
|
if type == "open"
|
2017-03-09 05:11:45 -05:00
|
|
|
cb()
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, (err) =>
|
|
|
|
expect(err).to.not.exist
|
|
|
|
done()
|
|
|
|
|
2016-03-12 07:01:36 -05:00
|
|
|
describe "symlink", ->
|
|
|
|
it "should not read file if it is symlink", (done)->
|
2016-03-12 10:05:29 -05:00
|
|
|
@isSafeOnFileSystem = false
|
2016-03-12 07:01:36 -05:00
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
|
|
|
@fs.createReadStream.called.should.equal false
|
|
|
|
done()
|
|
|
|
|
2017-03-17 09:03:16 -04:00
|
|
|
describe "symlink", ->
|
|
|
|
it "should not read file stat returns nothing", (done)->
|
|
|
|
@fs.lstat = sinon.stub().callsArgWith(1, null, null)
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, =>
|
|
|
|
@fs.createReadStream.called.should.equal false
|
|
|
|
done()
|
|
|
|
|
2017-03-09 05:11:45 -05:00
|
|
|
describe "when upload fails", ->
|
|
|
|
beforeEach ->
|
|
|
|
@writeStream.on = (type, cb) ->
|
|
|
|
if type == "response"
|
|
|
|
cb({statusCode: 500})
|
|
|
|
|
|
|
|
it 'should callback with an error', (done) ->
|
|
|
|
@fs.createReadStream.returns
|
|
|
|
pipe:->
|
|
|
|
on: (type, cb)->
|
2017-05-15 08:46:01 -04:00
|
|
|
if type == "open"
|
2017-03-09 05:11:45 -05:00
|
|
|
cb()
|
|
|
|
@handler.uploadFileFromDisk @project_id, @file_id, @fsPath, (err) =>
|
|
|
|
expect(err).to.exist
|
|
|
|
expect(err).to.be.instanceof Error
|
|
|
|
done()
|
|
|
|
|
2014-02-12 05:23:40 -05:00
|
|
|
describe "deleteFile", ->
|
|
|
|
|
|
|
|
it "should send a delete request to filestore api", (done)->
|
|
|
|
@request.callsArgWith(1, null)
|
|
|
|
@handler.deleteFile @project_id, @file_id, (err)=>
|
|
|
|
assert.equal err, undefined
|
|
|
|
@request.args[0][0].method.should.equal "delete"
|
|
|
|
@request.args[0][0].uri.should.equal @handler._buildUrl()
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "should return the error if there is one", (done)->
|
|
|
|
error = "my error"
|
|
|
|
@request.callsArgWith(1, error)
|
|
|
|
@handler.deleteFile @project_id, @file_id, (err)=>
|
|
|
|
assert.equal err, error
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "builds the correct url", (done)->
|
|
|
|
@request.callsArgWith(1, null)
|
|
|
|
@handler.deleteFile @project_id, @file_id, (err)=>
|
|
|
|
@handler._buildUrl.calledWith(@project_id, @file_id).should.equal true
|
|
|
|
done()
|
|
|
|
|
|
|
|
describe "getFileStream", ->
|
|
|
|
beforeEach ->
|
2016-05-18 04:58:57 -04:00
|
|
|
@query = {}
|
2014-02-12 05:23:40 -05:00
|
|
|
@request.returns(@readStream)
|
|
|
|
|
|
|
|
it "should get the stream with the correct params", (done)->
|
2016-05-18 04:58:57 -04:00
|
|
|
@handler.getFileStream @project_id, @file_id, @query, (err, stream)=>
|
2014-02-12 05:23:40 -05:00
|
|
|
@request.args[0][0].method.should.equal "get"
|
|
|
|
@request.args[0][0].uri.should.equal @handler._buildUrl()
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "should get stream from request", (done)->
|
2016-05-18 04:58:57 -04:00
|
|
|
@handler.getFileStream @project_id, @file_id, @query, (err, stream)=>
|
2014-02-12 05:23:40 -05:00
|
|
|
stream.should.equal @readStream
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "builds the correct url", (done)->
|
2016-05-18 04:58:57 -04:00
|
|
|
@handler.getFileStream @project_id, @file_id, @query, (err, stream)=>
|
2014-02-12 05:23:40 -05:00
|
|
|
@handler._buildUrl.calledWith(@project_id, @file_id).should.equal true
|
|
|
|
done()
|
2016-05-18 04:58:57 -04:00
|
|
|
|
2016-03-23 11:13:32 -04:00
|
|
|
it "should add an error handler", (done) ->
|
2016-05-18 04:58:57 -04:00
|
|
|
@handler.getFileStream @project_id, @file_id, @query, (err, stream)=>
|
2016-03-23 11:13:32 -04:00
|
|
|
stream.on.calledWith("error").should.equal true
|
|
|
|
done()
|
2016-05-18 04:58:57 -04:00
|
|
|
|
|
|
|
describe 'when range is specified in query', ->
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
@query = {'range': '0-10'}
|
|
|
|
|
|
|
|
it 'should add a range header', (done) ->
|
|
|
|
@handler.getFileStream @project_id, @file_id, @query, (err, stream)=>
|
|
|
|
@request.callCount.should.equal 1
|
|
|
|
headers = @request.firstCall.args[0].headers
|
|
|
|
expect(headers).to.have.keys('range')
|
|
|
|
expect(headers['range']).to.equal 'bytes=0-10'
|
|
|
|
done()
|
|
|
|
|
|
|
|
describe 'when range is invalid', ->
|
|
|
|
|
|
|
|
['0-', '-100', 'one-two', 'nonsense'].forEach (r) =>
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
@query = {'range': "#{r}"}
|
|
|
|
|
|
|
|
it "should not add a range header for '#{r}'", (done) ->
|
|
|
|
@handler.getFileStream @project_id, @file_id, @query, (err, stream)=>
|
|
|
|
@request.callCount.should.equal 1
|
|
|
|
headers = @request.firstCall.args[0].headers
|
|
|
|
expect(headers).to.not.have.keys('range')
|
|
|
|
done()
|
2014-02-12 05:23:40 -05:00
|
|
|
|
|
|
|
describe "copyFile", ->
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
@newProject_id = "new project"
|
|
|
|
@newFile_id = "new file id"
|
|
|
|
|
|
|
|
it "should post json", (done)->
|
|
|
|
@request.callsArgWith(1, null)
|
|
|
|
|
|
|
|
@handler.copyFile @project_id, @file_id, @newProject_id, @newFile_id, =>
|
|
|
|
@request.args[0][0].method.should.equal "put"
|
|
|
|
@request.args[0][0].uri.should.equal @handler._buildUrl()
|
|
|
|
@request.args[0][0].json.source.project_id.should.equal @project_id
|
|
|
|
@request.args[0][0].json.source.file_id.should.equal @file_id
|
|
|
|
done()
|
|
|
|
|
|
|
|
it "builds the correct url", (done)->
|
|
|
|
@request.callsArgWith(1, null)
|
|
|
|
@handler.copyFile @project_id, @file_id, @newProject_id, @newFile_id, =>
|
|
|
|
@handler._buildUrl.calledWith(@newProject_id, @newFile_id).should.equal true
|
|
|
|
done()
|
|
|
|
|
|
|
|
|
|
|
|
it "should return the err", (done)->
|
|
|
|
error = "errrror"
|
|
|
|
@request.callsArgWith(1, error)
|
|
|
|
@handler.copyFile @project_id, @file_id, @newProject_id, @newFile_id, (err)=>
|
|
|
|
err.should.equal error
|
|
|
|
done()
|