ProjectStructureMongoLockTest.js 5.8 KB

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