Browse Source

unit test passing version of FSPersistorManager

Oliver Matthews 12 năm trước cách đây
mục cha
commit
ff96f37b2d

+ 59 - 0
services/filestore/app/coffee/FSPersistorManager.coffee

@@ -0,0 +1,59 @@
+logger = require("logger-sharelatex")
+fs = require("fs")
+LocalFileWriter = require("./LocalFileWriter")
+
+module.exports =
+
+  sendFile: ( location, target, source, callback = (err)->) ->
+    logger.log location:location, target:target, source:source, "sending file"
+    fs.rename source, "#{location}/#{target}", (err) ->
+      logger.err err:err, location:location, target:target, source:source, "Error on put of file"
+      callback err
+
+  sendStream: ( location, target, sourceStream, callback = (err)->) ->
+    logger.log location:location, target:target, source:sourceStream, "sending file stream"
+    sourceStream.on "error", (err)->
+      logger.err location:location, target:target, source:sourceStream, err:err "error on stream to send"
+    LocalFileWriter.writeStream sourceStream, null, (err, fsPath)=>
+      if err?
+        logger.err  location:location, target:target, fsPath:fsPath, err:err, "something went wrong writing stream to disk"
+        return callback err
+      @sendFile location, target, fsPath, callback
+
+  getFileStream: (location, name, callback = (err, res)->)->
+    logger.log location:location, name:name, "getting file"
+    sourceStream = fs.createReadStream "#{location}/#{name}"
+    sourceStream.on 'error', (err) ->
+      logger.err err:err, location:location, name:name, "Error reading from file"
+      callback err
+    callback null,sourceStream
+
+
+  copyFile: (location, fromName, toName, callback = (err)->)->
+    logger.log location:location, fromName:fromName, toName:toName, "copying file"
+    sourceStream = fs.createReadStream "#{location}/#{fromName}"
+    sourceStream.on 'error', (err) ->
+      logger.err err:err, location:location, key:fromName, "Error reading from file"
+      callback err
+    targetStream = fs.createWriteStream "#{location}/#{toName}"
+    targetStream.on 'error', (err) ->
+      logger.err err:err, location:location, key:targetKey, "Error writing to file"
+      callback err
+    sourceStream.pipe targetStream
+
+  deleteFile: (location, name, callback)->
+    logger.log location:location, name:name, "delete file"
+    fs.unlink "#{location}/#{name}", (err) ->
+      logger.err err:err, location:location, name:name, "Error on delete."
+      callback err
+
+  deleteDirectory: (location, name, callback = (err)->)->
+    fs.rmdir "#{location}/#{name}", (err) ->
+      logger.err err:err, location:location, name:name, "Error on rmdir."
+      callback err
+
+  checkIfFileExists:(location, name, callback = (err,exists)->)->
+    logger.log location:location, name:name, "checking if file exists"
+    fs.exists "#{location}/#{name}", (exists) ->
+      logger.log location:location, name:name, exists:exists, "checked if file exists"
+      callback null, exists

+ 156 - 0
services/filestore/test/unit/coffee/FSPersistorManagerTests.coffee

