ProjectStructureMongoLockTest.mjs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* eslint-disable
  2. n/handle-callback-err,
  3. max-len,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS101: Remove unnecessary use of Array.from
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * DS207: Consider shorter variations of null checks
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. import LockManager from '../../../app/src/infrastructure/LockManager.mjs'
  15. import ProjectCreationHandler from '../../../app/src/Features/Project/ProjectCreationHandler.mjs'
  16. import ProjectGetter from '../../../app/src/Features/Project/ProjectGetter.mjs'
  17. import ProjectEntityMongoUpdateHandler from '../../../app/src/Features/Project/ProjectEntityMongoUpdateHandler.mjs'
  18. import UserCreator from '../../../app/src/Features/User/UserCreator.mjs'
  19. import { expect } from 'chai'
  20. import _ from 'lodash'
  21. // These tests are neither acceptance tests nor unit tests. It's difficult to
  22. // test/verify that our locking is doing what we hope.
  23. // These tests call methods in ProjectGetter and ProjectEntityMongoUpdateHandler
  24. // to see that they DO NOT work when a lock has been taken.
  25. //
  26. // It is tested that these methods DO work when the lock has not been taken in
  27. // other acceptance tests.
  28. describe('ProjectStructureMongoLock', function () {
  29. describe('whilst a project lock is taken', function () {
  30. let oldMaxLockWaitTime
  31. before(function () {
  32. oldMaxLockWaitTime = LockManager.MAX_LOCK_WAIT_TIME
  33. })
  34. after(function () {
  35. LockManager.MAX_LOCK_WAIT_TIME = oldMaxLockWaitTime
  36. })
  37. beforeEach(function (done) {
  38. // We want to instantly fail if the lock is taken
  39. LockManager.MAX_LOCK_WAIT_TIME = 1
  40. this.lockValue = 'lock-value'
  41. const userDetails = {
  42. holdingAccount: false,
  43. email: 'test@example.com',
  44. }
  45. UserCreator.createNewUser(userDetails, {}, (err, user) => {
  46. this.user = user
  47. if (err != null) {
  48. throw err
  49. }
  50. return ProjectCreationHandler.createBlankProject(
  51. user._id,
  52. 'locked-project',
  53. (err, project) => {
  54. if (err != null) {
  55. throw err
  56. }
  57. this.locked_project = project
  58. const namespace = ProjectEntityMongoUpdateHandler.LOCK_NAMESPACE
  59. this.lock_key = `lock:web:${namespace}:${project._id}`
  60. return LockManager._getLock(
  61. this.lock_key,
  62. namespace,
  63. (err, lockValue) => {
  64. this.lockValue = lockValue
  65. return done()
  66. }
  67. )
  68. }
  69. )
  70. })
  71. })
  72. afterEach(function (done) {
  73. return LockManager._releaseLock(this.lock_key, this.lockValue, done)
  74. })
  75. describe('interacting with the locked project', function () {
  76. const LOCKING_UPDATE_METHODS = [
  77. 'addDoc',
  78. 'addFile',
  79. 'mkdirp',
  80. 'moveEntity',
  81. 'renameEntity',
  82. 'addFolder',
  83. ]
  84. for (const methodName of Array.from(LOCKING_UPDATE_METHODS)) {
  85. it(`cannot call ProjectEntityMongoUpdateHandler.${methodName}`, function (done) {
  86. const method = ProjectEntityMongoUpdateHandler[methodName]
  87. const args = _.times(method.length - 2, _.constant(null))
  88. return method(this.locked_project._id, args, err => {
  89. expect(err).to.be.instanceOf(Error)
  90. expect(err).to.have.property('message', 'Timeout')
  91. return done()
  92. })
  93. })
  94. }
  95. it('cannot get the project without a projection', function (done) {
  96. return ProjectGetter.getProject(this.locked_project._id, err => {
  97. expect(err).to.be.instanceOf(Error)
  98. expect(err).to.have.property('message', 'Timeout')
  99. return done()
  100. })
  101. })
  102. it('cannot get the project if rootFolder is in the projection', function (done) {
  103. return ProjectGetter.getProject(
  104. this.locked_project._id,
  105. { rootFolder: true },
  106. err => {
  107. expect(err).to.be.instanceOf(Error)
  108. expect(err).to.have.property('message', 'Timeout')
  109. return done()
  110. }
  111. )
  112. })
  113. it('can get the project if rootFolder is not in the projection', function (done) {
  114. return ProjectGetter.getProject(
  115. this.locked_project._id,
  116. { _id: true },
  117. (err, project) => {
  118. expect(err).to.equal(null)
  119. expect(project._id).to.deep.equal(this.locked_project._id)
  120. return done()
  121. }
  122. )
  123. })
  124. })
  125. describe('interacting with other projects', function () {
  126. beforeEach(function (done) {
  127. return ProjectCreationHandler.createBlankProject(
  128. this.user._id,
  129. 'unlocked-project',
  130. (err, project) => {
  131. if (err != null) {
  132. throw err
  133. }
  134. this.unlocked_project = project
  135. return done()
  136. }
  137. )
  138. })
  139. it('can add folders to other projects', function (done) {
  140. return ProjectEntityMongoUpdateHandler.addFolder(
  141. this.unlocked_project._id,
  142. this.unlocked_project.rootFolder[0]._id,
  143. 'new folder',
  144. (err, folder) => {
  145. expect(err).to.equal(null)
  146. expect(folder).to.exist
  147. return done()
  148. }
  149. )
  150. })
  151. it('can get other projects without a projection', function (done) {
  152. return ProjectGetter.getProject(
  153. this.unlocked_project._id,
  154. (err, project) => {
  155. expect(err).to.equal(null)
  156. expect(project._id).to.deep.equal(this.unlocked_project._id)
  157. return done()
  158. }
  159. )
  160. })
  161. })
  162. })
  163. })