Просмотр исходного кода

Merge pull request #13023 from overleaf/em-delete-git-bridge-data

Delete git bridge data when a project is expired

GitOrigin-RevId: a600941831af31ff7712d44e437936cd416fc644
Eric Mc Sween 3 лет назад
Родитель
Сommit
1117bfae20

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

@@ -1,5 +1,6 @@
 const _ = require('lodash')
 const { db, ObjectId } = require('../../infrastructure/mongodb')
+const Modules = require('../../infrastructure/Modules')
 const { callbackify } = require('util')
 const { Project } = require('../../models/Project')
 const { DeletedProject } = require('../../models/DeletedProject')
@@ -387,6 +388,7 @@ async function expireDeletedProject(projectId) {
       ChatApiHandler.promises.destroyProject(deletedProject.project._id),
       hardDeleteDeletedFiles(deletedProject.project._id),
       ProjectAuditLogEntry.deleteMany({ projectId }),
+      Modules.promises.hooks.fire('projectExpired', deletedProject.project._id),
     ])
 
     await DeletedProject.updateOne(

+ 3 - 0
services/web/test/acceptance/config/settings.test.defaults.js

@@ -90,6 +90,9 @@ module.exports = {
     webpack: {
       url: 'http://localhost:23808',
     },
+    gitBridge: {
+      url: 'http://localhost:28000',
+    },
   },
 
   // for registration via SL, set enableLegacyRegistration to true

+ 51 - 1
services/web/test/acceptance/src/DeletionTests.js

@@ -4,16 +4,19 @@ const async = require('async')
 const { expect } = require('chai')
 const settings = require('@overleaf/settings')
 const { db, ObjectId } = require('../../../app/src/infrastructure/mongodb')
+const Features = require('../../../app/src/infrastructure/Features')
 const MockDocstoreApiClass = require('./mocks/MockDocstoreApi')
 const MockFilestoreApiClass = require('./mocks/MockFilestoreApi')
 const MockChatApiClass = require('./mocks/MockChatApi')
+const MockGitBridgeApiClass = require('./mocks/MockGitBridgeApi')
 
-let MockDocstoreApi, MockFilestoreApi, MockChatApi
+let MockDocstoreApi, MockFilestoreApi, MockChatApi, MockGitBridgeApi
 
 before(function () {
   MockDocstoreApi = MockDocstoreApiClass.instance()
   MockFilestoreApi = MockFilestoreApiClass.instance()
   MockChatApi = MockChatApiClass.instance()
+  MockGitBridgeApi = MockGitBridgeApiClass.instance()
 })
 
 describe('Deleting a user', function () {
@@ -313,6 +316,11 @@ describe('Deleting a project', function () {
           dummyFile: 'wombat',
         }
         MockChatApi.projects[this.projectId.toString()] = ['message']
+        if (Features.hasFeature('git-bridge')) {
+          MockGitBridgeApi.projects[this.projectId.toString()] = {
+            data: 'some-data',
+          }
+        }
       })
     })
 
@@ -437,4 +445,46 @@ describe('Deleting a project', function () {
       })
     })
   })
+
+  if (Features.hasFeature('git-bridge')) {
+    describe('When the project has git-bridge data', function () {
+      beforeEach(function () {
+        MockGitBridgeApi.projects[this.projectId.toString()] = {
+          data: 'some-data',
+        }
+      })
+
+      describe('When the deleted project is expired', function () {
+        beforeEach(function (done) {
+          this.user.deleteProject(this.projectId, error => {
+            if (error) {
+              return done(error)
+            }
+            request.post(
+              `/internal/project/${this.projectId}/expire-deleted-project`,
+              {
+                auth: {
+                  user: settings.apis.web.user,
+                  pass: settings.apis.web.pass,
+                  sendImmediately: true,
+                },
+              },
+              (error, res) => {
+                if (error) {
+                  return done(error)
+                }
+                expect(res.statusCode).to.equal(200)
+                done()
+              }
+            )
+          })
+        })
+
+        it('should delete the git-bridge data', function () {
+          expect(MockGitBridgeApi.projects[this.projectId.toString()]).not.to
+            .exist
+        })
+      })
+    })
+  }
 })

+ 5 - 0
services/web/test/acceptance/src/Init.js

@@ -7,6 +7,7 @@ const MockClsiApi = require('./mocks/MockClsiApi')
 const MockDocstoreApi = require('./mocks/MockDocstoreApi')
 const MockDocUpdaterApi = require('./mocks/MockDocUpdaterApi')
 const MockFilestoreApi = require('./mocks/MockFilestoreApi')
+const MockGitBridgeApi = require('./mocks/MockGitBridgeApi')
 const MockNotificationsApi = require('./mocks/MockNotificationsApi')
 const MockProjectHistoryApi = require('./mocks/MockProjectHistoryApi')
 const MockSpellingApi = require('./mocks/MockSpellingApi')
@@ -35,3 +36,7 @@ if (Features.hasFeature('saas')) {
   MockV1Api.initialize(25000, mockOpts)
   MockThirdPartyDataStoreApi.initialize(23002, mockOpts)
 }
+
+if (Features.hasFeature('git-bridge')) {
+  MockGitBridgeApi.initialize(28000, mockOpts)
+}

+ 21 - 0
services/web/test/acceptance/src/mocks/MockGitBridgeApi.js

@@ -0,0 +1,21 @@
+const AbstractMockApi = require('./AbstractMockApi')
+
+class MockGitBridgeApi extends AbstractMockApi {
+  reset() {
+    this.projects = {}
+  }
+
+  applyRoutes() {
+    this.app.delete('/api/projects/:projectId', (req, res) => {
+      this.deleteProject(req, res)
+    })
+  }
+
+  deleteProject(req, res) {
+    const projectId = req.params.projectId
+    delete this.projects[projectId]
+    res.sendStatus(204)
+  }
+}
+
+module.exports = MockGitBridgeApi