ResourceWriterTests.coffee 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. SandboxedModule = require('sandboxed-module')
  2. sinon = require('sinon')
  3. require('chai').should()
  4. modulePath = require('path').join __dirname, '../../../app/js/ResourceWriter'
  5. path = require "path"
  6. describe "ResourceWriter", ->
  7. beforeEach ->
  8. @ResourceWriter = SandboxedModule.require modulePath, requires:
  9. "fs": @fs = {}
  10. "wrench": @wrench = {}
  11. "./UrlCache" : @UrlCache = {}
  12. "mkdirp" : @mkdirp = sinon.stub().callsArg(1)
  13. "./OutputFileFinder": @OutputFileFinder = {}
  14. "./Metrics": @Metrics =
  15. Timer: class Timer
  16. done: sinon.stub()
  17. @project_id = "project-id-123"
  18. @basePath = "/path/to/write/files/to"
  19. @callback = sinon.stub()
  20. describe "syncResourcesToDisk", ->
  21. beforeEach ->
  22. @resources = [
  23. "resource-1-mock"
  24. "resource-2-mock"
  25. "resource-3-mock"
  26. ]
  27. @ResourceWriter._writeResourceToDisk = sinon.stub().callsArg(3)
  28. @ResourceWriter._removeExtraneousFiles = sinon.stub().callsArg(2)
  29. @ResourceWriter.syncResourcesToDisk(@project_id, @resources, @basePath, @callback)
  30. it "should remove old files", ->
  31. @ResourceWriter._removeExtraneousFiles
  32. .calledWith(@resources, @basePath)
  33. .should.equal true
  34. it "should write each resource to disk", ->
  35. for resource in @resources
  36. @ResourceWriter._writeResourceToDisk
  37. .calledWith(@project_id, resource, @basePath)
  38. .should.equal true
  39. it "should call the callback", ->
  40. @callback.called.should.equal true
  41. describe "_removeExtraneousFiles", ->
  42. beforeEach ->
  43. @output_files = [{
  44. path: "output.pdf"
  45. type: "pdf"
  46. }, {
  47. path: "extra/file.tex"
  48. type: "tex"
  49. }, {
  50. path: "extra.aux"
  51. type: "aux"
  52. }]
  53. @resources = "mock-resources"
  54. @OutputFileFinder.findOutputFiles = sinon.stub().callsArgWith(2, null, @output_files)
  55. @ResourceWriter._deleteFileIfNotDirectory = sinon.stub().callsArg(1)
  56. @ResourceWriter._removeExtraneousFiles(@resources, @basePath, @callback)
  57. it "should find the existing output files", ->
  58. @OutputFileFinder.findOutputFiles
  59. .calledWith(@resources, @basePath)
  60. .should.equal true
  61. it "should delete the output files", ->
  62. @ResourceWriter._deleteFileIfNotDirectory
  63. .calledWith(path.join(@basePath, "output.pdf"))
  64. .should.equal true
  65. it "should delete the extra files", ->
  66. @ResourceWriter._deleteFileIfNotDirectory
  67. .calledWith(path.join(@basePath, "extra/file.tex"))
  68. .should.equal true
  69. it "should not delete the extra aux files", ->
  70. @ResourceWriter._deleteFileIfNotDirectory
  71. .calledWith(path.join(@basePath, "extra.aux"))
  72. .should.equal false
  73. it "should call the callback", ->
  74. @callback.called.should.equal true
  75. it "should time the request", ->
  76. @Metrics.Timer::done.called.should.equal true
  77. describe "_writeResourceToDisk", ->
  78. describe "with a url based resource", ->
  79. beforeEach ->
  80. @resource =
  81. path: "main.tex"
  82. url: "http://www.example.com/main.tex"
  83. modified: Date.now()
  84. @UrlCache.downloadUrlToFile = sinon.stub().callsArg(4)
  85. @ResourceWriter._writeResourceToDisk(@project_id, @resource, @basePath, @callback)
  86. it "should ensure the directory exists", ->
  87. @mkdirp
  88. .calledWith(path.dirname(path.join(@basePath, @resource.path)))
  89. .should.equal true
  90. it "should write the URL from the cache", ->
  91. @UrlCache.downloadUrlToFile
  92. .calledWith(@project_id, @resource.url, path.join(@basePath, @resource.path), @resource.modified)
  93. .should.equal true
  94. it "should call the callback", ->
  95. @callback.called.should.equal true
  96. describe "with a content based resource", ->
  97. beforeEach ->
  98. @resource =
  99. path: "main.tex"
  100. content: "Hello world"
  101. @fs.writeFile = sinon.stub().callsArg(2)
  102. @ResourceWriter._writeResourceToDisk(@project_id, @resource, @basePath, @callback)
  103. it "should ensure the directory exists", ->
  104. @mkdirp
  105. .calledWith(path.dirname(path.join(@basePath, @resource.path)))
  106. .should.equal true
  107. it "should write the contents to disk", ->
  108. @fs.writeFile
  109. .calledWith(path.join(@basePath, @resource.path), @resource.content)
  110. .should.equal true
  111. it "should call the callback", ->
  112. @callback.called.should.equal true
  113. describe "with a file path that breaks out of the root folder", ->
  114. beforeEach ->
  115. @resource =
  116. path: "../../main.tex"
  117. content: "Hello world"
  118. @fs.writeFile = sinon.stub().callsArg(2)
  119. @ResourceWriter._writeResourceToDisk(@project_id, @resource, @basePath, @callback)
  120. it "should not write to disk", ->
  121. @fs.writeFile.called.should.equal false
  122. it "should return an error", ->
  123. @callback
  124. .calledWith(new Error("resource path is outside root directory"))
  125. .should.equal true