diff --git a/services/web/app/src/Features/Project/ProjectDeleter.js b/services/web/app/src/Features/Project/ProjectDeleter.js index a2064d81e6..ec5ccfa20e 100644 --- a/services/web/app/src/Features/Project/ProjectDeleter.js +++ b/services/web/app/src/Features/Project/ProjectDeleter.js @@ -342,6 +342,16 @@ async function undeleteProject(projectId, options = {}) { async function expireDeletedProject(projectId) { try { + const activeProject = await Project.findById(projectId).exec() + if (activeProject) { + // That project is active. The deleted project record might be there + // because of an incomplete delete or undelete operation. Clean it up and + // return. + await DeletedProject.deleteOne({ + 'deleterData.deletedProjectId': projectId, + }) + return + } const deletedProject = await DeletedProject.findOne({ 'deleterData.deletedProjectId': projectId, }).exec() diff --git a/services/web/test/unit/src/Project/ProjectDeleterTests.js b/services/web/test/unit/src/Project/ProjectDeleterTests.js index 167e2e9238..6578a4a76d 100644 --- a/services/web/test/unit/src/Project/ProjectDeleterTests.js +++ b/services/web/test/unit/src/Project/ProjectDeleterTests.js @@ -369,6 +369,12 @@ describe('ProjectDeleter', function () { describe('expireDeletedProjectsAfterDuration', function () { beforeEach(async function () { + for (const deletedProject of this.deletedProjects) { + this.ProjectMock.expects('findById') + .withArgs(deletedProject.deleterData.deletedProjectId) + .chain('exec') + .resolves(null) + } this.DeletedProjectMock.expects('find') .withArgs({ 'deleterData.deletedAt': { @@ -414,6 +420,12 @@ describe('ProjectDeleter', function () { describe('expireDeletedProject', function () { beforeEach(async function () { + for (const deletedProject of this.deletedProjects) { + this.ProjectMock.expects('findById') + .withArgs(deletedProject.deleterData.deletedProjectId) + .chain('exec') + .resolves(null) + } this.DeletedProjectMock.expects('updateOne') .withArgs( {