FileHandlerTests.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. const sinon = require('sinon')
  2. const chai = require('chai')
  3. const { expect } = chai
  4. const modulePath = '../../../app/js/FileHandler.js'
  5. const SandboxedModule = require('sandboxed-module')
  6. describe('FileHandler', function() {
  7. let PersistorManager,
  8. LocalFileWriter,
  9. FileConverter,
  10. KeyBuilder,
  11. ImageOptimiser,
  12. FileHandler,
  13. fs
  14. const settings = {
  15. s3: {
  16. buckets: {
  17. user_files: 'user_files'
  18. }
  19. }
  20. }
  21. const bucket = 'my_bucket'
  22. const key = 'key/here'
  23. const convertedFolderKey = 'convertedFolder'
  24. const sourceStream = 'sourceStream'
  25. const convertedKey = 'convertedKey'
  26. const readStream = {
  27. stream: 'readStream',
  28. on: sinon.stub()
  29. }
  30. beforeEach(function() {
  31. PersistorManager = {
  32. getFileStream: sinon.stub().yields(null, sourceStream),
  33. checkIfFileExists: sinon.stub().yields(),
  34. deleteFile: sinon.stub().yields(),
  35. deleteDirectory: sinon.stub().yields(),
  36. sendStream: sinon.stub().yields(),
  37. insertFile: sinon.stub().yields(),
  38. sendFile: sinon.stub().yields(),
  39. directorySize: sinon.stub().yields()
  40. }
  41. LocalFileWriter = {
  42. writeStream: sinon.stub().yields(),
  43. deleteFile: sinon.stub().yields()
  44. }
  45. FileConverter = {
  46. convert: sinon.stub().yields(),
  47. thumbnail: sinon.stub().yields(),
  48. preview: sinon.stub().yields()
  49. }
  50. KeyBuilder = {
  51. addCachingToKey: sinon.stub().returns(convertedKey),
  52. getConvertedFolderKey: sinon.stub().returns(convertedFolderKey)
  53. }
  54. ImageOptimiser = { compressPng: sinon.stub().yields() }
  55. fs = {
  56. createReadStream: sinon.stub().returns(readStream)
  57. }
  58. FileHandler = SandboxedModule.require(modulePath, {
  59. requires: {
  60. 'settings-sharelatex': settings,
  61. './PersistorManager': PersistorManager,
  62. './LocalFileWriter': LocalFileWriter,
  63. './FileConverter': FileConverter,
  64. './KeyBuilder': KeyBuilder,
  65. './ImageOptimiser': ImageOptimiser,
  66. fs: fs
  67. },
  68. globals: { console }
  69. })
  70. })
  71. describe('insertFile', function() {
  72. const stream = 'stream'
  73. it('should send file to the filestore', function(done) {
  74. FileHandler.insertFile(bucket, key, stream, err => {
  75. expect(err).not.to.exist
  76. expect(PersistorManager.sendStream).to.have.been.calledWith(
  77. bucket,
  78. key,
  79. stream
  80. )
  81. done()
  82. })
  83. })
  84. it('should delete the convertedKey folder', function(done) {
  85. FileHandler.insertFile(bucket, key, stream, err => {
  86. expect(err).not.to.exist
  87. expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
  88. bucket,
  89. convertedFolderKey
  90. )
  91. done()
  92. })
  93. })
  94. })
  95. describe('deleteFile', function() {
  96. it('should tell the filestore manager to delete the file', function(done) {
  97. FileHandler.deleteFile(bucket, key, err => {
  98. expect(err).not.to.exist
  99. expect(PersistorManager.deleteFile).to.have.been.calledWith(bucket, key)
  100. done()
  101. })
  102. })
  103. it('should tell the filestore manager to delete the cached folder', function(done) {
  104. FileHandler.deleteFile(bucket, key, err => {
  105. expect(err).not.to.exist
  106. expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
  107. bucket,
  108. convertedFolderKey
  109. )
  110. done()
  111. })
  112. })
  113. })
  114. describe('getFile', function() {
  115. it('should return the source stream no format or style are defined', function(done) {
  116. FileHandler.getFile(bucket, key, null, (err, stream) => {
  117. expect(err).not.to.exist
  118. expect(stream).to.equal(sourceStream)
  119. done()
  120. })
  121. })
  122. it('should pass options through to PersistorManager', function(done) {
  123. const options = { start: 0, end: 8 }
  124. FileHandler.getFile(bucket, key, options, err => {
  125. expect(err).not.to.exist
  126. expect(PersistorManager.getFileStream).to.have.been.calledWith(
  127. bucket,
  128. key,
  129. options
  130. )
  131. done()
  132. })
  133. })
  134. describe('when a format is defined', function() {
  135. let result
  136. describe('when the file is not cached', function() {
  137. beforeEach(function(done) {
  138. FileHandler.getFile(bucket, key, { format: 'png' }, (err, stream) => {
  139. result = { err, stream }
  140. done()
  141. })
  142. })
  143. it('should convert the file', function() {
  144. expect(FileConverter.convert).to.have.been.called
  145. expect(ImageOptimiser.compressPng).to.have.been.called
  146. })
  147. it('should return the the converted stream', function() {
  148. expect(result.err).not.to.exist
  149. expect(result.stream).to.equal(readStream)
  150. expect(PersistorManager.getFileStream).to.have.been.calledWith(
  151. bucket,
  152. key
  153. )
  154. })
  155. })
  156. describe('when the file is cached', function() {
  157. beforeEach(function(done) {
  158. PersistorManager.checkIfFileExists = sinon.stub().yields(null, true)
  159. FileHandler.getFile(bucket, key, { format: 'png' }, (err, stream) => {
  160. result = { err, stream }
  161. done()
  162. })
  163. })
  164. it('should not convert the file', function() {
  165. expect(FileConverter.convert).not.to.have.been.called
  166. expect(ImageOptimiser.compressPng).not.to.have.been.called
  167. })
  168. it('should return the cached stream', function() {
  169. expect(result.err).not.to.exist
  170. expect(result.stream).to.equal(sourceStream)
  171. expect(PersistorManager.getFileStream).to.have.been.calledWith(
  172. bucket,
  173. convertedKey
  174. )
  175. })
  176. })
  177. })
  178. describe('when a style is defined', function() {
  179. it('generates a thumbnail when requested', function(done) {
  180. FileHandler.getFile(bucket, key, { style: 'thumbnail' }, err => {
  181. expect(err).not.to.exist
  182. expect(FileConverter.thumbnail).to.have.been.called
  183. expect(FileConverter.preview).not.to.have.been.called
  184. done()
  185. })
  186. })
  187. it('generates a preview when requested', function(done) {
  188. FileHandler.getFile(bucket, key, { style: 'preview' }, err => {
  189. expect(err).not.to.exist
  190. expect(FileConverter.thumbnail).not.to.have.been.called
  191. expect(FileConverter.preview).to.have.been.called
  192. done()
  193. })
  194. })
  195. })
  196. })
  197. describe('getDirectorySize', function() {
  198. it('should call the filestore manager to get directory size', function(done) {
  199. FileHandler.getDirectorySize(bucket, key, err => {
  200. expect(err).not.to.exist
  201. expect(PersistorManager.directorySize).to.have.been.calledWith(
  202. bucket,
  203. key
  204. )
  205. done()
  206. })
  207. })
  208. })
  209. })