diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index f80f99288d..e41593cd4c 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -29,6 +29,7 @@ app.param 'doc_id', (req, res, next, doc_id) -> next new Error("invalid doc id") 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/raw', HttpController.getRawDoc # Add 16kb overhead for the JSON encoding diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index a51e825f90..36996d943a 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -37,13 +37,14 @@ module.exports = HttpController = logger.log project_id: project_id, "getting all docs" DocManager.getAllNonDeletedDocs project_id, {lines: true, rev: true}, (error, docs = []) -> return next(error) if error? - docViews = [] - for doc in docs - if doc? # There can end up being null docs for some reason :( (probably a race condition) - docViews.push HttpController._buildDocView(doc) - else - logger.error err: new Error("null doc"), project_id: project_id, "encountered null doc" - res.json docViews + res.json HttpController._buildDocsArrayView(project_id, docs) + + getAllRanges: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log {project_id}, "getting all ranges" + DocManager.getAllNonDeletedDocs project_id, {ranges: true}, (error, docs = []) -> + return next(error) if error? + res.json HttpController._buildDocsArrayView(project_id, docs) updateDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id @@ -79,21 +80,23 @@ module.exports = HttpController = res.send 204 _buildDocView: (doc) -> - doc_view = { - _id: doc._id?.toString() - lines: doc.lines - rev: doc.rev - } - if doc.version? - doc_view.version = doc.version - if doc.ranges? - doc_view.ranges = doc.ranges - if doc.deleted? - doc_view.deleted = doc.deleted + doc_view = { _id: doc._id?.toString() } + for attribute in ["lines", "rev", "version", "ranges", "deleted"] + if doc[attribute]? + doc_view[attribute] = doc[attribute] return doc_view _buildRawDocView: (doc)-> return (doc?.lines or []).join("\n") + + _buildDocsArrayView: (project_id, docs) -> + docViews = [] + for doc in docs + if doc? # There can end up being null docs for some reason :( (probably a race condition) + docViews.push HttpController._buildDocView(doc) + else + logger.error err: new Error("null doc"), project_id: project_id, "encountered null doc" + return docViews archiveAllDocs: (req, res, next = (error) ->) -> project_id = req.params.project_id diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 6bbfb4cfa9..7244693888 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -12,33 +12,36 @@ describe "Getting all docs", -> @docs = [{ _id: ObjectId() lines: ["one", "two", "three"] + ranges: {"mock": "one"} rev: 2 }, { _id: ObjectId() lines: ["aaa", "bbb", "ccc"] + ranges: {"mock": "two"} rev: 4 }, { _id: ObjectId() lines: ["111", "222", "333"] + ranges: {"mock": "three"} rev: 6 }] @deleted_doc = { _id: ObjectId() lines: ["deleted"] + ranges: {"mock": "four"} rev: 8 } version = 42 - ranges = 42 jobs = for doc in @docs do (doc) => (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, ranges, callback + DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, doc.ranges, callback jobs.push (cb) => - DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, version, {}, (err)=> + DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, version, @deleted_doc.ranges, (err)=> DocstoreClient.deleteDoc @project_id, @deleted_doc._id, cb async.series jobs, done - it "should return all the (non-deleted) docs", (done) -> + it "getAllDocs should return all the (non-deleted) docs", (done) -> DocstoreClient.getAllDocs @project_id, (error, res, docs) => throw error if error? docs.length.should.equal @docs.length @@ -46,4 +49,12 @@ describe "Getting all docs", -> doc.lines.should.deep.equal @docs[i].lines done() + it "getAllRanges should return all the (non-deleted) doc ranges", (done) -> + DocstoreClient.getAllRanges @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.ranges.should.deep.equal @docs[i].ranges + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index b4ccdcb418..05d8069d69 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -21,6 +21,12 @@ module.exports = DocstoreClient = json: true }, callback + getAllRanges: (project_id, callback = (error, res, body) ->) -> + request.get { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/ranges" + json: true + }, callback + updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, res, body) ->) -> request.post { url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index b775c5f91c..6b157050d4 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -180,6 +180,37 @@ describe "HttpController", -> ) .should.equal true + describe "getAllRanges", -> + describe "normally", -> + beforeEach -> + @req.params = + project_id: @project_id + @docs = [{ + _id: ObjectId() + ranges: {"mock_ranges": "one"} + }, { + _id: ObjectId() + ranges: {"mock_ranges": "two"} + }] + @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) + @HttpController.getAllRanges @req, @res, @next + + it "should get all the (non-deleted) doc ranges", -> + @DocManager.getAllNonDeletedDocs + .calledWith(@project_id, {ranges: true}) + .should.equal true + + it "should return the doc as JSON", -> + @res.json + .calledWith([{ + _id: @docs[0]._id.toString() + ranges: @docs[0].ranges + }, { + _id: @docs[1]._id.toString() + ranges: @docs[1].ranges + }]) + .should.equal true + describe "updateDoc", -> beforeEach -> @req.params =