@@ -0,0 +1,156 @@
+assert = require("chai").assert
+sinon = require('sinon')
+chai = require('chai')
+should = chai.should
+expect = chai.expect
+modulePath = "../../../app/js/FSPersistorManager.js"
+SandboxedModule = require('sandboxed-module')
+fs = require("fs")
+
+describe "FSPersistorManagerTests", ->
+
+  beforeEach ->
+    @Fs =
+      rename:sinon.stub()
+      createReadStream:sinon.stub()
+      createWriteStream:sinon.stub()
+      unlink:sinon.stub()
+      rmdir:sinon.stub()
+      exists:sinon.stub()
+    @LocalFileWriter =
+      writeStream: sinon.stub()
+    @requires =
+      "./LocalFileWriter":@LocalFileWriter
+      "fs":@Fs
+      "logger-sharelatex":
+        log:->
+        err:->
+    @location = "/tmp"
+    @name1 = "first_file"
+    @name2 = "second_file"
+    @error = "error_message"
+    @FSPersistorManager = SandboxedModule.require modulePath, requires: @requires
+
+  describe "sendFile", ->
+    it "should put the file", (done) ->
+      @Fs.rename.callsArgWith(2,@error)
+      @FSPersistorManager.sendFile @location, @name1, @name2, (err)=>
+        @Fs.rename.calledWith( @name2, "#{@location}/#{@name1}" ).should.equal true
+        err.should.equal @error
+        done()
+
+  describe "sendStream", ->
+    beforeEach ->
+      @FSPersistorManager.sendFile = sinon.stub().callsArgWith(3)
+      @LocalFileWriter.writeStream.callsArgWith(2, null, @name1)
+      @SourceStream =
+        on:->
+
+    it "should sent stream to LocalFileWriter", (done)->
+      @FSPersistorManager.sendStream @location, @name1, @SourceStream, =>
+        @LocalFileWriter.writeStream.calledWith(@SourceStream).should.equal true
+        done()
+
+    it "should return the error from LocalFileWriter", (done)->
+      @LocalFileWriter.writeStream.callsArgWith(2, @error)
+      @FSPersistorManager.sendStream @location, @name1, @SourceStream, (err)=>
+        err.should.equal @error
+        done()
+
+    it "should send the file to the filestore", (done)->
+      @LocalFileWriter.writeStream.callsArgWith(2)
+      @FSPersistorManager.sendStream @location, @name1, @SourceStream, (err)=>
+        @FSPersistorManager.sendFile.called.should.equal true
+        done()
+
+  describe "getFileStream", ->
+    it "should use correct file location", (done) ->
+      @Fs.createReadStream.returns(
+        on:->
+      )
+      @FSPersistorManager.getFileStream @location, @name1, (err,res)=>
+        @Fs.createReadStream.calledWith("#{@location}/#{@name1}").should.equal.true
+        done()
+
+  describe "copyFile", ->
+    beforeEach ->
+      @ReadStream=
+        on:->
+        pipe:sinon.stub()
+      @WriteStream=
+        on:->
+      @Fs.createReadStream.returns(@ReadStream)
+      @Fs.createWriteStream.returns(@WriteStream)
+
+    it "Should open the source for reading", (done) ->
+      @FSPersistorManager.copyFile @location, @name1, @name2, ->
+      @Fs.createReadStream.calledWith("#{@location}/#{@name1}").should.equal.true
+      done()
+
+    it "Should open the target for writing", (done) ->
+      @FSPersistorManager.copyFile @location, @name1, @name2, ->
+      @Fs.createWriteStream.calledWith("#{@location}/#{@name2}").should.equal.true
+      done()
+
+    it "Should pipe the source to the target", (done) ->
+      @FSPersistorManager.copyFile @location, @name1, @name2, ->
+      @ReadStream.pipe.calledWith(@WriteStream).should.equal.true
+      done()
+
+  describe "deleteFile", ->
+    beforeEach ->
+      @Fs.unlink.callsArgWith(1,@error)
+
+    it "Should call unlink with correct options", (done) ->
+      @FSPersistorManager.deleteFile @location, @name1, (err) =>
+        @Fs.unlink.calledWith("#{@location}/#{@name1}").should.equal.true
+        done()
+
+    it "Should propogate the error", (done) ->
+      @FSPersistorManager.deleteFile @location, @name1, (err) =>
+        err.should.equal @error
+        done()
+
+
+  describe "deleteDirectory", ->
+    beforeEach ->
+      @Fs.rmdir.callsArgWith(1,@error)
+
+    it "Should call rmdir with correct options", (done) ->
+      @FSPersistorManager.deleteDirectory @location, @name1, (err) =>
+        @Fs.rmdir.calledWith("#{@location}/#{@name1}").should.equal.true
+        done()
+
+    it "Should propogate the error", (done) ->
+      @FSPersistorManager.deleteDirectory @location, @name1, (err) =>
+        err.should.equal @error
+        done()
+
+  describe "checkIfFileExists", ->
+    beforeEach ->
+      @Fs.exists.callsArgWith(1,true)
+
+    it "Should call exists with correct options", (done) ->
+      @FSPersistorManager.checkIfFileExists @location, @name1, (exists) =>
+        @Fs.exists.calledWith("#{@location}/#{@name1}").should.equal.true
+        done()
+
+    # fs.exists simply returns false on any error, so...
+    it "should not return an error", (done) ->
+      @FSPersistorManager.checkIfFileExists @location, @name1, (err,exists) =>
+        expect(err).to.be.null
+        done()
+
+    it "Should return true for existing files", (done) ->
+      @Fs.exists.callsArgWith(1,true)
+      @FSPersistorManager.checkIfFileExists @location, @name1, (err,exists) =>
+        exists.should.be.true
+        done()
+
+    it "Should return false for non-existing files", (done) ->
+      @Fs.exists.callsArgWith(1,false)
+      @FSPersistorManager.checkIfFileExists @location, @name1, (err,exists) =>
+        exists.should.be.false
+        done()
+
+