getProjectDocsTests.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. const { expect } = require('chai')
  2. const sinon = require('sinon')
  3. const SandboxedModule = require('sandboxed-module')
  4. const Errors = require('../../../../app/js/Errors.js')
  5. const MODULE_PATH = '../../../../app/js/ProjectManager.js'
  6. describe('ProjectManager - getProjectDocsAndFlushIfOld', function () {
  7. beforeEach(function () {
  8. this.RedisManager = {
  9. promises: {
  10. checkOrSetProjectState: sinon.stub().resolves(),
  11. getDocIdsInProject: sinon.stub(),
  12. clearProjectState: sinon.stub().resolves(),
  13. },
  14. }
  15. this.ProjectHistoryRedisManager = {}
  16. this.DocumentManager = {
  17. promises: {
  18. getDocAndFlushIfOldWithLock: sinon.stub(),
  19. },
  20. }
  21. this.HistoryManager = {}
  22. this.Metrics = {
  23. Timer: class Timer {},
  24. }
  25. this.Metrics.Timer.prototype.done = sinon.stub()
  26. this.ProjectManager = SandboxedModule.require(MODULE_PATH, {
  27. requires: {
  28. './RedisManager': this.RedisManager,
  29. './ProjectHistoryRedisManager': this.ProjectHistoryRedisManager,
  30. './DocumentManager': this.DocumentManager,
  31. './HistoryManager': this.HistoryManager,
  32. './Metrics': this.Metrics,
  33. './Errors': Errors,
  34. },
  35. })
  36. this.project_id = 'project-id-123'
  37. this.doc_versions = [111, 222, 333]
  38. })
  39. describe('successfully', function () {
  40. beforeEach(async function () {
  41. this.doc_ids = ['doc-id-1', 'doc-id-2', 'doc-id-3']
  42. this.doc_lines = [
  43. ['aaa', 'aaa'],
  44. ['bbb', 'bbb'],
  45. ['ccc', 'ccc'],
  46. ]
  47. this.docs = [
  48. {
  49. _id: this.doc_ids[0],
  50. lines: this.doc_lines[0],
  51. v: this.doc_versions[0],
  52. },
  53. {
  54. _id: this.doc_ids[1],
  55. lines: this.doc_lines[1],
  56. v: this.doc_versions[1],
  57. },
  58. {
  59. _id: this.doc_ids[2],
  60. lines: this.doc_lines[2],
  61. v: this.doc_versions[2],
  62. },
  63. ]
  64. this.RedisManager.promises.getDocIdsInProject.resolves(this.doc_ids)
  65. this.DocumentManager.promises.getDocAndFlushIfOldWithLock
  66. .withArgs(this.project_id, this.doc_ids[0])
  67. .resolves({ lines: this.doc_lines[0], version: this.doc_versions[0] })
  68. this.DocumentManager.promises.getDocAndFlushIfOldWithLock
  69. .withArgs(this.project_id, this.doc_ids[1])
  70. .resolves({ lines: this.doc_lines[1], version: this.doc_versions[1] })
  71. this.DocumentManager.promises.getDocAndFlushIfOldWithLock
  72. .withArgs(this.project_id, this.doc_ids[2])
  73. .resolves({ lines: this.doc_lines[2], version: this.doc_versions[2] })
  74. this.result =
  75. await this.ProjectManager.promises.getProjectDocsAndFlushIfOld(
  76. this.project_id,
  77. this.projectStateHash,
  78. this.excludeVersions
  79. )
  80. })
  81. it('should check the project state', function () {
  82. this.RedisManager.promises.checkOrSetProjectState.should.have.been.calledWith(
  83. this.project_id,
  84. this.projectStateHash
  85. )
  86. })
  87. it('should get the doc ids in the project', function () {
  88. this.RedisManager.promises.getDocIdsInProject.should.have.been.calledWith(
  89. this.project_id
  90. )
  91. })
  92. it('should return docs', function () {
  93. expect(this.result).to.deep.equal(this.docs)
  94. })
  95. it('should time the execution', function () {
  96. this.Metrics.Timer.prototype.done.called.should.equal(true)
  97. })
  98. })
  99. describe('when the state does not match', function () {
  100. beforeEach(async function () {
  101. this.doc_ids = ['doc-id-1', 'doc-id-2', 'doc-id-3']
  102. this.RedisManager.promises.checkOrSetProjectState.resolves(true)
  103. await expect(
  104. this.ProjectManager.promises.getProjectDocsAndFlushIfOld(
  105. this.project_id,
  106. this.projectStateHash,
  107. this.excludeVersions
  108. )
  109. ).to.be.rejectedWith(Errors.ProjectStateChangedError)
  110. })
  111. it('should check the project state', function () {
  112. this.RedisManager.promises.checkOrSetProjectState.should.have.been.calledWith(
  113. this.project_id,
  114. this.projectStateHash
  115. )
  116. })
  117. it('should time the execution', function () {
  118. this.Metrics.Timer.prototype.done.called.should.equal(true)
  119. })
  120. })
  121. describe('when a doc errors', function () {
  122. it('should call the callback with an error', async function () {
  123. this.doc_ids = ['doc-id-1', 'doc-id-2', 'doc-id-3']
  124. this.error = new Error('oops')
  125. this.RedisManager.promises.getDocIdsInProject.resolves(this.doc_ids)
  126. this.DocumentManager.promises.getDocAndFlushIfOldWithLock
  127. .withArgs(this.project_id, 'doc-id-1')
  128. .resolves({
  129. lines: ['test doc content'],
  130. version: this.doc_versions[1],
  131. })
  132. this.DocumentManager.promises.getDocAndFlushIfOldWithLock
  133. .withArgs(this.project_id, 'doc-id-2')
  134. .rejects(this.error)
  135. await expect(
  136. this.ProjectManager.promises.getProjectDocsAndFlushIfOld(
  137. this.project_id,
  138. this.projectStateHash,
  139. this.excludeVersions
  140. )
  141. ).to.be.rejected
  142. })
  143. })
  144. describe('clearing the project state with clearProjectState', function () {
  145. beforeEach(async function () {
  146. await this.ProjectManager.promises.clearProjectState(this.project_id)
  147. })
  148. it('should clear the project state', function () {
  149. this.RedisManager.promises.clearProjectState.should.have.been.calledWith(
  150. this.project_id
  151. )
  152. })
  153. })
  154. })