ArchiveManagerTests.coffee 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. sinon = require('sinon')
  2. expect = require("chai").expect
  3. chai = require('chai')
  4. should = chai.should()
  5. modulePath = "../../../../app/js/Features/Uploads/ArchiveManager.js"
  6. SandboxedModule = require('sandboxed-module')
  7. events = require "events"
  8. describe "ArchiveManager", ->
  9. beforeEach ->
  10. @logger =
  11. error: sinon.stub()
  12. err:->
  13. log: sinon.stub()
  14. @process = new events.EventEmitter
  15. @process.stdout = new events.EventEmitter
  16. @process.stderr = new events.EventEmitter
  17. @child =
  18. spawn: sinon.stub().returns(@process)
  19. @metrics =
  20. Timer: class Timer
  21. done: sinon.stub()
  22. @ArchiveManager = SandboxedModule.require modulePath, requires:
  23. "child_process": @child
  24. "logger-sharelatex": @logger
  25. "../../infrastructure/Metrics": @metrics
  26. "fs": @fs = {}
  27. describe "extractZipArchive", ->
  28. beforeEach ->
  29. @source = "/path/to/zip/source.zip"
  30. @destination = "/path/to/zip/destination"
  31. @callback = sinon.stub()
  32. @ArchiveManager._isZipTooLarge = sinon.stub().callsArgWith(1, null, false)
  33. describe "successfully", ->
  34. beforeEach (done) ->
  35. @ArchiveManager.extractZipArchive @source, @destination, done
  36. @process.emit "close"
  37. it "should run unzip", ->
  38. @child.spawn.calledWithExactly("unzip", [@source, "-d", @destination]).should.equal true
  39. it "should time the unzip", ->
  40. @metrics.Timer::done.called.should.equal true
  41. it "should log the unzip", ->
  42. @logger.log.calledWith(sinon.match.any, "unzipping file").should.equal true
  43. describe "with an error on stderr", ->
  44. beforeEach (done) ->
  45. @ArchiveManager.extractZipArchive @source, @destination, (error) =>
  46. @callback(error)
  47. done()
  48. @process.stderr.emit "data", "Something went wrong"
  49. @process.emit "close"
  50. it "should return the callback with an error", ->
  51. @callback.calledWithExactly(new Error("Something went wrong")).should.equal true
  52. it "should log out the error", ->
  53. @logger.error.called.should.equal true
  54. describe "with a zip that is too large", ->
  55. beforeEach (done) ->
  56. @ArchiveManager._isZipTooLarge = sinon.stub().callsArgWith(1, null, true)
  57. @ArchiveManager.extractZipArchive @source, @destination, (error) =>
  58. @callback(error)
  59. done()
  60. it "should return the callback with an error", ->
  61. @callback.calledWithExactly(new Error("zip_too_large")).should.equal true
  62. it "should not call spawn", ->
  63. @child.spawn.called.should.equal false
  64. describe "with an error on the process", ->
  65. beforeEach (done) ->
  66. @ArchiveManager.extractZipArchive @source, @destination, (error) =>
  67. @callback(error)
  68. done()
  69. @process.emit "error", new Error("Something went wrong")
  70. it "should return the callback with an error", ->
  71. @callback.calledWithExactly(new Error("Something went wrong")).should.equal true
  72. it "should log out the error", ->
  73. @logger.error.called.should.equal true
  74. describe "_isZipTooLarge", ->
  75. beforeEach ->
  76. @output = (totalSize)->" Length Date Time Name \n-------- ---- ---- ---- \n241 03-12-16 12:20 main.tex \n108801 03-12-16 12:20 ddd/x1J5kHh.jpg \n-------- ------- \n#{totalSize} 2 files\n"
  77. it "should return false with small output", (done)->
  78. @ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
  79. isTooLarge.should.equal false
  80. done()
  81. @process.stdout.emit "data", @output("109042")
  82. @process.emit "close"
  83. it "should return true with large bytes", (done)->
  84. @ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
  85. isTooLarge.should.equal true
  86. done()
  87. @process.stdout.emit "data", @output("1090000000000000042")
  88. @process.emit "close"
  89. it "should return error on no data", (done)->
  90. @ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
  91. expect(error).to.exist
  92. done()
  93. @process.stdout.emit "data", ""
  94. @process.emit "close"
  95. it "should return error if it didn't get a number", (done)->
  96. @ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
  97. expect(error).to.exist
  98. done()
  99. @process.stdout.emit "data", @output("total_size_string")
  100. @process.emit "close"
  101. it "should return error if the is only a bit of data", (done)->
  102. @ArchiveManager._isZipTooLarge @source, (error, isTooLarge) =>
  103. expect(error).to.exist
  104. done()
  105. @process.stdout.emit "data", " Length Date Time Name \n--------"
  106. @process.emit "close"
  107. describe "findTopLevelDirectory", ->
  108. beforeEach ->
  109. @fs.readdir = sinon.stub()
  110. @fs.stat = sinon.stub()
  111. @directory = "test/directory"
  112. describe "with multiple files", ->
  113. beforeEach ->
  114. @fs.readdir.callsArgWith(1, null, ["multiple", "files"])
  115. @ArchiveManager.findTopLevelDirectory(@directory, @callback)
  116. it "should find the files in the directory", ->
  117. @fs.readdir
  118. .calledWith(@directory)
  119. .should.equal true
  120. it "should return the original directory", ->
  121. @callback
  122. .calledWith(null, @directory)
  123. .should.equal true
  124. describe "with a single file (not folder)", ->
  125. beforeEach ->
  126. @fs.readdir.callsArgWith(1, null, ["foo.tex"])
  127. @fs.stat.callsArgWith(1, null, { isDirectory: () -> false })
  128. @ArchiveManager.findTopLevelDirectory(@directory, @callback)
  129. it "should check if the file is a directory", ->
  130. @fs.stat
  131. .calledWith(@directory + "/foo.tex")
  132. .should.equal true
  133. it "should return the original directory", ->
  134. @callback
  135. .calledWith(null, @directory)
  136. .should.equal true
  137. describe "with a single top-level folder", ->
  138. beforeEach ->
  139. @fs.readdir.callsArgWith(1, null, ["folder"])
  140. @fs.stat.callsArgWith(1, null, { isDirectory: () -> true })
  141. @ArchiveManager.findTopLevelDirectory(@directory, @callback)
  142. it "should check if the file is a directory", ->
  143. @fs.stat
  144. .calledWith(@directory + "/folder")
  145. .should.equal true
  146. it "should return the child directory", ->
  147. @callback
  148. .calledWith(null, @directory + "/folder")
  149. .should.equal true