ProjectStructureMongoLockTest.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* eslint-disable
  2. 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', () =>
  30. describe('whilst a project lock is taken', function() {
  31. before(function(done) {
  32. // We want to instantly fail if the lock is taken
  33. LockManager.MAX_LOCK_WAIT_TIME = 1
  34. this.lockValue = 'lock-value'
  35. const userDetails = {
  36. holdingAccount: false,
  37. email: 'test@example.com'
  38. }
  39. UserCreator.createNewUser(userDetails, (err, user) => {
  40. this.user = user
  41. if (err != null) {
  42. throw err
  43. }
  44. return ProjectCreationHandler.createBlankProject(
  45. user._id,
  46. 'locked-project',
  47. (err, project) => {
  48. if (err != null) {
  49. throw err
  50. }
  51. this.locked_project = project
  52. const namespace = ProjectEntityMongoUpdateHandler.LOCK_NAMESPACE
  53. this.lock_key = `lock:web:${namespace}:${project._id}`
  54. return LockManager._getLock(
  55. this.lock_key,
  56. namespace,
  57. (err, lockValue) => {
  58. this.lockValue = lockValue
  59. return done()
  60. }
  61. )
  62. }
  63. )
  64. })
  65. })
  66. after(function(done) {
  67. return LockManager._releaseLock(this.lock_key, this.lockValue, done)
  68. })
  69. describe('interacting with the locked project', function() {
  70. const LOCKING_UPDATE_METHODS = [
  71. 'addDoc',
  72. 'addFile',
  73. 'mkdirp',
  74. 'moveEntity',
  75. 'renameEntity',
  76. 'addFolder'
  77. ]
  78. for (var methodName of Array.from(LOCKING_UPDATE_METHODS)) {
  79. it(`cannot call ProjectEntityMongoUpdateHandler.${methodName}`, function(done) {
  80. const method = ProjectEntityMongoUpdateHandler[methodName]
  81. const args = _.times(method.length - 2, _.constant(null))
  82. return method(this.locked_project._id, args, function(err) {
  83. expect(err).to.deep.equal(new Error('Timeout'))
  84. return done()
  85. })
  86. })
  87. }
  88. it('cannot get the project without a projection', function(done) {
  89. return ProjectGetter.getProject(this.locked_project._id, function(err) {
  90. expect(err).to.deep.equal(new Error('Timeout'))
  91. return done()
  92. })
  93. })
  94. it('cannot get the project if rootFolder is in the projection', function(done) {
  95. return ProjectGetter.getProject(
  96. this.locked_project._id,
  97. { rootFolder: true },
  98. function(err) {
  99. expect(err).to.deep.equal(new Error('Timeout'))
  100. return done()
  101. }
  102. )
  103. })
  104. return it('can get the project if rootFolder is not in the projection', function(done) {
  105. return ProjectGetter.getProject(
  106. this.locked_project._id,
  107. { _id: true },
  108. (err, project) => {
  109. expect(err).to.equal(null)
  110. expect(project._id).to.deep.equal(this.locked_project._id)
  111. return done()
  112. }
  113. )
  114. })
  115. })
  116. return describe('interacting with other projects', function() {
  117. before(function(done) {
  118. return ProjectCreationHandler.createBlankProject(
  119. this.user._id,
  120. 'unlocked-project',
  121. (err, project) => {
  122. if (err != null) {
  123. throw err
  124. }
  125. this.unlocked_project = project
  126. return done()
  127. }
  128. )
  129. })
  130. it('can add folders to other projects', function(done) {
  131. return ProjectEntityMongoUpdateHandler.addFolder(
  132. this.unlocked_project._id,
  133. this.unlocked_project.rootFolder[0]._id,
  134. 'new folder',
  135. function(err, folder) {
  136. expect(err).to.equal(null)
  137. expect(folder).to.be.defined
  138. return done()
  139. }
  140. )
  141. })
  142. return it('can get other projects without a projection', function(done) {
  143. return ProjectGetter.getProject(
  144. this.unlocked_project._id,
  145. (err, project) => {
  146. expect(err).to.equal(null)
  147. expect(project._id).to.deep.equal(this.unlocked_project._id)
  148. return done()
  149. }
  150. )
  151. })
  152. })
  153. }))