Merge pull request #2496 from overleaf/cmg-clear-leaving-archived

Clear archived/trashed status when leaving a project

GitOrigin-RevId: ca7026bb7848fd7b17c13856bc65b28e577a8236
This commit is contained in:
Jessica Lawshe 2020-01-07 09:24:03 -06:00 committed by Copybot
parent f2943054fb
commit e4cc1b1403
2 changed files with 172 additions and 32 deletions

View file

@ -2,6 +2,7 @@ const { callbackify } = require('util')
const OError = require('@overleaf/o-error')
const { Project } = require('../../models/Project')
const ProjectGetter = require('../Project/ProjectGetter')
const ProjectHelper = require('../Project/ProjectHelper')
const logger = require('logger-sharelatex')
const ContactManager = require('../Contacts/ContactManager')
const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
@ -27,17 +28,47 @@ module.exports = {
async function removeUserFromProject(projectId, userId) {
try {
await Project.update(
{ _id: projectId },
{
$pull: {
collaberator_refs: userId,
readOnly_refs: userId,
tokenAccessReadOnly_refs: userId,
tokenAccessReadAndWrite_refs: userId
const project = await Project.findOne({ _id: projectId }).exec()
// Deal with the old type of boolean value for archived
// In order to clear it
if (typeof project.archived === 'boolean') {
let archived = ProjectHelper.calculateArchivedArray(
project,
userId,
'ARCHIVE'
)
archived = archived.filter(id => id.toString() !== userId.toString())
await Project.update(
{ _id: projectId },
{
$set: { archived: archived },
$pull: {
collaberator_refs: userId,
readOnly_refs: userId,
tokenAccessReadOnly_refs: userId,
tokenAccessReadAndWrite_refs: userId,
trashed: userId
}
}
}
).exec()
)
} else {
await Project.update(
{ _id: projectId },
{
$pull: {
collaberator_refs: userId,
readOnly_refs: userId,
tokenAccessReadOnly_refs: userId,
tokenAccessReadAndWrite_refs: userId,
archived: userId,
trashed: userId
}
}
)
}
} catch (err) {
throw new OError({
message: 'problem removing user from project collaborators',

View file

@ -27,6 +27,16 @@ describe('CollaboratorsHandler', function() {
_id: ObjectId()
}
this.archivedProject = {
_id: ObjectId(),
archived: [ObjectId(this.userId)]
}
this.oldArchivedProject = {
_id: ObjectId(),
archived: true
}
this.UserGetter = {
promises: {
getUser: sinon.stub().resolves(null)
@ -46,6 +56,10 @@ describe('CollaboratorsHandler', function() {
getProject: sinon.stub().resolves(this.project)
}
}
this.ProjectHelper = {
calculateArchivedArray: sinon.stub()
}
this.CollaboratorsGetter = {
promises: {
getProjectsUserIsMemberOf: sinon.stub()
@ -62,6 +76,7 @@ describe('CollaboratorsHandler', function() {
'../../models/Project': { Project },
'../ThirdPartyDataStore/TpdsProjectFlusher': this.TpdsProjectFlusher,
'../Project/ProjectGetter': this.ProjectGetter,
'../Project/ProjectHelper': this.ProjectHelper,
'../Errors/Errors': Errors,
'./CollaboratorsGetter': this.CollaboratorsGetter
}
@ -73,29 +88,115 @@ describe('CollaboratorsHandler', function() {
})
describe('removeUserFromProject', function() {
beforeEach(function() {})
it('should remove the user from mongo', async function() {
this.ProjectMock.expects('update')
.withArgs(
{
describe('a non-archived project', function() {
beforeEach(function() {
this.ProjectMock.expects('findOne')
.withArgs({
_id: this.project._id
},
{
$pull: {
collaberator_refs: this.userId,
readOnly_refs: this.userId,
tokenAccessReadOnly_refs: this.userId,
tokenAccessReadAndWrite_refs: this.userId
})
.chain('exec')
.resolves(this.project)
})
it('should remove the user from mongo', async function() {
this.ProjectMock.expects('update')
.withArgs(
{
_id: this.project._id
},
{
$pull: {
collaberator_refs: this.userId,
readOnly_refs: this.userId,
tokenAccessReadOnly_refs: this.userId,
tokenAccessReadAndWrite_refs: this.userId,
archived: this.userId,
trashed: this.userId
}
}
}
)
.chain('exec')
.resolves()
await this.CollaboratorsHandler.promises.removeUserFromProject(
this.project._id,
this.userId
)
.chain('exec')
.resolves()
await this.CollaboratorsHandler.promises.removeUserFromProject(
this.project._id,
this.userId
)
})
})
describe('an archived project, archived with a boolean value', function() {
beforeEach(function() {
let archived = [ObjectId(this.userId)]
this.ProjectHelper.calculateArchivedArray.returns(archived)
this.ProjectMock.expects('findOne')
.withArgs({
_id: this.oldArchivedProject._id
})
.chain('exec')
.resolves(this.oldArchivedProject)
})
it('should remove the user from mongo', async function() {
this.ProjectMock.expects('update')
.withArgs(
{
_id: this.oldArchivedProject._id
},
{
$set: {
archived: []
},
$pull: {
collaberator_refs: this.userId,
readOnly_refs: this.userId,
tokenAccessReadOnly_refs: this.userId,
tokenAccessReadAndWrite_refs: this.userId,
trashed: this.userId
}
}
)
.resolves()
await this.CollaboratorsHandler.promises.removeUserFromProject(
this.oldArchivedProject._id,
this.userId
)
})
})
describe('an archived project, archived with an array value', function() {
beforeEach(function() {
this.ProjectMock.expects('findOne')
.withArgs({
_id: this.archivedProject._id
})
.chain('exec')
.resolves(this.archivedProject)
})
it('should remove the user from mongo', async function() {
this.ProjectMock.expects('update')
.withArgs(
{
_id: this.archivedProject._id
},
{
$pull: {
collaberator_refs: this.userId,
readOnly_refs: this.userId,
tokenAccessReadOnly_refs: this.userId,
tokenAccessReadAndWrite_refs: this.userId,
archived: this.userId,
trashed: this.userId
}
}
)
.resolves()
await this.CollaboratorsHandler.promises.removeUserFromProject(
this.archivedProject._id,
this.userId
)
})
})
})
@ -240,6 +341,13 @@ describe('CollaboratorsHandler', function() {
'token-read-only-1'
]
for (const projectId of expectedProjects) {
this.ProjectMock.expects('findOne')
.withArgs({
_id: projectId
})
.chain('exec')
.resolves({ _id: projectId })
this.ProjectMock.expects('update')
.withArgs(
{
@ -250,11 +358,12 @@ describe('CollaboratorsHandler', function() {
collaberator_refs: this.userId,
readOnly_refs: this.userId,
tokenAccessReadOnly_refs: this.userId,
tokenAccessReadAndWrite_refs: this.userId
tokenAccessReadAndWrite_refs: this.userId,
archived: this.userId,
trashed: this.userId
}
}
)
.chain('exec')
.resolves()
}
await this.CollaboratorsHandler.promises.removeUserFromAllProjects(