mirror of
https://github.com/overleaf/overleaf.git
synced 2025-02-18 16:33:00 +00:00
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:
parent
f2943054fb
commit
e4cc1b1403
2 changed files with 172 additions and 32 deletions
|
@ -2,6 +2,7 @@ const { callbackify } = require('util')
|
||||||
const OError = require('@overleaf/o-error')
|
const OError = require('@overleaf/o-error')
|
||||||
const { Project } = require('../../models/Project')
|
const { Project } = require('../../models/Project')
|
||||||
const ProjectGetter = require('../Project/ProjectGetter')
|
const ProjectGetter = require('../Project/ProjectGetter')
|
||||||
|
const ProjectHelper = require('../Project/ProjectHelper')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const ContactManager = require('../Contacts/ContactManager')
|
const ContactManager = require('../Contacts/ContactManager')
|
||||||
const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
|
const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
|
||||||
|
@ -27,17 +28,47 @@ module.exports = {
|
||||||
|
|
||||||
async function removeUserFromProject(projectId, userId) {
|
async function removeUserFromProject(projectId, userId) {
|
||||||
try {
|
try {
|
||||||
await Project.update(
|
const project = await Project.findOne({ _id: projectId }).exec()
|
||||||
{ _id: projectId },
|
|
||||||
{
|
// Deal with the old type of boolean value for archived
|
||||||
$pull: {
|
// In order to clear it
|
||||||
collaberator_refs: userId,
|
if (typeof project.archived === 'boolean') {
|
||||||
readOnly_refs: userId,
|
let archived = ProjectHelper.calculateArchivedArray(
|
||||||
tokenAccessReadOnly_refs: userId,
|
project,
|
||||||
tokenAccessReadAndWrite_refs: userId
|
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) {
|
} catch (err) {
|
||||||
throw new OError({
|
throw new OError({
|
||||||
message: 'problem removing user from project collaborators',
|
message: 'problem removing user from project collaborators',
|
||||||
|
|
|
@ -27,6 +27,16 @@ describe('CollaboratorsHandler', function() {
|
||||||
_id: ObjectId()
|
_id: ObjectId()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.archivedProject = {
|
||||||
|
_id: ObjectId(),
|
||||||
|
archived: [ObjectId(this.userId)]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.oldArchivedProject = {
|
||||||
|
_id: ObjectId(),
|
||||||
|
archived: true
|
||||||
|
}
|
||||||
|
|
||||||
this.UserGetter = {
|
this.UserGetter = {
|
||||||
promises: {
|
promises: {
|
||||||
getUser: sinon.stub().resolves(null)
|
getUser: sinon.stub().resolves(null)
|
||||||
|
@ -46,6 +56,10 @@ describe('CollaboratorsHandler', function() {
|
||||||
getProject: sinon.stub().resolves(this.project)
|
getProject: sinon.stub().resolves(this.project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.ProjectHelper = {
|
||||||
|
calculateArchivedArray: sinon.stub()
|
||||||
|
}
|
||||||
this.CollaboratorsGetter = {
|
this.CollaboratorsGetter = {
|
||||||
promises: {
|
promises: {
|
||||||
getProjectsUserIsMemberOf: sinon.stub()
|
getProjectsUserIsMemberOf: sinon.stub()
|
||||||
|
@ -62,6 +76,7 @@ describe('CollaboratorsHandler', function() {
|
||||||
'../../models/Project': { Project },
|
'../../models/Project': { Project },
|
||||||
'../ThirdPartyDataStore/TpdsProjectFlusher': this.TpdsProjectFlusher,
|
'../ThirdPartyDataStore/TpdsProjectFlusher': this.TpdsProjectFlusher,
|
||||||
'../Project/ProjectGetter': this.ProjectGetter,
|
'../Project/ProjectGetter': this.ProjectGetter,
|
||||||
|
'../Project/ProjectHelper': this.ProjectHelper,
|
||||||
'../Errors/Errors': Errors,
|
'../Errors/Errors': Errors,
|
||||||
'./CollaboratorsGetter': this.CollaboratorsGetter
|
'./CollaboratorsGetter': this.CollaboratorsGetter
|
||||||
}
|
}
|
||||||
|
@ -73,29 +88,115 @@ describe('CollaboratorsHandler', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('removeUserFromProject', function() {
|
describe('removeUserFromProject', function() {
|
||||||
beforeEach(function() {})
|
describe('a non-archived project', function() {
|
||||||
|
beforeEach(function() {
|
||||||
it('should remove the user from mongo', async function() {
|
this.ProjectMock.expects('findOne')
|
||||||
this.ProjectMock.expects('update')
|
.withArgs({
|
||||||
.withArgs(
|
|
||||||
{
|
|
||||||
_id: this.project._id
|
_id: this.project._id
|
||||||
},
|
})
|
||||||
{
|
.chain('exec')
|
||||||
$pull: {
|
.resolves(this.project)
|
||||||
collaberator_refs: this.userId,
|
})
|
||||||
readOnly_refs: this.userId,
|
|
||||||
tokenAccessReadOnly_refs: this.userId,
|
it('should remove the user from mongo', async function() {
|
||||||
tokenAccessReadAndWrite_refs: this.userId
|
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,
|
describe('an archived project, archived with a boolean value', function() {
|
||||||
this.userId
|
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'
|
'token-read-only-1'
|
||||||
]
|
]
|
||||||
for (const projectId of expectedProjects) {
|
for (const projectId of expectedProjects) {
|
||||||
|
this.ProjectMock.expects('findOne')
|
||||||
|
.withArgs({
|
||||||
|
_id: projectId
|
||||||
|
})
|
||||||
|
.chain('exec')
|
||||||
|
.resolves({ _id: projectId })
|
||||||
|
|
||||||
this.ProjectMock.expects('update')
|
this.ProjectMock.expects('update')
|
||||||
.withArgs(
|
.withArgs(
|
||||||
{
|
{
|
||||||
|
@ -250,11 +358,12 @@ describe('CollaboratorsHandler', function() {
|
||||||
collaberator_refs: this.userId,
|
collaberator_refs: this.userId,
|
||||||
readOnly_refs: this.userId,
|
readOnly_refs: this.userId,
|
||||||
tokenAccessReadOnly_refs: this.userId,
|
tokenAccessReadOnly_refs: this.userId,
|
||||||
tokenAccessReadAndWrite_refs: this.userId
|
tokenAccessReadAndWrite_refs: this.userId,
|
||||||
|
archived: this.userId,
|
||||||
|
trashed: this.userId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.chain('exec')
|
|
||||||
.resolves()
|
.resolves()
|
||||||
}
|
}
|
||||||
await this.CollaboratorsHandler.promises.removeUserFromAllProjects(
|
await this.CollaboratorsHandler.promises.removeUserFromAllProjects(
|
||||||
|
|
Loading…
Reference in a new issue