From 8a991b0d06c1d3c4655bbde33b5111c8b03b38f8 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Tue, 26 Jan 2016 14:29:23 +0000 Subject: [PATCH] Start testing ReferencesSearch feature --- .../ReferencesSearchController.coffee | 35 +-- .../ReferencesSearchHandler.coffee | 104 ++++---- .../ReferencesSearchControllerTests.coffee | 229 ++++++++---------- .../ReferencesSearchHandlerTests.coffee | 108 +++++++-- 4 files changed, 242 insertions(+), 234 deletions(-) diff --git a/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchController.coffee b/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchController.coffee index 55fca1c3e6..db85585724 100644 --- a/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchController.coffee +++ b/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchController.coffee @@ -1,48 +1,15 @@ logger = require('logger-sharelatex') ReferencesSearchHandler = require('./ReferencesSearchHandler') -ProjectLocator = require("../Project/ProjectLocator") settings = require('settings-sharelatex') EditorRealTimeController = require("../Editor/EditorRealTimeController") module.exports = ReferencesSearchController = - indexFile: (req, res) -> - project_id = req.params.Project_id - doc_id = req.body.docId - logger.log {project_id, doc_id}, "indexing references" - - if !doc_id - logger.log project_id: project_id, "no fileUrl supplied" - return res.send 400 - ProjectLocator.findElement { - project_id: project_id, - element_id: doc_id, - type: 'doc' - }, (err, doc) -> - if err? - logger.err {err, project_id, doc_id}, "error finding doc to index" - return res.send 500 - ReferencesSearchHandler.indexFile project_id, doc_id, (err) -> - if err - logger.err {err, project_id, doc_id}, "error indexing references file" - return res.send 500 - - res.send 200 - - getKeys: (req, res) -> - project_id = req.params.Project_id - logger.log {project_id}, "getting project references keys" - ReferencesSearchHandler.getKeys project_id, (err, data) -> - if err - logger.err {err, project_id}, "error getting references keys" - return res.send 500 - return res.json data - index: (req, res) -> projectId = req.params.Project_id shouldBroadcast = req.body.shouldBroadcast docIds = req.body.docIds - if (not docIds instanceof Array) and (docIds != "ALL") + if (!docIds or (!(docIds instanceof Array) and (docIds != 'ALL'))) logger.err {projectId, docIds}, "docIds is not valid, should be either Array or String 'ALL'" return res.send 400 logger.log {projectId, docIds}, "index references for project" diff --git a/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchHandler.coffee b/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchHandler.coffee index a4cfad8622..2b877bba8d 100644 --- a/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchHandler.coffee +++ b/services/web/app/coffee/Features/ReferencesSearch/ReferencesSearchHandler.coffee @@ -67,58 +67,58 @@ module.exports = ReferencesSearchHandler = ## ## ## ## - indexProjectReferences: (project, callback = (err) ->) -> - logger.log {projectId: project._id}, "try indexing references from project" - ids = ReferencesSearchHandler._findBibDocIds(project) - logger.log {projectId: project._id, count: ids.length}, "found bib files in project" - Async.eachSeries( - ids, - (docId, next) -> - ReferencesSearchHandler.indexFile project._id, docId, (err) -> - next(err) - , (err) -> - logger.log {projectId: project._id, count: ids.length}, "done index bib files in project" - callback(err) - ) + # indexProjectReferences: (project, callback = (err) ->) -> + # logger.log {projectId: project._id}, "try indexing references from project" + # ids = ReferencesSearchHandler._findBibDocIds(project) + # logger.log {projectId: project._id, count: ids.length}, "found bib files in project" + # Async.eachSeries( + # ids, + # (docId, next) -> + # ReferencesSearchHandler.indexFile project._id, docId, (err) -> + # next(err) + # , (err) -> + # logger.log {projectId: project._id, count: ids.length}, "done index bib files in project" + # callback(err) + # ) - indexFile: (projectId, fileId, callback = (err)->) -> - target_url = "#{settings.apis.references.url}/project/#{projectId}" - fileUrl = ReferencesSearchHandler._buildDocUrl projectId, fileId - logger.log {projectId, fileId}, "checking if file should be fully indexed" - ReferencesSearchHandler._isFullIndex projectId, (err, isFullIndex) -> - if err - logger.err {projectId, fileId, err}, "error checking if file should be fully indexed" - return callback(err) - logger.log {projectId, fileId, isFullIndex}, "sending index request to references api" - request.post { - url: target_url - json: - referencesUrl: fileUrl - }, (err, res, result) -> - if err - return callback(err) - if 200 <= res.statusCode < 300 - return callback(null) - else - err = new Error("references api responded with non-success code: #{res.statusCode}") - logger.log {err, projectId, fileUrl}, "error updating references" - return callback(err) + # indexFile: (projectId, fileId, callback = (err)->) -> + # target_url = "#{settings.apis.references.url}/project/#{projectId}" + # fileUrl = ReferencesSearchHandler._buildDocUrl projectId, fileId + # logger.log {projectId, fileId}, "checking if file should be fully indexed" + # ReferencesSearchHandler._isFullIndex projectId, (err, isFullIndex) -> + # if err + # logger.err {projectId, fileId, err}, "error checking if file should be fully indexed" + # return callback(err) + # logger.log {projectId, fileId, isFullIndex}, "sending index request to references api" + # request.post { + # url: target_url + # json: + # referencesUrl: fileUrl + # }, (err, res, result) -> + # if err + # return callback(err) + # if 200 <= res.statusCode < 300 + # return callback(null) + # else + # err = new Error("references api responded with non-success code: #{res.statusCode}") + # logger.log {err, projectId, fileUrl}, "error updating references" + # return callback(err) - getKeys: (projectId, callback = (err, result)->) -> - logger.log {projectId}, "getting keys from remote references api" - url = "#{settings.apis.references.url}/project/#{projectId}/keys" - request.get { - url: url - json: true - }, (err, res, result) -> - if err - return callback(err) - if 200 <= res.statusCode < 300 - return callback(null, result) - else - err = new Error("references api responded with non-success code: #{res.statusCode}") - logger.log {err, projectId}, "error getting references keys" - return callback(err) + # getKeys: (projectId, callback = (err, result)->) -> + # logger.log {projectId}, "getting keys from remote references api" + # url = "#{settings.apis.references.url}/project/#{projectId}/keys" + # request.get { + # url: url + # json: true + # }, (err, res, result) -> + # if err + # return callback(err) + # if 200 <= res.statusCode < 300 + # return callback(null, result) + # else + # err = new Error("references api responded with non-success code: #{res.statusCode}") + # logger.log {err, projectId}, "error getting references keys" + # return callback(err) - _buildDocUrl: (projectId, docId) -> - "#{settings.apis.web.url}/project/#{projectId}/doc/#{docId}" + # _buildDocUrl: (projectId, docId) -> + # "#{settings.apis.web.url}/project/#{projectId}/doc/#{docId}" diff --git a/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchControllerTests.coffee b/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchControllerTests.coffee index 985a392fed..dd93ef8626 100644 --- a/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchControllerTests.coffee @@ -9,165 +9,148 @@ MockResponse = require "../helpers/MockResponse" describe "ReferencesSearchController", -> beforeEach -> - @project_id = '2222' - @doc_id = '3333' + @projectId = '2222' @controller = SandboxedModule.require modulePath, requires: 'logger-sharelatex': { log: -> err: -> - } + }, 'settings-sharelatex': @settings = { apis: {web: {url: 'http://some.url'}} - } - '../Project/ProjectLocator': @ProjectLocator = { - findElement: sinon.stub() - } + }, './ReferencesSearchHandler': @ReferencesSearchHandler = { - indexFile: sinon.stub() - getKeys: sinon.stub() + index: sinon.stub() + }, + '../Editor/EditorRealTimeController': @EditorRealTimeController = { + emitToRoom: sinon.stub() } + @req = new MockRequest() + @req.params.Project_id = @projectId + @req.body = + docIds: @docIds = ['aaa', 'bbb'] + shouldBroadcast: false + @res = new MockResponse() + @res.json = sinon.stub() + @res.send = sinon.stub() + @fakeResponseData = + projectId: @projectId, + keys: ['one', 'two', 'three'] - describe 'getKeys', -> + describe 'index', -> - beforeEach -> - @req = new MockRequest() - @req.params.Project_id = @project_id - @res = new MockResponse() - @data = - projectId: @project_id, - keys: ['one', 'two', 'three'] - @ReferencesSearchHandler.getKeys.callsArgWith(1, null, @data) - - describe 'when remote service works', -> - - it 'should produce a json response', (done) -> - @res.json = (data) => - data.should.not.equal null - data.should.deep.equal @data - done() - @controller.getKeys(@req, @res) - - it 'should call getKeys on ReferencesSearchHandler', (done) -> - @res.json = (data) => - @ReferencesSearchHandler.getKeys - .calledOnce.should.equal true - @ReferencesSearchHandler.getKeys - .calledWith(@project_id).should.equal true - done() - @controller.getKeys(@req, @res) - - describe 'when remote service produces an error', -> + describe 'with docIds as an array and shouldBroadcast as false', -> beforeEach -> - @ReferencesSearchHandler.getKeys.callsArgWith(1, new Error('nope')) + @ReferencesSearchHandler.index.callsArgWith(2, null, @fakeResponseData) + @call = (callback) => + @controller.index @req, @res + callback() - it 'should produce a 500 response', (done) -> - @res.send = (status) => - status.should.equal 500 + it 'should call ReferencesSearchHandler.index', (done) -> + @call () => + @ReferencesSearchHandler.index.callCount.should.equal 1 + @ReferencesSearchHandler.index.calledWith(@projectId, @docIds).should.equal true done() - @controller.getKeys(@req, @res) - it 'should call getKeys on ReferencesSearchHandler', (done) -> - @res.send = (status) => - @ReferencesSearchHandler.getKeys - .calledOnce.should.equal true - @ReferencesSearchHandler.getKeys - .calledWith(@project_id).should.equal true + it 'should return data', (done) -> + @call () => + @res.json.callCount.should.equal 1 + @res.json.calledWith(@fakeResponseData).should.equal true done() - @controller.getKeys(@req, @res) - describe 'indexFile', -> + it 'should not produce an error', (done) -> + @call () => + @res.send.callCount.should.equal 0 + @res.send.calledWith(500).should.equal false + @res.send.calledWith(400).should.equal false + done() - beforeEach -> - @req = new MockRequest() - @req.params.Project_id = @project_id - @res = new MockResponse() - @ProjectLocator.findElement.callsArgWith(1, null, {}) - @ReferencesSearchHandler.indexFile.callsArgWith(2, null) + it 'should not call EditorRealTimController.emitToRoom', (done) -> + @call () => + @EditorRealTimeController.emitToRoom.callCount.should.equal 0 + done() - describe 'with a valid doc_id', -> + describe 'with docIds set to ALL', -> + + beforeEach -> + @req.body.docIds = 'ALL' + + it 'should still pass the "ALL" value to handler', (done) -> + @call () => + @ReferencesSearchHandler.index.callCount.should.equal 1 + @ReferencesSearchHandler.index.calledWith(@projectId, 'ALL').should.equal true + done() + + it 'should not produce an error', (done) -> + @call () => + @res.send.callCount.should.equal 0 + @res.send.calledWith(500).should.equal false + @res.send.calledWith(400).should.equal false + done() + + describe 'when ReferencesSearchHandler.index produces an error', -> + + beforeEach -> + @ReferencesSearchHandler.index.callsArgWith(2, new Error('woops'), null) + + it 'should produce an error response', (done) -> + @call () => + @res.send.callCount.should.equal 1 + @res.send.calledWith(500).should.equal true + done() + + describe 'when shouldBroadcast is true', -> beforeEach -> - @req.body = {docId: @doc_id} + @ReferencesSearchHandler.index.callsArgWith(2, null, @fakeResponseData) + @req.body.shouldBroadcast = true - it 'should produce a 200 response', (done) -> - @res.send = (status) => - status.should.equal 200 + it 'should call EditorRealTimeController.emitToRoom', (done) -> + @call () => + @EditorRealTimeController.emitToRoom.callCount.should.equal 1 done() - @controller.indexFile(@req, @res) - it 'should call ProjectLocator.findElement', (done) -> - @res.send = (status) => - @ProjectLocator.findElement.calledOnce.should.equal true - arg = - project_id: @project_id - element_id: @doc_id, - type: 'doc' - @ProjectLocator.findElement.calledWith(arg).should.equal true + it 'should not produce an error', (done) -> + @call () => + @res.send.callCount.should.equal 0 + @res.send.calledWith(500).should.equal false + @res.send.calledWith(400).should.equal false done() - @controller.indexFile(@req, @res) - it 'should call ReferencesSearchHandler.indexFile', (done) -> - @res.send = (status) => - @ReferencesSearchHandler.indexFile.calledOnce.should.equal true - @ReferencesSearchHandler.indexFile - .calledWith(@project_id, @doc_id).should.equal true + it 'should still return data', (done) -> + @call () => + @res.json.callCount.should.equal 1 + @res.json.calledWith(@fakeResponseData).should.equal true done() - @controller.indexFile(@req, @res) - describe 'without a doc_id', -> + describe 'with missing docIds', -> beforeEach -> - @req.body = {bad: true} + delete @req.body.docIds - it 'should produce a 400 response', (done) -> - @res.send = (status) => - status.should.equal 400 + it 'should produce an error response', (done) -> + @call () => + @res.send.callCount.should.equal 1 + @res.send.calledWith(400).should.equal true done() - @controller.indexFile(@req, @res) - describe 'when the ProjectLocator cannot find the doc', -> + it 'should not call ReferencesSearchHandler.index', (done) -> + @call () => + @ReferencesSearchHandler.index.callCount.should.equal 0 + done() + + describe 'with invalid docIds', -> beforeEach -> - @req.body = {docId: 'some_weird_id'} - @ProjectLocator.findElement.callsArgWith(1, new Error('not found'), null) - @ReferencesSearchHandler.indexFile.callsArgWith(2, null) + @req.body.docIds = 42 - it 'should call ProjectLocator.findElement', (done) -> - @res.send = (status) => - @ProjectLocator.findElement.calledOnce.should.equal true - arg = - project_id: @project_id - element_id: 'some_weird_id', - type: 'doc' - @ProjectLocator.findElement.calledWith(arg).should.equal true + it 'should produce an error response', (done) -> + @call () => + @res.send.callCount.should.equal 1 + @res.send.calledWith(400).should.equal true done() - @controller.indexFile(@req, @res) - it 'should produce a 500 response', (done) -> - @res.send = (status) => - status.should.equal 500 + it 'should not call ReferencesSearchHandler.index', (done) -> + @call () => + @ReferencesSearchHandler.index.callCount.should.equal 0 done() - @controller.indexFile(@req, @res) - - describe 'when the ReferencesSearchHandler produces an error', -> - - beforeEach -> - @req.body = {docId: @doc_id} - @ProjectLocator.findElement.callsArgWith(1, null, {}) - @ReferencesSearchHandler.indexFile - .callsArgWith(2, new Error('something went wrong')) - - it 'should call ReferencesSearchHandler.indexFile', (done) -> - @res.send = (status) => - @ReferencesSearchHandler.indexFile.calledOnce.should.equal true - @ReferencesSearchHandler.indexFile - .calledWith(@project_id, @doc_id).should.equal true - done() - @controller.indexFile(@req, @res) - - it 'should produce a 500 response', (done) -> - @res.send = (status) => - status.should.equal 500 - done() - @controller.indexFile(@req, @res) diff --git a/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchHandlerTests.coffee b/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchHandlerTests.coffee index 805e804d44..a9354b4cd8 100644 --- a/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/ReferencesSearch/ReferencesSearchHandlerTests.coffee @@ -7,31 +7,89 @@ modulePath = "../../../../app/js/Features/ReferencesSearch/ReferencesSearchHandl describe 'ReferencesSearchHandler', -> - # beforeEach -> - # @project_id = '222' - # @file_id = '111111' - # @handler = SandboxedModule.require modulePath, requires: - # 'logger-sharelatex': { - # log: -> - # err: -> - # } - # 'settings-sharelatex': @settings = { - # apis: - # references: {url: 'http://some.url'} - # web: {url: 'http://some.url'} - # } - # 'request': @request = { - # get: sinon.stub() - # post: sinon.stub() - # } - # '../../models/Project': @Project = { - # Project: { - # findById: sinon.stub().callsArgWith(2, null, {owner_ref: '111'}) - # } - # } - # '../User/UserGetter': @UserGetter = { - # getUser: sinon.stub().callsArgWith(2, null, {features: {references: false}}) - # } + beforeEach -> + @project_id = '222' + @file_id = '111111' + @handler = SandboxedModule.require modulePath, requires: + 'logger-sharelatex': { + log: -> + err: -> + } + 'settings-sharelatex': @settings = { + apis: + references: {url: 'http://some.url'} + web: {url: 'http://some.url'} + } + 'request': @request = { + get: sinon.stub() + post: sinon.stub() + } + '../../models/Project': @Project = { + Project: { + findById: sinon.stub().callsArgWith(2, null, {owner_ref: '111'}) + } + } + '../User/UserGetter': @UserGetter = { + getUser: sinon.stub().callsArgWith(2, null, {features: {references: false}}) + } + + + describe '_findBibDocIds', -> + + beforeEach -> + @fakeProject = + rootFolder: [ + docs: [ + {name: 'one.bib', _id: 'aaa'}, + {name: 'two.txt', _id: 'bbb'}, + ] + folders: [ + {docs: [{name: 'three.bib', _id: 'ccc'}], folders: []} + ] + ] + @expectedIds = ['aaa', 'ccc'] + + it 'should select the correct docIds', -> + result = @handler._findBibDocIds(@fakeProject) + expect(result).to.deep.equal @expectedIds + + describe '_isFullIndex', -> + + beforeEach -> + @fakeProject = + owner_ref: + features: + references: false + @call = (callback) => + @handler._isFullIndex @fakeProject, callback + + describe 'with references feature on', -> + + beforeEach -> + @fakeProject.owner_ref.features.references = true + + it 'should return true', -> + @call (err, isFullIndex) => + expect(err).to.equal null + expect(isFullIndex).to.equal true + + describe 'with references feature off', -> + + beforeEach -> + @fakeProject.owner_ref.features.references = false + + it 'should return false', -> + @call (err, isFullIndex) => + expect(err).to.equal null + expect(isFullIndex).to.equal false + + + describe 'index', -> + + + + + # describe 'indexFile', ->