Start testing ReferencesSearch feature

This commit is contained in:
Shane Kilkelly 2016-01-26 14:29:23 +00:00
parent a3cee72663
commit 8a991b0d06
4 changed files with 242 additions and 234 deletions

View file

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

View file

@ -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}"

View file

@ -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()
}
describe 'getKeys', ->
beforeEach ->
@req = new MockRequest()
@req.params.Project_id = @project_id
@req.params.Project_id = @projectId
@req.body =
docIds: @docIds = ['aaa', 'bbb']
shouldBroadcast: false
@res = new MockResponse()
@data =
projectId: @project_id,
@res.json = sinon.stub()
@res.send = sinon.stub()
@fakeResponseData =
projectId: @projectId,
keys: ['one', 'two', 'three']
@ReferencesSearchHandler.getKeys.callsArgWith(1, null, @data)
describe 'when remote service works', ->
describe 'index', ->
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()
it 'should not call EditorRealTimController.emitToRoom', (done) ->
@call () =>
@EditorRealTimeController.emitToRoom.callCount.should.equal 0
done()
describe 'with docIds set to ALL', ->
beforeEach ->
@req = new MockRequest()
@req.params.Project_id = @project_id
@res = new MockResponse()
@ProjectLocator.findElement.callsArgWith(1, null, {})
@ReferencesSearchHandler.indexFile.callsArgWith(2, null)
@req.body.docIds = 'ALL'
describe 'with a valid doc_id', ->
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 ->
@req.body = {docId: @doc_id}
@ReferencesSearchHandler.index.callsArgWith(2, new Error('woops'), null)
it 'should produce a 200 response', (done) ->
@res.send = (status) =>
status.should.equal 200
it 'should produce an error response', (done) ->
@call () =>
@res.send.callCount.should.equal 1
@res.send.calledWith(500).should.equal true
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
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
done()
@controller.indexFile(@req, @res)
describe 'without a doc_id', ->
describe 'when shouldBroadcast is true', ->
beforeEach ->
@req.body = {bad: true}
@ReferencesSearchHandler.index.callsArgWith(2, null, @fakeResponseData)
@req.body.shouldBroadcast = true
it 'should produce a 400 response', (done) ->
@res.send = (status) =>
status.should.equal 400
it 'should call EditorRealTimeController.emitToRoom', (done) ->
@call () =>
@EditorRealTimeController.emitToRoom.callCount.should.equal 1
done()
@controller.indexFile(@req, @res)
describe 'when the ProjectLocator cannot find the doc', ->
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()
it 'should still return data', (done) ->
@call () =>
@res.json.callCount.should.equal 1
@res.json.calledWith(@fakeResponseData).should.equal true
done()
describe 'with missing docIds', ->
beforeEach ->
@req.body = {docId: 'some_weird_id'}
@ProjectLocator.findElement.callsArgWith(1, new Error('not found'), null)
@ReferencesSearchHandler.indexFile.callsArgWith(2, null)
delete @req.body.docIds
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', ->
describe 'with invalid docIds', ->
beforeEach ->
@req.body = {docId: @doc_id}
@ProjectLocator.findElement.callsArgWith(1, null, {})
@ReferencesSearchHandler.indexFile
.callsArgWith(2, new Error('something went wrong'))
@req.body.docIds = 42
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 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)

View file

@ -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', ->