AutomaticSnapshotManagerTests.coffee 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. should = require('chai').should()
  2. sinon = require('sinon')
  3. SandboxedModule = require('sandboxed-module')
  4. assert = require('assert')
  5. path = require("path")
  6. modulePath = path.join __dirname, '../../../../app/js/Features/Versioning/AutomaticSnapshotManager'
  7. tk = require 'timekeeper'
  8. Settings = require "settings-sharelatex"
  9. describe 'AutomaticSnapshotManager', ->
  10. beforeEach ->
  11. tk.freeze(Date.now())
  12. @project_id = "project-id-1234"
  13. @callback = sinon.stub()
  14. @rclient =
  15. auth:->
  16. del: sinon.stub().callsArg(2)
  17. srem: sinon.stub().callsArg(2)
  18. sadd: sinon.stub().callsArg(2)
  19. set: sinon.stub().callsArg(2)
  20. @VersioningApiHandler =
  21. takeSnapshot: sinon.stub().callsArg(2)
  22. @AutomaticSnapshotManager = SandboxedModule.require modulePath,
  23. requires:
  24. 'redis' : createClient: () => @rclient
  25. '../../Features/Versioning/VersioningApiHandler' : @VersioningApiHandler
  26. globals:
  27. Date: Date
  28. afterEach -> tk.reset()
  29. describe "markProjectAsUpdated", ->
  30. beforeEach ->
  31. @AutomaticSnapshotManager.markProjectAsUpdated(@project_id, @callback)
  32. it "should update the project's last updated date", ->
  33. @rclient.set.calledWith("project_last_updated:#{@project_id}", Date.now())
  34. it "should add the project to the set needing processing", ->
  35. @rclient.sadd.calledWith("projects_to_snapshot", @project_id)
  36. it "should call the callback", ->
  37. @callback.calledWith().should.equal true
  38. describe "takeSnapshotIfRequired", ->
  39. beforeEach ->
  40. @lastUpdated = Date.now() - Settings.automaticSnapshots.waitTimeAfterLastEdit + 1
  41. @lastSnapshot = Date.now() - Settings.automaticSnapshots.maxTimeBetweenSnapshots + 1
  42. @rclient.get = (key, callback) =>
  43. if key == "project_last_updated:#{@project_id}"
  44. callback(null, @lastUpdated)
  45. else if key == "project_last_snapshot:#{@project_id}"
  46. callback(null, @lastSnapshot)
  47. else
  48. throw new Error("unexpected key: #{key}")
  49. describe "when updated longer than waitTimeAfterLastEdit ago", ->
  50. beforeEach ->
  51. @lastUpdated = Date.now() - Settings.automaticSnapshots.waitTimeAfterLastEdit - 1
  52. @AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
  53. it "should take a snapshot", ->
  54. @VersioningApiHandler.takeSnapshot.calledWith(@project_id, "Automatic snapshot")
  55. .should.equal true
  56. it "should return the callback", ->
  57. @callback.calledWithExactly().should.equal true
  58. describe "when last snapshot longer then maxTimeBetweenSnapshots ago", ->
  59. beforeEach ->
  60. @lastSnapshot = Date.now() - Settings.automaticSnapshots.maxTimeBetweenSnapshots - 1
  61. @AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
  62. it "should take a snapshot", ->
  63. @VersioningApiHandler.takeSnapshot.calledWith(@project_id, "Automatic snapshot")
  64. .should.equal true
  65. it "should return the callback", ->
  66. @callback.calledWithExactly().should.equal true
  67. describe "when no snapshot has been taken", ->
  68. beforeEach ->
  69. @lastSnapshot = null
  70. @AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
  71. it "should take a snapshot", ->
  72. @VersioningApiHandler.takeSnapshot.calledWith(@project_id, "Automatic snapshot")
  73. .should.equal true
  74. it "should return the callback", ->
  75. @callback.calledWithExactly().should.equal true
  76. describe "when no snapshot is needed", ->
  77. beforeEach ->
  78. @AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
  79. it "should take a snapshot", ->
  80. @VersioningApiHandler.takeSnapshot.called.should.equal false
  81. it "should return the callback", ->
  82. @callback.calledWithExactly().should.equal true
  83. describe "takeAutomaticSnapshots", ->
  84. beforeEach ->
  85. @project_ids = ["project-1", "project-2", "project-3"]
  86. @rclient.smembers = (key, callback) =>
  87. if key == "projects_to_snapshot"
  88. callback(null, @project_ids)
  89. else
  90. throw new Error("unexpected key: #{key}")
  91. sinon.stub(@AutomaticSnapshotManager, "takeSnapshotIfRequired")
  92. .callsArgWith(1)
  93. @AutomaticSnapshotManager.takeAutomaticSnapshots(@callback)
  94. afterEach ->
  95. @AutomaticSnapshotManager.takeSnapshotIfRequired.restore()
  96. it "should call takeSnapshotIfRequired for each project id", ->
  97. for project_id in @project_ids
  98. @AutomaticSnapshotManager.takeSnapshotIfRequired.calledWith(project_id)
  99. .should.equal true
  100. it "should call the callback", ->
  101. @callback.calledWith(null).should.equal true
  102. describe "removing project from marked set", ->
  103. beforeEach ->
  104. @AutomaticSnapshotManager.markProjectAsUpdated @project_id, =>
  105. @AutomaticSnapshotManager.unmarkProjectAsUpdated @project_id, @callback
  106. it "should update the project's last updated date", ->
  107. @rclient.del.calledWith("project_last_updated:#{@project_id}", Date.now())
  108. it "should add the project to the set needing processing", ->
  109. @rclient.srem.calledWith("projects_to_snapshot", @project_id)
  110. it "should call the callback", ->
  111. @callback.calledWith().should.equal true