AppendingUpdatesTests.coffee 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. sinon = require "sinon"
  2. chai = require("chai")
  3. chai.should()
  4. expect = chai.expect
  5. mongojs = require "../../../app/js/mongojs"
  6. ObjectId = mongojs.ObjectId
  7. Settings = require "settings-sharelatex"
  8. request = require "request"
  9. rclient = require("redis").createClient() # Only works locally for now
  10. TrackChangesClient = require "./helpers/TrackChangesClient"
  11. describe "Appending doc ops to the history", ->
  12. describe "when the history does not exist yet", ->
  13. before (done) ->
  14. @project_id = ObjectId().toString()
  15. @doc_id = ObjectId().toString()
  16. @user_id = ObjectId().toString()
  17. TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
  18. op: [{ i: "f", p: 3 }]
  19. meta: { ts: Date.now(), user_id: @user_id }
  20. v: 3
  21. }, {
  22. op: [{ i: "o", p: 4 }]
  23. meta: { ts: Date.now(), user_id: @user_id }
  24. v: 4
  25. }, {
  26. op: [{ i: "o", p: 5 }]
  27. meta: { ts: Date.now(), user_id: @user_id }
  28. v: 5
  29. }], (error) =>
  30. throw error if error?
  31. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
  32. throw error if error?
  33. done()
  34. it "should insert the compressed op into mongo", ->
  35. expect(@updates[0].op).to.deep.equal [{
  36. p: 3, i: "foo"
  37. }]
  38. it "should insert the correct version number into mongo", ->
  39. expect(@updates[0].v).to.equal 5
  40. it "should store the doc id", ->
  41. expect(@updates[0].doc_id.toString()).to.equal @doc_id
  42. it "should store the project id", ->
  43. expect(@updates[0].project_id.toString()).to.equal @project_id
  44. it "should clear the doc from the DocsWithHistoryOps set", (done) ->
  45. rclient.sismember "DocsWithHistoryOps:#{@project_id}", @doc_id, (error, member) ->
  46. member.should.equal 0
  47. done()
  48. describe "when the history has already been started", ->
  49. beforeEach (done) ->
  50. @project_id = ObjectId().toString()
  51. @doc_id = ObjectId().toString()
  52. @user_id = ObjectId().toString()
  53. TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
  54. op: [{ i: "f", p: 3 }]
  55. meta: { ts: Date.now(), user_id: @user_id }
  56. v: 3
  57. }, {
  58. op: [{ i: "o", p: 4 }]
  59. meta: { ts: Date.now(), user_id: @user_id }
  60. v: 4
  61. }, {
  62. op: [{ i: "o", p: 5 }]
  63. meta: { ts: Date.now(), user_id: @user_id }
  64. v: 5
  65. }], (error) =>
  66. throw error if error?
  67. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, updates) =>
  68. throw error if error?
  69. done()
  70. describe "when the updates are recent and from the same user", ->
  71. beforeEach (done) ->
  72. TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
  73. op: [{ i: "b", p: 6 }]
  74. meta: { ts: Date.now(), user_id: @user_id }
  75. v: 6
  76. }, {
  77. op: [{ i: "a", p: 7 }]
  78. meta: { ts: Date.now(), user_id: @user_id }
  79. v: 7
  80. }, {
  81. op: [{ i: "r", p: 8 }]
  82. meta: { ts: Date.now(), user_id: @user_id }
  83. v: 8
  84. }], (error) =>
  85. throw error if error?
  86. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
  87. throw error if error?
  88. done()
  89. it "should combine all the updates into one", ->
  90. expect(@updates[0].op).to.deep.equal [{
  91. p: 3, i: "foobar"
  92. }]
  93. it "should insert the correct version number into mongo", ->
  94. expect(@updates[0].v).to.equal 8
  95. describe "when the updates are far apart", ->
  96. beforeEach (done) ->
  97. oneDay = 24 * 60 * 60 * 1000
  98. TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
  99. op: [{ i: "b", p: 6 }]
  100. meta: { ts: Date.now() + oneDay, user_id: @user_id }
  101. v: 6
  102. }, {
  103. op: [{ i: "a", p: 7 }]
  104. meta: { ts: Date.now() + oneDay, user_id: @user_id }
  105. v: 7
  106. }, {
  107. op: [{ i: "r", p: 8 }]
  108. meta: { ts: Date.now() + oneDay, user_id: @user_id }
  109. v: 8
  110. }], (error) =>
  111. throw error if error?
  112. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
  113. throw error if error?
  114. done()
  115. it "should keep the updates separate", ->
  116. expect(@updates[0].op).to.deep.equal [{
  117. p: 3, i: "foo"
  118. }]
  119. expect(@updates[1].op).to.deep.equal [{
  120. p: 6, i: "bar"
  121. }]
  122. describe "when the updates need processing in batches", ->
  123. before (done) ->
  124. @project_id = ObjectId().toString()
  125. @doc_id = ObjectId().toString()
  126. @user_id = ObjectId().toString()
  127. updates = []
  128. @expectedOp = [{ p:0, i: "" }]
  129. for i in [0..250]
  130. updates.push {
  131. op: [{i: "a", p: 0}]
  132. meta: { ts: Date.now(), user_id: @user_id }
  133. v: i
  134. }
  135. @expectedOp[0].i = "a" + @expectedOp[0].i
  136. TrackChangesClient.pushRawUpdates @project_id, @doc_id, updates, (error) =>
  137. throw error if error?
  138. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
  139. throw error if error?
  140. done()
  141. it "should concat the compressed op into mongo", ->
  142. expect(@updates[0].op).to.deep.equal @expectedOp
  143. it "should insert the correct version number into mongo", ->
  144. expect(@updates[0].v).to.equal 250
  145. describe "when there are multiple ops in each update", ->
  146. before (done) ->
  147. @project_id = ObjectId().toString()
  148. @doc_id = ObjectId().toString()
  149. @user_id = ObjectId().toString()
  150. oneDay = 24 * 60 * 60 * 1000
  151. TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
  152. op: [{ i: "f", p: 3 }, { i: "o", p: 4 }, { i: "o", p: 5 }]
  153. meta: { ts: Date.now(), user_id: @user_id }
  154. v: 3
  155. }, {
  156. op: [{ i: "b", p: 6 }, { i: "a", p: 7 }, { i: "r", p: 8 }]
  157. meta: { ts: Date.now() + oneDay, user_id: @user_id }
  158. v: 4
  159. }], (error) =>
  160. throw error if error?
  161. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
  162. throw error if error?
  163. done()
  164. it "should insert the compressed ops into mongo", ->
  165. expect(@updates[0].op).to.deep.equal [{
  166. p: 3, i: "foo"
  167. }]
  168. expect(@updates[1].op).to.deep.equal [{
  169. p: 6, i: "bar"
  170. }]
  171. it "should insert the correct version numbers into mongo", ->
  172. expect(@updates[0].v).to.equal 3
  173. expect(@updates[1].v).to.equal 4
  174. describe "when there is a no-op update", ->
  175. before (done) ->
  176. @project_id = ObjectId().toString()
  177. @doc_id = ObjectId().toString()
  178. @user_id = ObjectId().toString()
  179. oneDay = 24 * 60 * 60 * 1000
  180. TrackChangesClient.pushRawUpdates @project_id, @doc_id, [{
  181. op: []
  182. meta: { ts: Date.now(), user_id: @user_id }
  183. v: 3
  184. }, {
  185. op: [{ i: "foo", p: 3 }]
  186. meta: { ts: Date.now() + oneDay, user_id: @user_id }
  187. v: 4
  188. }], (error) =>
  189. throw error if error?
  190. TrackChangesClient.flushAndGetCompressedUpdates @project_id, @doc_id, (error, @updates) =>
  191. throw error if error?
  192. done()
  193. it "should insert the compressed no-op into mongo", ->
  194. expect(@updates[0].op).to.deep.equal []
  195. it "should insert the compressed next update into mongo", ->
  196. expect(@updates[1].op).to.deep.equal [{
  197. p: 3, i: "foo"
  198. }]
  199. it "should insert the correct version numbers into mongo", ->
  200. expect(@updates[0].v).to.equal 3
  201. expect(@updates[1].v).to.equal 4