UrlCacheTests.coffee 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. SandboxedModule = require('sandboxed-module')
  2. sinon = require('sinon')
  3. require('chai').should()
  4. modulePath = require('path').join __dirname, '../../../app/js/UrlCache'
  5. EventEmitter = require("events").EventEmitter
  6. describe "UrlCache", ->
  7. beforeEach ->
  8. @callback = sinon.stub()
  9. @url = "www.example.com/file"
  10. @project_id = "project-id-123"
  11. @UrlCache = SandboxedModule.require modulePath, requires:
  12. "./db" : {}
  13. "./UrlFetcher" : @UrlFetcher = {}
  14. "logger-sharelatex": @logger = {log: sinon.stub()}
  15. "settings-sharelatex": @Settings = { path: clsiCacheDir: "/cache/dir" }
  16. "fs": @fs = {}
  17. describe "_doesUrlNeedDownloading", ->
  18. beforeEach ->
  19. @lastModified = new Date()
  20. @lastModifiedRoundedToSeconds = new Date(Math.floor(@lastModified.getTime() / 1000) * 1000)
  21. describe "when URL does not exist in cache", ->
  22. beforeEach ->
  23. @UrlCache._findUrlDetails = sinon.stub().callsArgWith(2, null, null)
  24. @UrlCache._doesUrlNeedDownloading(@project_id, @url, @lastModified, @callback)
  25. it "should return the callback with true", ->
  26. @callback.calledWith(null, true).should.equal true
  27. describe "when URL does exist in cache", ->
  28. beforeEach ->
  29. @urlDetails = {}
  30. @UrlCache._findUrlDetails = sinon.stub().callsArgWith(2, null, @urlDetails)
  31. describe "when the modified date is more recent than the cached modified date", ->
  32. beforeEach ->
  33. @urlDetails.lastModified = new Date(@lastModified.getTime() - 1000)
  34. @UrlCache._doesUrlNeedDownloading(@project_id, @url, @lastModified, @callback)
  35. it "should get the url details", ->
  36. @UrlCache._findUrlDetails
  37. .calledWith(@project_id, @url)
  38. .should.equal true
  39. it "should return the callback with true", ->
  40. @callback.calledWith(null, true).should.equal true
  41. describe "when the cached modified date is more recent than the modified date", ->
  42. beforeEach ->
  43. @urlDetails.lastModified = new Date(@lastModified.getTime() + 1000)
  44. @UrlCache._doesUrlNeedDownloading(@project_id, @url, @lastModified, @callback)
  45. it "should return the callback with false", ->
  46. @callback.calledWith(null, false).should.equal true
  47. describe "when the cached modified date is equal to the modified date", ->
  48. beforeEach ->
  49. @urlDetails.lastModified = @lastModified
  50. @UrlCache._doesUrlNeedDownloading(@project_id, @url, @lastModified, @callback)
  51. it "should return the callback with false", ->
  52. @callback.calledWith(null, false).should.equal true
  53. describe "when the provided modified date does not exist", ->
  54. beforeEach ->
  55. @lastModified = null
  56. @UrlCache._doesUrlNeedDownloading(@project_id, @url, @lastModified, @callback)
  57. it "should return the callback with true", ->
  58. @callback.calledWith(null, true).should.equal true
  59. describe "when the URL does not have a modified date", ->
  60. beforeEach ->
  61. @urlDetails.lastModified = null
  62. @UrlCache._doesUrlNeedDownloading(@project_id, @url, @lastModified, @callback)
  63. it "should return the callback with true", ->
  64. @callback.calledWith(null, true).should.equal true
  65. describe "_ensureUrlIsInCache", ->
  66. beforeEach ->
  67. @UrlFetcher.pipeUrlToFile = sinon.stub().callsArg(2)
  68. @UrlCache._updateOrCreateUrlDetails = sinon.stub().callsArg(3)
  69. describe "when the URL needs updating", ->
  70. beforeEach ->
  71. @UrlCache._doesUrlNeedDownloading = sinon.stub().callsArgWith(3, null, true)
  72. @UrlCache._ensureUrlIsInCache(@project_id, @url, @lastModified, @callback)
  73. it "should check that the url needs downloading", ->
  74. @UrlCache._doesUrlNeedDownloading
  75. .calledWith(@project_id, @url, @lastModifiedRoundedToSeconds)
  76. .should.equal true
  77. it "should download the URL to the cache file", ->
  78. @UrlFetcher.pipeUrlToFile
  79. .calledWith(@url, @UrlCache._cacheFilePathForUrl(@project_id, @url))
  80. .should.equal true
  81. it "should update the database entry", ->
  82. @UrlCache._updateOrCreateUrlDetails
  83. .calledWith(@project_id, @url, @lastModifiedRoundedToSeconds)
  84. .should.equal true
  85. it "should return the callback with the cache file path", ->
  86. @callback
  87. .calledWith(null, @UrlCache._cacheFilePathForUrl(@project_id, @url))
  88. .should.equal true
  89. describe "when the URL does not need updating", ->
  90. beforeEach ->
  91. @UrlCache._doesUrlNeedDownloading = sinon.stub().callsArgWith(3, null, false)
  92. @UrlCache._ensureUrlIsInCache(@project_id, @url, @lastModified, @callback)
  93. it "should not download the URL to the cache file", ->
  94. @UrlFetcher.pipeUrlToFile
  95. .called.should.equal false
  96. it "should return the callback with the cache file path", ->
  97. @callback
  98. .calledWith(null, @UrlCache._cacheFilePathForUrl(@project_id, @url))
  99. .should.equal true
  100. describe "downloadUrlToFile", ->
  101. beforeEach ->
  102. @cachePath = "path/to/cached/url"
  103. @destPath = "path/to/destination"
  104. @UrlCache._copyFile = sinon.stub().callsArg(2)
  105. @UrlCache._ensureUrlIsInCache = sinon.stub().callsArgWith(3, null, @cachePath)
  106. @UrlCache.downloadUrlToFile(@project_id, @url, @destPath, @lastModified, @callback)
  107. it "should ensure the URL is downloaded and updated in the cache", ->
  108. @UrlCache._ensureUrlIsInCache
  109. .calledWith(@project_id, @url, @lastModified)
  110. .should.equal true
  111. it "should copy the file to the new location", ->
  112. @UrlCache._copyFile
  113. .calledWith(@cachePath, @destPath)
  114. .should.equal true
  115. it "should call the callback", ->
  116. @callback.called.should.equal true
  117. describe "_deleteUrlCacheFromDisk", ->
  118. beforeEach ->
  119. @fs.unlink = sinon.stub().callsArg(1)
  120. @UrlCache._deleteUrlCacheFromDisk(@project_id, @url, @callback)
  121. it "should delete the cache file", ->
  122. @fs.unlink
  123. .calledWith(@UrlCache._cacheFilePathForUrl(@project_id, @url))
  124. .should.equal true
  125. it "should call the callback", ->
  126. @callback.called.should.equal true
  127. describe "_clearUrlFromCache", ->
  128. beforeEach ->
  129. @UrlCache._deleteUrlCacheFromDisk = sinon.stub().callsArg(2)
  130. @UrlCache._clearUrlDetails = sinon.stub().callsArg(2)
  131. @UrlCache._clearUrlFromCache @project_id, @url, @callback
  132. it "should delete the file on disk", ->
  133. @UrlCache._deleteUrlCacheFromDisk
  134. .calledWith(@project_id, @url)
  135. .should.equal true
  136. it "should clear the entry in the database", ->
  137. @UrlCache._clearUrlDetails
  138. .calledWith(@project_id, @url)
  139. .should.equal true
  140. it "should call the callback", ->
  141. @callback.called.should.equal true
  142. describe "clearProject", ->
  143. beforeEach ->
  144. @urls = [
  145. "www.example.com/file1"
  146. "www.example.com/file2"
  147. ]
  148. @UrlCache._findAllUrlsInProject = sinon.stub().callsArgWith(1, null, @urls)
  149. @UrlCache._clearUrlFromCache = sinon.stub().callsArg(2)
  150. @UrlCache.clearProject @project_id, @callback
  151. it "should clear the cache for each url in the project", ->
  152. for url in @urls
  153. @UrlCache._clearUrlFromCache
  154. .calledWith(@project_id, url)
  155. .should.equal true
  156. it "should call the callback", ->
  157. @callback.called.should.equal true