Merge pull request #89 from overleaf/jpa-is-doc-deleted

[misc] add a new endpoint for querying the deleted status of a doc
This commit is contained in:
Jakob Ackermann 2021-02-09 11:14:28 +00:00 committed by GitHub
commit 2cf9ff7b41
5 changed files with 98 additions and 0 deletions

View file

@ -46,6 +46,7 @@ Metrics.injectMetricsRoute(app)
app.get('/project/:project_id/doc', HttpController.getAllDocs)
app.get('/project/:project_id/ranges', HttpController.getAllRanges)
app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc)
app.get('/project/:project_id/doc/:doc_id/deleted', HttpController.isDocDeleted)
app.get('/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc)
// Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload
app.post(

View file

@ -90,6 +90,24 @@ module.exports = DocManager = {
)
},
isDocDeleted(projectId, docId, callback) {
MongoManager.findDoc(projectId, docId, { deleted: true }, function (
err,
doc
) {
if (err) {
return callback(err)
}
if (!doc) {
return callback(
new Errors.NotFoundError(`No such project/doc: ${projectId}/${docId}`)
)
}
// `doc.deleted` is `undefined` for non deleted docs
callback(null, Boolean(doc.deleted))
})
},
getFullDoc(project_id, doc_id, callback) {
if (callback == null) {
callback = function (err, doc) {}

View file

@ -44,6 +44,16 @@ module.exports = HttpController = {
})
},
isDocDeleted(req, res, next) {
const { doc_id: docId, project_id: projectId } = req.params
DocManager.isDocDeleted(projectId, docId, function (error, deleted) {
if (error) {
return next(error)
}
res.json({ deleted })
})
},
getRawDoc(req, res, next) {
if (next == null) {
next = function (error) {}

View file

@ -44,6 +44,19 @@ describe('Deleting a doc', function () {
})
})
it('should show as not deleted on /deleted', function (done) {
DocstoreClient.isDocDeleted(
this.project_id,
this.doc_id,
(error, res, body) => {
if (error) return done(error)
expect(res.statusCode).to.equal(200)
expect(body).to.have.property('deleted').to.equal(false)
done()
}
)
})
describe('when the doc exists', function () {
beforeEach(function (done) {
return DocstoreClient.deleteDoc(
@ -60,6 +73,19 @@ describe('Deleting a doc', function () {
return db.docs.remove({ _id: this.doc_id }, done)
})
it('should mark the doc as deleted on /deleted', function (done) {
DocstoreClient.isDocDeleted(
this.project_id,
this.doc_id,
(error, res, body) => {
if (error) return done(error)
expect(res.statusCode).to.equal(200)
expect(body).to.have.property('deleted').to.equal(true)
done()
}
)
})
return it('should insert a deleted doc into the docs collection', function (done) {
return db.docs.find({ _id: this.doc_id }).toArray((error, docs) => {
docs[0]._id.should.deep.equal(this.doc_id)
@ -70,7 +96,40 @@ describe('Deleting a doc', function () {
})
})
describe('when the doc exists in another project', function () {
const otherProjectId = ObjectId()
it('should show as not existing on /deleted', function (done) {
DocstoreClient.isDocDeleted(otherProjectId, this.doc_id, (error, res) => {
if (error) return done(error)
expect(res.statusCode).to.equal(404)
done()
})
})
it('should return a 404 when trying to delete', function (done) {
DocstoreClient.deleteDoc(otherProjectId, this.doc_id, (error, res) => {
if (error) return done(error)
expect(res.statusCode).to.equal(404)
done()
})
})
})
return describe('when the doc does not exist', function () {
it('should show as not existing on /deleted', function (done) {
const missing_doc_id = ObjectId()
DocstoreClient.isDocDeleted(
this.project_id,
missing_doc_id,
(error, res) => {
if (error) return done(error)
expect(res.statusCode).to.equal(404)
done()
}
)
})
return it('should return a 404', function (done) {
const missing_doc_id = ObjectId()
return DocstoreClient.deleteDoc(

View file

@ -60,6 +60,16 @@ module.exports = DocstoreClient = {
)
},
isDocDeleted(project_id, doc_id, callback) {
request.get(
{
url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/deleted`,
json: true
},
callback
)
},
getAllDocs(project_id, callback) {
if (callback == null) {
callback = function (error, res, body) {}