diff --git a/services/history-v1/api/controllers/projects.js b/services/history-v1/api/controllers/projects.js index 031833688c..a314e9a5ce 100644 --- a/services/history-v1/api/controllers/projects.js +++ b/services/history-v1/api/controllers/projects.js @@ -18,6 +18,8 @@ const { HashCheckBlobStore, ProjectArchive, zipStore, + persistBuffer, + redisBuffer, } = require('../../storage') const render = require('./render') @@ -226,6 +228,19 @@ async function createZip(req, res, next) { async function deleteProject(req, res, next) { const projectId = req.swagger.params.project_id.value const blobStore = new BlobStore(projectId) + + const farFuture = new Date() + farFuture.setTime(farFuture.getTime() + 7 * 24 * 3600 * 1000) + const limits = { + maxChanges: 0, + minChangeTimestamp: farFuture, + maxChangeTimestamp: farFuture, + autoResync: false, + } + + await persistBuffer(projectId, limits) + await redisBuffer.expireProject(projectId) + await Promise.all([ chunkStore.deleteProjectChunks(projectId), blobStore.deleteBlobs(), diff --git a/services/history-v1/storage/index.js b/services/history-v1/storage/index.js index 82a51583be..6bc81f60e8 100644 --- a/services/history-v1/storage/index.js +++ b/services/history-v1/storage/index.js @@ -2,6 +2,7 @@ exports.BatchBlobStore = require('./lib/batch_blob_store') exports.blobHash = require('./lib/blob_hash') exports.HashCheckBlobStore = require('./lib/hash_check_blob_store') exports.chunkStore = require('./lib/chunk_store') +exports.redisBuffer = require('./lib/chunk_store/redis') exports.historyStore = require('./lib/history_store').historyStore exports.knex = require('./lib/knex') exports.mongodb = require('./lib/mongodb') diff --git a/services/history-v1/test/acceptance/js/api/projects.test.js b/services/history-v1/test/acceptance/js/api/projects.test.js index 7654829516..22220ae8bd 100644 --- a/services/history-v1/test/acceptance/js/api/projects.test.js +++ b/services/history-v1/test/acceptance/js/api/projects.test.js @@ -10,7 +10,12 @@ const cleanup = require('../storage/support/cleanup') const fixtures = require('../storage/support/fixtures') const testFiles = require('../storage/support/test_files') -const { zipStore, BlobStore, persistChanges } = require('../../../../storage') +const { + zipStore, + BlobStore, + persistChanges, + redisBuffer, +} = require('../../../../storage') const { expectHttpError } = require('./support/expect_response') const testServer = require('./support/test_server') @@ -347,5 +352,60 @@ describe('project controller', function () { const response3 = await fetch(blobUrl, { headers: authHeaders }) expect(response3.status).to.equal(HTTPStatus.NOT_FOUND) }) + + it('deletes the project from the redis buffer', async function () { + const projectId = await createEmptyProject() + const blobStore = new BlobStore(projectId) + const blob = await blobStore.putString('this is a test') + const snapshot = new Snapshot() + const change = new Change( + [new AddFileOperation('test.tex', File.createLazyFromBlobs(blob))], + new Date(), + [] + ) + + await redisBuffer.queueChanges(projectId, snapshot, 0, [change]) + const changesBefore = await redisBuffer.getNonPersistedChanges( + projectId, + 0 + ) + expect(changesBefore.length).to.equal(1) + + const deleteResponse = + await testServer.basicAuthClient.apis.Project.deleteProject({ + project_id: projectId, + }) + expect(deleteResponse.status).to.equal(HTTPStatus.NO_CONTENT) + + const changesAfter = await redisBuffer.getNonPersistedChanges( + projectId, + 0 + ) + expect(changesAfter.length).to.equal(0) + + const finalState = await redisBuffer.getState(projectId) + expect(finalState).to.deep.equal({ + changes: [], + expireTime: null, + headSnapshot: null, + headVersion: null, + persistTime: null, + persistedVersion: null, + }) + }) + + it('deletes an empty project from the redis buffer', async function () { + const projectId = await createEmptyProject() + const deleteResponse = + await testServer.basicAuthClient.apis.Project.deleteProject({ + project_id: projectId, + }) + expect(deleteResponse.status).to.equal(HTTPStatus.NO_CONTENT) + const changesAfter = await redisBuffer.getNonPersistedChanges( + projectId, + 0 + ) + expect(changesAfter.length).to.equal(0) + }) }) })