Parcourir la source

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

[misc] add a new endpoint for querying the deleted status of a doc
Jakob Ackermann il y a 5 ans
Parent
commit
2cf9ff7b41

+ 1 - 0
services/docstore/app.js

@@ -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(

+ 18 - 0
services/docstore/app/js/DocManager.js

@@ -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) {}

+ 10 - 0
services/docstore/app/js/HttpController.js

@@ -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) {}

+ 59 - 0
services/docstore/test/acceptance/js/DeletingDocsTests.js

@@ -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(

+ 10 - 0
services/docstore/test/acceptance/js/helpers/DocstoreClient.js

@@ -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) {}