ShareJsDBTests.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* eslint-disable
  2. no-return-assign,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * DS207: Consider shorter variations of null checks
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const sinon = require('sinon')
  14. const { expect } = require('chai')
  15. const modulePath = '../../../../app/js/ShareJsDB.js'
  16. const SandboxedModule = require('sandboxed-module')
  17. const Errors = require('../../../../app/js/Errors')
  18. describe('ShareJsDB', function () {
  19. beforeEach(function () {
  20. this.doc_id = 'document-id'
  21. this.project_id = 'project-id'
  22. this.doc_key = `${this.project_id}:${this.doc_id}`
  23. this.callback = sinon.stub()
  24. this.ShareJsDB = SandboxedModule.require(modulePath, {
  25. requires: {
  26. './RedisManager': (this.RedisManager = {
  27. getPreviousDocOps: sinon.stub(),
  28. }),
  29. './Errors': Errors,
  30. '@overleaf/metrics': {
  31. inc: sinon.stub(),
  32. histogram: sinon.stub(),
  33. Timer: class Timer {
  34. done() {}
  35. },
  36. },
  37. },
  38. })
  39. this.version = 42
  40. this.lines = ['one', 'two', 'three']
  41. return (this.db = new this.ShareJsDB(
  42. this.project_id,
  43. this.doc_id,
  44. this.lines,
  45. this.version
  46. ))
  47. })
  48. describe('getSnapshot', function () {
  49. describe('successfully', function () {
  50. beforeEach(function () {
  51. return this.db.getSnapshot(this.doc_key, this.callback)
  52. })
  53. it('should return the doc lines', function () {
  54. return this.callback.args[0][1].snapshot.should.equal(
  55. this.lines.join('\n')
  56. )
  57. })
  58. it('should return the doc version', function () {
  59. return this.callback.args[0][1].v.should.equal(this.version)
  60. })
  61. return it('should return the type as text', function () {
  62. return this.callback.args[0][1].type.should.equal('text')
  63. })
  64. })
  65. return describe('when the key does not match', function () {
  66. beforeEach(function () {
  67. return this.db.getSnapshot('bad:key', this.callback)
  68. })
  69. return it('should return the callback with a NotFoundError', function () {
  70. return this.callback
  71. .calledWith(sinon.match.instanceOf(Errors.NotFoundError))
  72. .should.equal(true)
  73. })
  74. })
  75. })
  76. describe('getOps', function () {
  77. describe('with start == end', function () {
  78. beforeEach(function () {
  79. this.start = this.end = 42
  80. return this.db.getOps(this.doc_key, this.start, this.end, this.callback)
  81. })
  82. it('should not talk to redis', function () {
  83. this.RedisManager.getPreviousDocOps.should.not.have.been.called
  84. })
  85. return it('should return an empty array', function () {
  86. return this.callback.calledWith(null, []).should.equal(true)
  87. })
  88. })
  89. describe('with start == redis-version and end unset', function () {
  90. beforeEach(function () {
  91. const start = this.version
  92. const end = null
  93. this.db.getOps(this.doc_key, start, end, this.callback)
  94. })
  95. it('should not talk to redis', function () {
  96. this.RedisManager.getPreviousDocOps.should.not.have.been.called
  97. })
  98. it('should return an empty array', function () {
  99. this.callback.should.have.been.calledWith(null, [])
  100. })
  101. })
  102. describe('with a non empty range', function () {
  103. beforeEach(function () {
  104. this.start = 35
  105. this.end = 42
  106. this.ops = new Array(this.end - this.start)
  107. this.RedisManager.getPreviousDocOps = sinon
  108. .stub()
  109. .callsArgWith(3, null, this.ops)
  110. return this.db.getOps(this.doc_key, this.start, this.end, this.callback)
  111. })
  112. it('should get the range from redis', function () {
  113. return this.RedisManager.getPreviousDocOps
  114. .calledWith(this.doc_id, this.start, this.end - 1)
  115. .should.equal(true)
  116. })
  117. return it('should return the ops', function () {
  118. return this.callback.calledWith(null, this.ops).should.equal(true)
  119. })
  120. })
  121. return describe('with no specified end', function () {
  122. beforeEach(function () {
  123. this.start = 35
  124. this.end = null
  125. this.ops = []
  126. this.RedisManager.getPreviousDocOps = sinon
  127. .stub()
  128. .callsArgWith(3, null, this.ops)
  129. return this.db.getOps(this.doc_key, this.start, this.end, this.callback)
  130. })
  131. return it('should get until the end of the list', function () {
  132. return this.RedisManager.getPreviousDocOps
  133. .calledWith(this.doc_id, this.start, -1)
  134. .should.equal(true)
  135. })
  136. })
  137. })
  138. return describe('writeOps', function () {
  139. return describe('writing an op', function () {
  140. beforeEach(function () {
  141. this.opData = {
  142. op: { p: 20, t: 'foo' },
  143. meta: { source: 'bar' },
  144. v: this.version,
  145. }
  146. return this.db.writeOp(this.doc_key, this.opData, this.callback)
  147. })
  148. it('should write into appliedOps', function () {
  149. return expect(this.db.appliedOps[this.doc_key]).to.deep.equal([
  150. this.opData,
  151. ])
  152. })
  153. return it('should call the callback without an error', function () {
  154. this.callback.called.should.equal(true)
  155. return (this.callback.args[0][0] != null).should.equal(false)
  156. })
  157. })
  158. })
  159. })