mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Start testing ReferencesSearch feature
This commit is contained in:
parent
a3cee72663
commit
8a991b0d06
4 changed files with 242 additions and 234 deletions
|
@ -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"
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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', ->
|
||||
|
||||
|
|
Loading…
Reference in a new issue