Преглед изворни кода

Merge pull request #3372 from overleaf/jpa-archive-docs-on-soft-delete

[ProjectDeleter] flush docs out of mongo when soft-deleting a project

GitOrigin-RevId: 52f3e1298af5ca481ba9b27b18c9190063019988
Simon Detheridge пре 6 година
родитељ
комит
da8663fd0f

+ 12 - 0
services/web/app/src/Features/Project/ProjectDeleter.js

@@ -240,6 +240,18 @@ async function deleteProject(projectId, options = {}) {
       projectId
       projectId
     )
     )
 
 
+    try {
+      // OPTIMIZATION: flush docs out of mongo
+      await DocstoreManager.promises.archiveProject(projectId)
+    } catch (err) {
+      // It is OK to fail here, the docs will get hard-deleted eventually after
+      //  the grace-period for soft-deleted projects has passed.
+      logger.warn(
+        { projectId, err },
+        'failed archiving doc via docstore as part of project soft-deletion'
+      )
+    }
+
     const memberIds = await CollaboratorsGetter.promises.getMemberIds(projectId)
     const memberIds = await CollaboratorsGetter.promises.getMemberIds(projectId)
 
 
     // fire these jobs in the background
     // fire these jobs in the background

+ 27 - 0
services/web/test/unit/src/Project/ProjectDeleterTests.js

@@ -112,6 +112,7 @@ describe('ProjectDeleter', function() {
 
 
     this.DocstoreManager = {
     this.DocstoreManager = {
       promises: {
       promises: {
+        archiveProject: sinon.stub().resolves(),
         destroyProject: sinon.stub().resolves()
         destroyProject: sinon.stub().resolves()
       }
       }
     }
     }
@@ -320,6 +321,32 @@ describe('ProjectDeleter', function() {
         .should.equal(true)
         .should.equal(true)
     })
     })
 
 
+    it('should flush docs out of mongo', async function() {
+      this.ProjectMock.expects('deleteOne')
+        .chain('exec')
+        .resolves()
+      this.DeletedProjectMock.expects('updateOne').resolves()
+      await this.ProjectDeleter.promises.deleteProject(this.project._id, {
+        deleterUser: this.user,
+        ipAddress: this.ip
+      })
+      expect(
+        this.DocstoreManager.promises.archiveProject
+      ).to.have.been.calledWith(this.project._id)
+    })
+
+    it('should flush docs out of mongo and ignore errors', async function() {
+      this.ProjectMock.expects('deleteOne')
+        .chain('exec')
+        .resolves()
+      this.DeletedProjectMock.expects('updateOne').resolves()
+      this.DocstoreManager.promises.archiveProject.rejects(new Error('foo'))
+      await this.ProjectDeleter.promises.deleteProject(this.project._id, {
+        deleterUser: this.user,
+        ipAddress: this.ip
+      })
+    })
+
     it('should removeProjectFromAllTags', async function() {
     it('should removeProjectFromAllTags', async function() {
       this.ProjectMock.expects('deleteOne')
       this.ProjectMock.expects('deleteOne')
         .chain('exec')
         .chain('exec')