2019-05-29 05:21:06 -04:00
|
|
|
/* eslint-disable
|
2020-12-15 05:23:54 -05:00
|
|
|
node/handle-callback-err,
|
2019-05-29 05:21:06 -04:00
|
|
|
max-len,
|
|
|
|
*/
|
|
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
// Fix any style issues and re-enable lint.
|
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* DS101: Remove unnecessary use of Array.from
|
|
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
* DS207: Consider shorter variations of null checks
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
|
|
|
const APP_PATH = '../../../app/src'
|
|
|
|
|
|
|
|
const LockManager = require(`${APP_PATH}/infrastructure/LockManager`)
|
|
|
|
const ProjectCreationHandler = require(`${APP_PATH}/Features/Project/ProjectCreationHandler.js`)
|
|
|
|
const ProjectGetter = require(`${APP_PATH}/Features/Project/ProjectGetter.js`)
|
|
|
|
const ProjectEntityMongoUpdateHandler = require(`${APP_PATH}/Features/Project/ProjectEntityMongoUpdateHandler.js`)
|
|
|
|
const UserCreator = require(`${APP_PATH}/Features/User/UserCreator.js`)
|
|
|
|
|
|
|
|
const { expect } = require('chai')
|
|
|
|
const _ = require('lodash')
|
|
|
|
|
|
|
|
// These tests are neither acceptance tests nor unit tests. It's difficult to
|
|
|
|
// test/verify that our locking is doing what we hope.
|
|
|
|
// These tests call methods in ProjectGetter and ProjectEntityMongoUpdateHandler
|
|
|
|
// to see that they DO NOT work when a lock has been taken.
|
|
|
|
//
|
|
|
|
// It is tested that these methods DO work when the lock has not been taken in
|
|
|
|
// other acceptance tests.
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('ProjectStructureMongoLock', function () {
|
|
|
|
describe('whilst a project lock is taken', function () {
|
2020-07-16 06:10:13 -04:00
|
|
|
let oldMaxLockWaitTime
|
2021-04-14 09:17:21 -04:00
|
|
|
before(function () {
|
2020-07-16 06:10:13 -04:00
|
|
|
oldMaxLockWaitTime = LockManager.MAX_LOCK_WAIT_TIME
|
|
|
|
})
|
2021-04-14 09:17:21 -04:00
|
|
|
after(function () {
|
2020-07-16 06:10:13 -04:00
|
|
|
LockManager.MAX_LOCK_WAIT_TIME = oldMaxLockWaitTime
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
beforeEach(function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
// We want to instantly fail if the lock is taken
|
|
|
|
LockManager.MAX_LOCK_WAIT_TIME = 1
|
|
|
|
this.lockValue = 'lock-value'
|
|
|
|
const userDetails = {
|
|
|
|
holdingAccount: false,
|
2021-04-27 03:52:58 -04:00
|
|
|
email: 'test@example.com',
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2020-09-01 08:37:09 -04:00
|
|
|
UserCreator.createNewUser(userDetails, {}, (err, user) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.user = user
|
|
|
|
if (err != null) {
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
return ProjectCreationHandler.createBlankProject(
|
|
|
|
user._id,
|
|
|
|
'locked-project',
|
|
|
|
(err, project) => {
|
|
|
|
if (err != null) {
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
this.locked_project = project
|
|
|
|
const namespace = ProjectEntityMongoUpdateHandler.LOCK_NAMESPACE
|
|
|
|
this.lock_key = `lock:web:${namespace}:${project._id}`
|
|
|
|
return LockManager._getLock(
|
|
|
|
this.lock_key,
|
|
|
|
namespace,
|
|
|
|
(err, lockValue) => {
|
|
|
|
this.lockValue = lockValue
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
after(function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return LockManager._releaseLock(this.lock_key, this.lockValue, done)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('interacting with the locked project', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
const LOCKING_UPDATE_METHODS = [
|
|
|
|
'addDoc',
|
|
|
|
'addFile',
|
|
|
|
'mkdirp',
|
|
|
|
'moveEntity',
|
|
|
|
'renameEntity',
|
2021-04-27 03:52:58 -04:00
|
|
|
'addFolder',
|
2019-05-29 05:21:06 -04:00
|
|
|
]
|
2021-10-26 04:08:56 -04:00
|
|
|
for (const methodName of Array.from(LOCKING_UPDATE_METHODS)) {
|
2021-04-14 09:17:21 -04:00
|
|
|
it(`cannot call ProjectEntityMongoUpdateHandler.${methodName}`, function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
const method = ProjectEntityMongoUpdateHandler[methodName]
|
|
|
|
const args = _.times(method.length - 2, _.constant(null))
|
2019-08-07 10:04:04 -04:00
|
|
|
return method(this.locked_project._id, args, err => {
|
2019-11-18 09:37:05 -05:00
|
|
|
expect(err).to.be.instanceOf(Error)
|
|
|
|
expect(err).to.have.property('message', 'Timeout')
|
2019-05-29 05:21:06 -04:00
|
|
|
return done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('cannot get the project without a projection', function (done) {
|
2019-08-07 10:04:04 -04:00
|
|
|
return ProjectGetter.getProject(this.locked_project._id, err => {
|
2019-11-18 09:37:05 -05:00
|
|
|
expect(err).to.be.instanceOf(Error)
|
|
|
|
expect(err).to.have.property('message', 'Timeout')
|
2019-05-29 05:21:06 -04:00
|
|
|
return done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('cannot get the project if rootFolder is in the projection', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return ProjectGetter.getProject(
|
|
|
|
this.locked_project._id,
|
|
|
|
{ rootFolder: true },
|
2019-08-07 10:04:04 -04:00
|
|
|
err => {
|
2019-11-18 09:37:05 -05:00
|
|
|
expect(err).to.be.instanceOf(Error)
|
|
|
|
expect(err).to.have.property('message', 'Timeout')
|
2019-05-29 05:21:06 -04:00
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('can get the project if rootFolder is not in the projection', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return ProjectGetter.getProject(
|
|
|
|
this.locked_project._id,
|
|
|
|
{ _id: true },
|
|
|
|
(err, project) => {
|
|
|
|
expect(err).to.equal(null)
|
2020-10-05 04:30:15 -04:00
|
|
|
expect(project).to.have.same.id(this.locked_project)
|
2019-05-29 05:21:06 -04:00
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('interacting with other projects', function () {
|
|
|
|
beforeEach(function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return ProjectCreationHandler.createBlankProject(
|
|
|
|
this.user._id,
|
|
|
|
'unlocked-project',
|
|
|
|
(err, project) => {
|
|
|
|
if (err != null) {
|
|
|
|
throw err
|
|
|
|
}
|
|
|
|
this.unlocked_project = project
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('can add folders to other projects', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return ProjectEntityMongoUpdateHandler.addFolder(
|
|
|
|
this.unlocked_project._id,
|
|
|
|
this.unlocked_project.rootFolder[0]._id,
|
|
|
|
'new folder',
|
2019-08-07 10:04:04 -04:00
|
|
|
(err, folder) => {
|
2019-05-29 05:21:06 -04:00
|
|
|
expect(err).to.equal(null)
|
2019-11-18 09:37:05 -05:00
|
|
|
expect(folder).to.exist
|
2019-05-29 05:21:06 -04:00
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('can get other projects without a projection', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
return ProjectGetter.getProject(
|
|
|
|
this.unlocked_project._id,
|
|
|
|
(err, project) => {
|
|
|
|
expect(err).to.equal(null)
|
2020-10-05 04:30:15 -04:00
|
|
|
expect(project).to.have.same.id(this.unlocked_project)
|
2019-05-29 05:21:06 -04:00
|
|
|
return done()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
|
|
|
})
|