mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge branch 'per-user-containers-part-2'
Conflicts: app/coffee/Features/Compile/ClsiManager.coffee app/coffee/Features/Compile/CompileController.coffee app/coffee/Features/Compile/CompileManager.coffee
This commit is contained in:
commit
49a7c3c27b
8 changed files with 151 additions and 91 deletions
|
@ -13,7 +13,7 @@ ClsiFormatChecker = require("./ClsiFormatChecker")
|
||||||
|
|
||||||
module.exports = ClsiManager =
|
module.exports = ClsiManager =
|
||||||
|
|
||||||
sendRequest: (project_id, options = {}, callback = (error, status, outputFiles, clsiServerId, validationProblems) ->) ->
|
sendRequest: (project_id, user_id, options = {}, callback = (error, status, outputFiles, clsiServerId, validationProblems) ->) ->
|
||||||
ClsiManager._buildRequest project_id, options, (error, req) ->
|
ClsiManager._buildRequest project_id, options, (error, req) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
logger.log project_id: project_id, "sending compile to CLSI"
|
logger.log project_id: project_id, "sending compile to CLSI"
|
||||||
|
@ -24,26 +24,25 @@ module.exports = ClsiManager =
|
||||||
if validationProblems?
|
if validationProblems?
|
||||||
logger.log project_id:project_id, validationProblems:validationProblems, "problems with users latex before compile was attempted"
|
logger.log project_id:project_id, validationProblems:validationProblems, "problems with users latex before compile was attempted"
|
||||||
return callback(null, "validation-problems", null, null, validationProblems)
|
return callback(null, "validation-problems", null, null, validationProblems)
|
||||||
ClsiManager._postToClsi project_id, req, options.compileGroup, (error, response) ->
|
ClsiManager._postToClsi project_id, user_id, req, options.compileGroup, (error, response) ->
|
||||||
if error?
|
if error?
|
||||||
logger.err err:error, project_id:project_id, "error sending request to clsi"
|
logger.err err:error, project_id:project_id, "error sending request to clsi"
|
||||||
return callback(error)
|
return callback(error)
|
||||||
logger.log project_id: project_id, outputFilesLength: response?.outputFiles?.length, status: response?.status, "received compile response from CLSI"
|
logger.log project_id: project_id, outputFilesLength: response?.outputFiles?.length, status: response?.status, "received compile response from CLSI"
|
||||||
ClsiCookieManager._getServerId project_id, (err, clsiServerId)->
|
ClsiCookieManager._getServerId project_id, (err, clsiServerId)->
|
||||||
if err?
|
if err?
|
||||||
logger.err err:err, project_id:project_id, "error getting server id"
|
logger.err err:err, project_id:project_id, "error getting server id"
|
||||||
return callback(err)
|
return callback(err)
|
||||||
outputFiles = ClsiManager._parseOutputFiles(project_id, response?.compile?.outputFiles)
|
outputFiles = ClsiManager._parseOutputFiles(project_id, response?.compile?.outputFiles)
|
||||||
callback(null, response?.compile?.status, outputFiles, clsiServerId)
|
callback(null, response?.compile?.status, outputFiles, clsiServerId)
|
||||||
|
|
||||||
deleteAuxFiles: (project_id, options, callback = (error) ->) ->
|
deleteAuxFiles: (project_id, user_id, options, callback = (error) ->) ->
|
||||||
compilerUrl = @_getCompilerUrl(options?.compileGroup)
|
compilerUrl = @_getCompilerUrl(options?.compileGroup, project_id, user_id)
|
||||||
opts =
|
opts =
|
||||||
url:"#{compilerUrl}/project/#{project_id}"
|
url:compilerUrl
|
||||||
method:"DELETE"
|
method:"DELETE"
|
||||||
ClsiManager._makeRequest project_id, opts, callback
|
ClsiManager._makeRequest project_id, opts, callback
|
||||||
|
|
||||||
|
|
||||||
_makeRequest: (project_id, opts, callback)->
|
_makeRequest: (project_id, opts, callback)->
|
||||||
ClsiCookieManager.getCookieJar project_id, (err, jar)->
|
ClsiCookieManager.getCookieJar project_id, (err, jar)->
|
||||||
if err?
|
if err?
|
||||||
|
@ -60,14 +59,17 @@ module.exports = ClsiManager =
|
||||||
|
|
||||||
return callback err, response, body
|
return callback err, response, body
|
||||||
|
|
||||||
|
_getCompilerUrl: (compileGroup, project_id, user_id, action) ->
|
||||||
|
host = Settings.apis.clsi.url
|
||||||
|
path = "/project/#{project_id}"
|
||||||
|
path += "/user/#{user_id}" if user_id?
|
||||||
|
path += "/#{action}" if action?
|
||||||
|
return "#{host}#{path}"
|
||||||
|
|
||||||
_getCompilerUrl: (compileGroup) ->
|
_postToClsi: (project_id, user_id, req, compileGroup, callback = (error, response) ->) ->
|
||||||
return Settings.apis.clsi.url
|
compileUrl = @_getCompilerUrl(compileGroup, project_id, user_id, "compile")
|
||||||
|
opts =
|
||||||
_postToClsi: (project_id, req, compileGroup, callback = (error, response) ->) ->
|
url: compileUrl
|
||||||
compilerUrl = Settings.apis.clsi.url
|
|
||||||
opts =
|
|
||||||
url: "#{compilerUrl}/project/#{project_id}/compile"
|
|
||||||
json: req
|
json: req
|
||||||
method: "POST"
|
method: "POST"
|
||||||
ClsiManager._makeRequest project_id, opts, (error, response, body) ->
|
ClsiManager._makeRequest project_id, opts, (error, response, body) ->
|
||||||
|
@ -142,15 +144,15 @@ module.exports = ClsiManager =
|
||||||
resources: resources
|
resources: resources
|
||||||
}
|
}
|
||||||
|
|
||||||
wordCount: (project_id, file, options, callback = (error, response) ->) ->
|
wordCount: (project_id, user_id, file, options, callback = (error, response) ->) ->
|
||||||
ClsiManager._buildRequest project_id, options, (error, req) ->
|
ClsiManager._buildRequest project_id, options, (error, req) ->
|
||||||
compilerUrl = ClsiManager._getCompilerUrl(options?.compileGroup)
|
|
||||||
filename = file || req?.compile?.rootResourcePath
|
filename = file || req?.compile?.rootResourcePath
|
||||||
wordcount_url = "#{compilerUrl}/project/#{project_id}/wordcount?file=#{encodeURIComponent(filename)}"
|
wordcount_url = ClsiManager._getCompilerUrl(options?.compileGroup, project_id, user_id, "wordcount")
|
||||||
if req.compile.options.imageName?
|
|
||||||
wordcount_url += "&image=#{encodeURIComponent(req.compile.options.imageName)}"
|
|
||||||
opts =
|
opts =
|
||||||
url: wordcount_url
|
url: wordcount_url
|
||||||
|
qs:
|
||||||
|
file: filename
|
||||||
|
image: req.compile.options.imageName
|
||||||
method: "GET"
|
method: "GET"
|
||||||
ClsiManager._makeRequest project_id, opts, (error, response, body) ->
|
ClsiManager._makeRequest project_id, opts, (error, response, body) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
|
|
|
@ -29,7 +29,9 @@ module.exports = CompileController =
|
||||||
options.compiler = req.body.compiler
|
options.compiler = req.body.compiler
|
||||||
if req.body?.draft
|
if req.body?.draft
|
||||||
options.draft = req.body.draft
|
options.draft = req.body.draft
|
||||||
logger.log {options, project_id}, "got compile request"
|
if req.query?.isolated is "true"
|
||||||
|
options.isolated = true
|
||||||
|
logger.log {options:options, project_id:project_id, user_id:user_id}, "got compile request"
|
||||||
CompileManager.compile project_id, user_id, options, (error, status, outputFiles, clsiServerId, limits, validationProblems) ->
|
CompileManager.compile project_id, user_id, options, (error, status, outputFiles, clsiServerId, limits, validationProblems) ->
|
||||||
return next(error) if error?
|
return next(error) if error?
|
||||||
res.contentType("application/json")
|
res.contentType("application/json")
|
||||||
|
@ -41,6 +43,13 @@ module.exports = CompileController =
|
||||||
validationProblems:validationProblems
|
validationProblems:validationProblems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_compileAsUser: (req, callback) ->
|
||||||
|
isolated = req.query?.isolated is "true"
|
||||||
|
if isolated
|
||||||
|
AuthenticationController.getLoggedInUserId req, callback
|
||||||
|
else
|
||||||
|
callback()
|
||||||
|
|
||||||
downloadPdf: (req, res, next = (error) ->)->
|
downloadPdf: (req, res, next = (error) ->)->
|
||||||
Metrics.inc "pdf-downloads"
|
Metrics.inc "pdf-downloads"
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
|
@ -77,28 +86,40 @@ module.exports = CompileController =
|
||||||
|
|
||||||
deleteAuxFiles: (req, res, next) ->
|
deleteAuxFiles: (req, res, next) ->
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
CompileManager.deleteAuxFiles project_id, (error) ->
|
CompileController._compileAsUser req, (error, user_id) ->
|
||||||
return next(error) if error?
|
return next(error) if error?
|
||||||
res.sendStatus(200)
|
CompileManager.deleteAuxFiles project_id, user_id, (error) ->
|
||||||
|
return next(error) if error?
|
||||||
|
res.sendStatus(200)
|
||||||
|
|
||||||
compileAndDownloadPdf: (req, res, next)->
|
compileAndDownloadPdf: (req, res, next)->
|
||||||
project_id = req.params.project_id
|
project_id = req.params.project_id
|
||||||
CompileManager.compile project_id, null, {}, (err)->
|
CompileController._compileAsUser req, (error, user_id) ->
|
||||||
if err?
|
return next(error) if error?
|
||||||
logger.err err:err, project_id:project_id, "something went wrong compile and downloading pdf"
|
CompileManager.compile project_id, user_id, {}, (err)->
|
||||||
res.sendStatus 500
|
if err?
|
||||||
url = "/project/#{project_id}/output/output.pdf"
|
logger.err err:err, project_id:project_id, "something went wrong compile and downloading pdf"
|
||||||
CompileController.proxyToClsi project_id, url, req, res, next
|
res.sendStatus 500
|
||||||
|
url = "/project/#{project_id}/output/output.pdf"
|
||||||
|
CompileController.proxyToClsi project_id, user_id, url, req, res, next
|
||||||
|
|
||||||
getFileFromClsi: (req, res, next = (error) ->) ->
|
getFileFromClsi: (req, res, next = (error) ->) ->
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
build = req.params.build
|
build_id = req.params.build_id
|
||||||
if build?
|
user_id = req.params.user_id
|
||||||
url = "/project/#{project_id}/build/#{build}/output/#{req.params.file}"
|
if user_id? and build_id?
|
||||||
|
url = "/project/#{project_id}/user/#{user_id}/build/#{build_id}/output/#{req.params.file}"
|
||||||
|
else if build_id?
|
||||||
|
url = "/project/#{project_id}/build/#{build_id}/output/#{req.params.file}"
|
||||||
else
|
else
|
||||||
url = "/project/#{project_id}/output/#{req.params.file}"
|
url = "/project/#{project_id}/output/#{req.params.file}"
|
||||||
CompileController.proxyToClsi(project_id, url, req, res, next)
|
CompileController.proxyToClsi(project_id, url, req, res, next)
|
||||||
|
|
||||||
|
_getUrl: (project_id, user_id, action) ->
|
||||||
|
path = "/project/#{project_id}"
|
||||||
|
path += "/user/#{user_id}" if user_id?
|
||||||
|
return "#{path}/#{action}"
|
||||||
|
|
||||||
proxySyncPdf: (req, res, next = (error) ->) ->
|
proxySyncPdf: (req, res, next = (error) ->) ->
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
{page, h, v} = req.query
|
{page, h, v} = req.query
|
||||||
|
@ -108,8 +129,12 @@ module.exports = CompileController =
|
||||||
return next(new Error("invalid h parameter"))
|
return next(new Error("invalid h parameter"))
|
||||||
if not v?.match(/^\d+\.\d+$/)
|
if not v?.match(/^\d+\.\d+$/)
|
||||||
return next(new Error("invalid v parameter"))
|
return next(new Error("invalid v parameter"))
|
||||||
destination = {url: "/project/#{project_id}/sync/pdf", qs: {page, h, v}}
|
url = CompileController._getUrl(project_id, user_id, "sync/pdf")
|
||||||
CompileController.proxyToClsi(project_id, destination, req, res, next)
|
destination = {url: url, qs: {page, h, v}}
|
||||||
|
# whether this request is going to a per-user container
|
||||||
|
CompileController._compileAsUser req, (error, user_id) ->
|
||||||
|
return next(error) if error?
|
||||||
|
CompileController.proxyToClsi(project_id, destination, req, res, next)
|
||||||
|
|
||||||
proxySyncCode: (req, res, next = (error) ->) ->
|
proxySyncCode: (req, res, next = (error) ->) ->
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
|
@ -120,8 +145,11 @@ module.exports = CompileController =
|
||||||
return next(new Error("invalid line parameter"))
|
return next(new Error("invalid line parameter"))
|
||||||
if not column?.match(/^\d+$/)
|
if not column?.match(/^\d+$/)
|
||||||
return next(new Error("invalid column parameter"))
|
return next(new Error("invalid column parameter"))
|
||||||
destination = {url:"/project/#{project_id}/sync/code", qs: {file, line, column}}
|
url = CompileController._getUrl(project_id, user_id, "sync/code")
|
||||||
CompileController.proxyToClsi(project_id, destination, req, res, next)
|
destination = {url:url, qs: {file, line, column}}
|
||||||
|
CompileController._compileAsUser req, (error, user_id) ->
|
||||||
|
return next(error) if error?
|
||||||
|
CompileController.proxyToClsi(project_id, destination, req, res, next)
|
||||||
|
|
||||||
proxyToClsi: (project_id, url, req, res, next = (error) ->) ->
|
proxyToClsi: (project_id, url, req, res, next = (error) ->) ->
|
||||||
if req.query?.compileGroup
|
if req.query?.compileGroup
|
||||||
|
@ -166,7 +194,9 @@ module.exports = CompileController =
|
||||||
wordCount: (req, res, next) ->
|
wordCount: (req, res, next) ->
|
||||||
project_id = req.params.Project_id
|
project_id = req.params.Project_id
|
||||||
file = req.query.file || false
|
file = req.query.file || false
|
||||||
CompileManager.wordCount project_id, file, (error, body) ->
|
CompileController._compileAsUser req, (error, user_id) ->
|
||||||
return next(error) if error?
|
return next(error) if error?
|
||||||
res.contentType("application/json")
|
CompileManager.wordCount project_id, user_id, file, (error, body) ->
|
||||||
res.send body
|
return next(error) if error?
|
||||||
|
res.contentType("application/json")
|
||||||
|
res.send body
|
||||||
|
|
|
@ -37,15 +37,17 @@ module.exports = CompileManager =
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
for key, value of limits
|
for key, value of limits
|
||||||
options[key] = value
|
options[key] = value
|
||||||
ClsiManager.sendRequest project_id, options, (error, status, outputFiles, clsiServerId, validationProblems) ->
|
# only pass user_id down to clsi if this is a per-user compile
|
||||||
|
compileAsUser = if options.isolated then user_id else undefined
|
||||||
|
ClsiManager.sendRequest project_id, compileAsUser, options, (error, status, outputFiles, clsiServerId, validationProblems) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
logger.log files: outputFiles, "output files"
|
logger.log files: outputFiles, "output files"
|
||||||
callback(null, status, outputFiles, clsiServerId, limits, validationProblems)
|
callback(null, status, outputFiles, clsiServerId, limits, validationProblems)
|
||||||
|
|
||||||
deleteAuxFiles: (project_id, callback = (error) ->) ->
|
deleteAuxFiles: (project_id, user_id, callback = (error) ->) ->
|
||||||
CompileManager.getProjectCompileLimits project_id, (error, limits) ->
|
CompileManager.getProjectCompileLimits project_id, (error, limits) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
ClsiManager.deleteAuxFiles project_id, limits, callback
|
ClsiManager.deleteAuxFiles project_id, user_id, limits, callback
|
||||||
|
|
||||||
getProjectCompileLimits: (project_id, callback = (error, limits) ->) ->
|
getProjectCompileLimits: (project_id, callback = (error, limits) ->) ->
|
||||||
Project.findById project_id, {owner_ref: 1}, (error, project) ->
|
Project.findById project_id, {owner_ref: 1}, (error, project) ->
|
||||||
|
@ -92,7 +94,7 @@ module.exports = CompileManager =
|
||||||
else
|
else
|
||||||
ProjectRootDocManager.setRootDocAutomatically project_id, callback
|
ProjectRootDocManager.setRootDocAutomatically project_id, callback
|
||||||
|
|
||||||
wordCount: (project_id, file, callback = (error) ->) ->
|
wordCount: (project_id, user_id, file, callback = (error) ->) ->
|
||||||
CompileManager.getProjectCompileLimits project_id, (error, limits) ->
|
CompileManager.getProjectCompileLimits project_id, (error, limits) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
ClsiManager.wordCount project_id, file, limits, callback
|
ClsiManager.wordCount project_id, user_id, file, limits, callback
|
||||||
|
|
|
@ -119,12 +119,25 @@ module.exports = class Router
|
||||||
((req, res, next) ->
|
((req, res, next) ->
|
||||||
params =
|
params =
|
||||||
"Project_id": req.params[0]
|
"Project_id": req.params[0]
|
||||||
"build": req.params[1]
|
"build_id": req.params[1]
|
||||||
"file": req.params[2]
|
"file": req.params[2]
|
||||||
req.params = params
|
req.params = params
|
||||||
next()
|
next()
|
||||||
), AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.getFileFromClsi
|
), AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.getFileFromClsi
|
||||||
|
|
||||||
|
# direct url access to output files for a specific user and build (query string not required)
|
||||||
|
webRouter.get /^\/project\/([^\/]*)\/user\/([0-9a-f]+)\/build\/([0-9a-f-]+)\/output\/(.*)$/,
|
||||||
|
((req, res, next) ->
|
||||||
|
params =
|
||||||
|
"Project_id": req.params[0]
|
||||||
|
"user_id": req.params[1]
|
||||||
|
"build_id": req.params[2]
|
||||||
|
"file": req.params[3]
|
||||||
|
req.params = params
|
||||||
|
next()
|
||||||
|
), AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.getFileFromClsi
|
||||||
|
|
||||||
|
|
||||||
webRouter.delete "/project/:Project_id/output", AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.deleteAuxFiles
|
webRouter.delete "/project/:Project_id/output", AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.deleteAuxFiles
|
||||||
webRouter.get "/project/:Project_id/sync/code", AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.proxySyncCode
|
webRouter.get "/project/:Project_id/sync/code", AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.proxySyncCode
|
||||||
webRouter.get "/project/:Project_id/sync/pdf", AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.proxySyncPdf
|
webRouter.get "/project/:Project_id/sync/pdf", AuthorizationMiddlewear.ensureUserCanReadProject, CompileController.proxySyncPdf
|
||||||
|
|
|
@ -5,6 +5,8 @@ define [
|
||||||
], (App, LogParser, BibLogParser) ->
|
], (App, LogParser, BibLogParser) ->
|
||||||
App.controller "PdfController", ($scope, $http, ide, $modal, synctex, event_tracking, localStorage) ->
|
App.controller "PdfController", ($scope, $http, ide, $modal, synctex, event_tracking, localStorage) ->
|
||||||
|
|
||||||
|
# enable per-user containers if querystring includes isolated=true
|
||||||
|
perUserCompile = window.location?.search?.match(/isolated=true/)? or undefined
|
||||||
autoCompile = true
|
autoCompile = true
|
||||||
|
|
||||||
# pdf.view = uncompiled | pdf | errors
|
# pdf.view = uncompiled | pdf | errors
|
||||||
|
@ -28,13 +30,16 @@ define [
|
||||||
|
|
||||||
sendCompileRequest = (options = {}) ->
|
sendCompileRequest = (options = {}) ->
|
||||||
url = "/project/#{$scope.project_id}/compile"
|
url = "/project/#{$scope.project_id}/compile"
|
||||||
|
params = {}
|
||||||
if options.isAutoCompile
|
if options.isAutoCompile
|
||||||
url += "?auto_compile=true"
|
params["auto_compile"]=true
|
||||||
|
if perUserCompile # send ?isolated=true for per-user compiles
|
||||||
|
params["isolated"] = true
|
||||||
return $http.post url, {
|
return $http.post url, {
|
||||||
rootDoc_id: options.rootDocOverride_id or null
|
rootDoc_id: options.rootDocOverride_id or null
|
||||||
draft: $scope.draft
|
draft: $scope.draft
|
||||||
_csrf: window.csrfToken
|
_csrf: window.csrfToken
|
||||||
}
|
}, {params: params}
|
||||||
|
|
||||||
parseCompileResponse = (response) ->
|
parseCompileResponse = (response) ->
|
||||||
|
|
||||||
|
@ -132,7 +137,6 @@ define [
|
||||||
opts =
|
opts =
|
||||||
method:"GET"
|
method:"GET"
|
||||||
params:
|
params:
|
||||||
build:file.build
|
|
||||||
clsiserverid:ide.clsiServerId
|
clsiserverid:ide.clsiServerId
|
||||||
if file.url? # FIXME clean this up when we have file.urls out consistently
|
if file.url? # FIXME clean this up when we have file.urls out consistently
|
||||||
opts.url = file.url
|
opts.url = file.url
|
||||||
|
@ -246,6 +250,7 @@ define [
|
||||||
method: "DELETE"
|
method: "DELETE"
|
||||||
params:
|
params:
|
||||||
clsiserverid:ide.clsiServerId
|
clsiserverid:ide.clsiServerId
|
||||||
|
isolated: perUserCompile
|
||||||
headers:
|
headers:
|
||||||
"X-Csrf-Token": window.csrfToken
|
"X-Csrf-Token": window.csrfToken
|
||||||
}
|
}
|
||||||
|
@ -329,6 +334,7 @@ define [
|
||||||
line: row + 1
|
line: row + 1
|
||||||
column: column
|
column: column
|
||||||
clsiserverid:ide.clsiServerId
|
clsiserverid:ide.clsiServerId
|
||||||
|
isolated: perUserCompile
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.success (data) ->
|
.success (data) ->
|
||||||
|
@ -357,6 +363,7 @@ define [
|
||||||
h: position.offset.left.toFixed(2)
|
h: position.offset.left.toFixed(2)
|
||||||
v: position.offset.top.toFixed(2)
|
v: position.offset.top.toFixed(2)
|
||||||
clsiserverid:ide.clsiServerId
|
clsiserverid:ide.clsiServerId
|
||||||
|
isolated: perUserCompile
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.success (data) ->
|
.success (data) ->
|
||||||
|
|
|
@ -31,6 +31,7 @@ describe "ClsiManager", ->
|
||||||
"request": @request = sinon.stub()
|
"request": @request = sinon.stub()
|
||||||
"./ClsiFormatChecker": @ClsiFormatChecker
|
"./ClsiFormatChecker": @ClsiFormatChecker
|
||||||
@project_id = "project-id"
|
@project_id = "project-id"
|
||||||
|
@user_id = "user-id"
|
||||||
@callback = sinon.stub()
|
@callback = sinon.stub()
|
||||||
|
|
||||||
describe "sendRequest", ->
|
describe "sendRequest", ->
|
||||||
|
@ -40,22 +41,22 @@ describe "ClsiManager", ->
|
||||||
|
|
||||||
describe "with a successful compile", ->
|
describe "with a successful compile", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager._postToClsi = sinon.stub().callsArgWith(3, null, {
|
@ClsiManager._postToClsi = sinon.stub().callsArgWith(4, null, {
|
||||||
compile:
|
compile:
|
||||||
status: @status = "success"
|
status: @status = "success"
|
||||||
outputFiles: [{
|
outputFiles: [{
|
||||||
url: "#{@settings.apis.clsi.url}/project/#{@project_id}/build/1234/output/output.pdf"
|
url: "#{@settings.apis.clsi.url}/project/#{@project_id}/user/#{@user_id}/build/1234/output/output.pdf"
|
||||||
path: "output.pdf"
|
path: "output.pdf"
|
||||||
type: "pdf"
|
type: "pdf"
|
||||||
build: 1234
|
build: 1234
|
||||||
},{
|
},{
|
||||||
url: "#{@settings.apis.clsi.url}/project/#{@project_id}/build/1234/output/output.log"
|
url: "#{@settings.apis.clsi.url}/project/#{@project_id}/user/#{@user_id}/build/1234/output/output.log"
|
||||||
path: "output.log"
|
path: "output.log"
|
||||||
type: "log"
|
type: "log"
|
||||||
build: 1234
|
build: 1234
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
@ClsiManager.sendRequest @project_id, {compileGroup:"standard"}, @callback
|
@ClsiManager.sendRequest @project_id, @user_id, {compileGroup:"standard"}, @callback
|
||||||
|
|
||||||
it "should build the request", ->
|
it "should build the request", ->
|
||||||
@ClsiManager._buildRequest
|
@ClsiManager._buildRequest
|
||||||
|
@ -64,17 +65,17 @@ describe "ClsiManager", ->
|
||||||
|
|
||||||
it "should send the request to the CLSI", ->
|
it "should send the request to the CLSI", ->
|
||||||
@ClsiManager._postToClsi
|
@ClsiManager._postToClsi
|
||||||
.calledWith(@project_id, @request, "standard")
|
.calledWith(@project_id, @user_id, @request, "standard")
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should call the callback with the status and output files", ->
|
it "should call the callback with the status and output files", ->
|
||||||
outputFiles = [{
|
outputFiles = [{
|
||||||
url: "/project/#{@project_id}/build/1234/output/output.pdf"
|
url: "/project/#{@project_id}/user/#{@user_id}/build/1234/output/output.pdf"
|
||||||
path: "output.pdf"
|
path: "output.pdf"
|
||||||
type: "pdf"
|
type: "pdf"
|
||||||
build: 1234
|
build: 1234
|
||||||
},{
|
},{
|
||||||
url: "/project/#{@project_id}/build/1234/output/output.log"
|
url: "/project/#{@project_id}/user/#{@user_id}/build/1234/output/output.log"
|
||||||
path: "output.log"
|
path: "output.log"
|
||||||
type: "log"
|
type: "log"
|
||||||
build: 1234
|
build: 1234
|
||||||
|
@ -83,11 +84,11 @@ describe "ClsiManager", ->
|
||||||
|
|
||||||
describe "with a failed compile", ->
|
describe "with a failed compile", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager._postToClsi = sinon.stub().callsArgWith(3, null, {
|
@ClsiManager._postToClsi = sinon.stub().callsArgWith(4, null, {
|
||||||
compile:
|
compile:
|
||||||
status: @status = "failure"
|
status: @status = "failure"
|
||||||
})
|
})
|
||||||
@ClsiManager.sendRequest @project_id, {}, @callback
|
@ClsiManager.sendRequest @project_id, @user_id, {}, @callback
|
||||||
|
|
||||||
it "should call the callback with a failure statue", ->
|
it "should call the callback with a failure statue", ->
|
||||||
@callback.calledWith(null, @status).should.equal true
|
@callback.calledWith(null, @status).should.equal true
|
||||||
|
@ -98,11 +99,11 @@ describe "ClsiManager", ->
|
||||||
|
|
||||||
describe "with the standard compileGroup", ->
|
describe "with the standard compileGroup", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager.deleteAuxFiles @project_id, {compileGroup: "standard"}, @callback
|
@ClsiManager.deleteAuxFiles @project_id, @user_id, {compileGroup: "standard"}, @callback
|
||||||
|
|
||||||
it "should call the delete method in the standard CLSI", ->
|
it "should call the delete method in the standard CLSI", ->
|
||||||
@ClsiManager._makeRequest
|
@ClsiManager._makeRequest
|
||||||
.calledWith(@project_id, { method:"DELETE", url:"#{@settings.apis.clsi.url}/project/#{@project_id}"})
|
.calledWith(@project_id, { method:"DELETE", url:"#{@settings.apis.clsi.url}/project/#{@project_id}/user/#{@user_id}"})
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should call the callback", ->
|
it "should call the callback", ->
|
||||||
|
@ -242,10 +243,10 @@ describe "ClsiManager", ->
|
||||||
describe "successfully", ->
|
describe "successfully", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager._makeRequest = sinon.stub().callsArgWith(2, null, {statusCode: 204}, @body = { mock: "foo" })
|
@ClsiManager._makeRequest = sinon.stub().callsArgWith(2, null, {statusCode: 204}, @body = { mock: "foo" })
|
||||||
@ClsiManager._postToClsi @project_id, @req, "standard", @callback
|
@ClsiManager._postToClsi @project_id, @user_id, @req, "standard", @callback
|
||||||
|
|
||||||
it 'should send the request to the CLSI', ->
|
it 'should send the request to the CLSI', ->
|
||||||
url = "#{@settings.apis.clsi.url}/project/#{@project_id}/compile"
|
url = "#{@settings.apis.clsi.url}/project/#{@project_id}/user/#{@user_id}/compile"
|
||||||
@ClsiManager._makeRequest.calledWith(@project_id, {
|
@ClsiManager._makeRequest.calledWith(@project_id, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: url
|
url: url
|
||||||
|
@ -258,7 +259,7 @@ describe "ClsiManager", ->
|
||||||
describe "when the CLSI returns an error", ->
|
describe "when the CLSI returns an error", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager._makeRequest = sinon.stub().callsArgWith(2, null, {statusCode: 500}, @body = { mock: "foo" })
|
@ClsiManager._makeRequest = sinon.stub().callsArgWith(2, null, {statusCode: 500}, @body = { mock: "foo" })
|
||||||
@ClsiManager._postToClsi @project_id, @req, "standard", @callback
|
@ClsiManager._postToClsi @project_id, @user_id, @req, "standard", @callback
|
||||||
|
|
||||||
it "should call the callback with the body and the error", ->
|
it "should call the callback with the body and the error", ->
|
||||||
@callback.calledWith(new Error("CLSI returned non-success code: 500"), @body).should.equal true
|
@callback.calledWith(new Error("CLSI returned non-success code: 500"), @body).should.equal true
|
||||||
|
@ -268,37 +269,36 @@ describe "ClsiManager", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager._makeRequest = sinon.stub().callsArgWith(2, null, {statusCode: 200}, @body = { mock: "foo" })
|
@ClsiManager._makeRequest = sinon.stub().callsArgWith(2, null, {statusCode: 200}, @body = { mock: "foo" })
|
||||||
@ClsiManager._buildRequest = sinon.stub().callsArgWith(2, null, @req = { compile: { rootResourcePath: "rootfile.text", options: {} } })
|
@ClsiManager._buildRequest = sinon.stub().callsArgWith(2, null, @req = { compile: { rootResourcePath: "rootfile.text", options: {} } })
|
||||||
@ClsiManager._getCompilerUrl = sinon.stub().returns "compiler.url"
|
|
||||||
|
|
||||||
describe "with root file", ->
|
describe "with root file", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager.wordCount @project_id, false, {}, @callback
|
@ClsiManager.wordCount @project_id, @user_id, false, {}, @callback
|
||||||
|
|
||||||
it "should call wordCount with root file", ->
|
it "should call wordCount with root file", ->
|
||||||
@ClsiManager._makeRequest
|
@ClsiManager._makeRequest
|
||||||
.calledWith(@project_id, { method: "GET", url: "compiler.url/project/#{@project_id}/wordcount?file=rootfile.text" })
|
.calledWith(@project_id, {method: "GET", url: "http://clsi.example.com/project/#{@project_id}/user/#{@user_id}/wordcount", qs: {file: "rootfile.text",image:undefined}})
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should call the callback", ->
|
it "should call the callback", ->
|
||||||
@callback.called.should.equal true
|
@callback.called.should.equal true
|
||||||
|
|
||||||
describe "with param file", ->
|
describe "with param file", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@ClsiManager.wordCount @project_id, "main.tex", {}, @callback
|
@ClsiManager.wordCount @project_id, @user_id, "main.tex", {}, @callback
|
||||||
|
|
||||||
it "should call wordCount with param file", ->
|
it "should call wordCount with param file", ->
|
||||||
@ClsiManager._makeRequest
|
@ClsiManager._makeRequest
|
||||||
.calledWith(@project_id, { method: "GET", url: "compiler.url/project/#{@project_id}/wordcount?file=main.tex" })
|
.calledWith(@project_id, { method: "GET", url: "http://clsi.example.com/project/#{@project_id}/user/#{@user_id}/wordcount", qs:{file:"main.tex",image:undefined}})
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
describe "with image", ->
|
describe "with image", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@req.compile.options.imageName = @image = "example.com/mock/image"
|
@req.compile.options.imageName = @image = "example.com/mock/image"
|
||||||
@ClsiManager.wordCount @project_id, "main.tex", {}, @callback
|
@ClsiManager.wordCount @project_id, @user_id, "main.tex", {}, @callback
|
||||||
|
|
||||||
it "should call wordCount with file and image", ->
|
it "should call wordCount with file and image", ->
|
||||||
@ClsiManager._makeRequest
|
@ClsiManager._makeRequest
|
||||||
.calledWith(@project_id, { method: "GET", url: "compiler.url/project/#{@project_id}/wordcount?file=main.tex&image=#{encodeURIComponent(@image)}" })
|
.calledWith(@project_id, { method: "GET", url: "http://clsi.example.com/project/#{@project_id}/user/#{@user_id}/wordcount", qs:{file:"main.tex",image:@image}})
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,13 +45,13 @@ describe "CompileController", ->
|
||||||
@next = sinon.stub()
|
@next = sinon.stub()
|
||||||
@req = new MockRequest()
|
@req = new MockRequest()
|
||||||
@res = new MockResponse()
|
@res = new MockResponse()
|
||||||
|
@AuthenticationController.getLoggedInUserId = sinon.stub().callsArgWith(1, null, @user_id = "mock-user-id")
|
||||||
|
|
||||||
describe "compile", ->
|
describe "compile", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@req.params =
|
@req.params =
|
||||||
Project_id: @project_id
|
Project_id: @project_id
|
||||||
@req.session = {}
|
@req.session = {}
|
||||||
@AuthenticationController.getLoggedInUserId = sinon.stub().callsArgWith(1, null, @user_id = "mock-user-id")
|
|
||||||
@CompileManager.compile = sinon.stub().callsArgWith(3, null, @status = "success", @outputFiles = ["mock-output-files"])
|
@CompileManager.compile = sinon.stub().callsArgWith(3, null, @status = "success", @outputFiles = ["mock-output-files"])
|
||||||
|
|
||||||
describe "when not an auto compile", ->
|
describe "when not an auto compile", ->
|
||||||
|
@ -317,7 +317,7 @@ describe "CompileController", ->
|
||||||
|
|
||||||
describe "deleteAuxFiles", ->
|
describe "deleteAuxFiles", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@CompileManager.deleteAuxFiles = sinon.stub().callsArg(1)
|
@CompileManager.deleteAuxFiles = sinon.stub().callsArg(2)
|
||||||
@req.params =
|
@req.params =
|
||||||
Project_id: @project_id
|
Project_id: @project_id
|
||||||
@res.sendStatus = sinon.stub()
|
@res.sendStatus = sinon.stub()
|
||||||
|
@ -338,6 +338,8 @@ describe "CompileController", ->
|
||||||
@req =
|
@req =
|
||||||
params:
|
params:
|
||||||
project_id:@project_id
|
project_id:@project_id
|
||||||
|
query:
|
||||||
|
isolated: "true"
|
||||||
@CompileManager.compile.callsArgWith(3)
|
@CompileManager.compile.callsArgWith(3)
|
||||||
@CompileController.proxyToClsi = sinon.stub()
|
@CompileController.proxyToClsi = sinon.stub()
|
||||||
@res =
|
@res =
|
||||||
|
@ -350,21 +352,25 @@ describe "CompileController", ->
|
||||||
|
|
||||||
it "should proxy the res to the clsi with correct url", (done)->
|
it "should proxy the res to the clsi with correct url", (done)->
|
||||||
@CompileController.compileAndDownloadPdf @req, @res
|
@CompileController.compileAndDownloadPdf @req, @res
|
||||||
@CompileController.proxyToClsi.calledWith(@project_id, "/project/#{@project_id}/output/output.pdf", @req, @res).should.equal true
|
sinon.assert.calledWith @CompileController.proxyToClsi, @project_id, @user_id, "/project/#{@project_id}/output/output.pdf", @req, @res
|
||||||
|
|
||||||
|
@CompileController.proxyToClsi.calledWith(@project_id, @user_id, "/project/#{@project_id}/output/output.pdf", @req, @res).should.equal true
|
||||||
done()
|
done()
|
||||||
|
|
||||||
describe "wordCount", ->
|
describe "wordCount", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@CompileManager.wordCount = sinon.stub().callsArgWith(2, null, {content:"body"})
|
@CompileManager.wordCount = sinon.stub().callsArgWith(3, null, {content:"body"})
|
||||||
@req.params =
|
@req.params =
|
||||||
Project_id: @project_id
|
Project_id: @project_id
|
||||||
|
@req.query =
|
||||||
|
isolated: "true"
|
||||||
@res.send = sinon.stub()
|
@res.send = sinon.stub()
|
||||||
@res.contentType = sinon.stub()
|
@res.contentType = sinon.stub()
|
||||||
@CompileController.wordCount @req, @res, @next
|
@CompileController.wordCount @req, @res, @next
|
||||||
|
|
||||||
it "should proxy to the CLSI", ->
|
it "should proxy to the CLSI", ->
|
||||||
@CompileManager.wordCount
|
@CompileManager.wordCount
|
||||||
.calledWith(@project_id, false)
|
.calledWith(@project_id, @user_id, false)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should return a 200 and body", ->
|
it "should return a 200 and body", ->
|
||||||
|
|
|
@ -42,7 +42,7 @@ describe "CompileManager", ->
|
||||||
@CompileManager._ensureRootDocumentIsSet = sinon.stub().callsArgWith(1, null)
|
@CompileManager._ensureRootDocumentIsSet = sinon.stub().callsArgWith(1, null)
|
||||||
@DocumentUpdaterHandler.flushProjectToMongo = sinon.stub().callsArgWith(1, null)
|
@DocumentUpdaterHandler.flushProjectToMongo = sinon.stub().callsArgWith(1, null)
|
||||||
@CompileManager.getProjectCompileLimits = sinon.stub().callsArgWith(1, null, @limits)
|
@CompileManager.getProjectCompileLimits = sinon.stub().callsArgWith(1, null, @limits)
|
||||||
@ClsiManager.sendRequest = sinon.stub().callsArgWith(2, null, @status = "mock-status", @outputFiles = "mock output files", @output = "mock output")
|
@ClsiManager.sendRequest = sinon.stub().callsArgWith(3, null, @status = "mock-status", @outputFiles = "mock output files", @output = "mock output")
|
||||||
|
|
||||||
describe "succesfully", ->
|
describe "succesfully", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
@ -71,7 +71,7 @@ describe "CompileManager", ->
|
||||||
|
|
||||||
it "should run the compile with the compile limits", ->
|
it "should run the compile with the compile limits", ->
|
||||||
@ClsiManager.sendRequest
|
@ClsiManager.sendRequest
|
||||||
.calledWith(@project_id, {
|
.calledWith(@project_id, undefined, {
|
||||||
timeout: @limits.timeout
|
timeout: @limits.timeout
|
||||||
})
|
})
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
@ -135,8 +135,8 @@ describe "CompileManager", ->
|
||||||
describe "deleteAuxFiles", ->
|
describe "deleteAuxFiles", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@CompileManager.getProjectCompileLimits = sinon.stub().callsArgWith 1, null, @limits = { compileGroup: "mock-compile-group" }
|
@CompileManager.getProjectCompileLimits = sinon.stub().callsArgWith 1, null, @limits = { compileGroup: "mock-compile-group" }
|
||||||
@ClsiManager.deleteAuxFiles = sinon.stub().callsArg(2)
|
@ClsiManager.deleteAuxFiles = sinon.stub().callsArg(3)
|
||||||
@CompileManager.deleteAuxFiles @project_id, @callback
|
@CompileManager.deleteAuxFiles @project_id, @user_id, @callback
|
||||||
|
|
||||||
it "should look up the compile group to use", ->
|
it "should look up the compile group to use", ->
|
||||||
@CompileManager.getProjectCompileLimits
|
@CompileManager.getProjectCompileLimits
|
||||||
|
@ -145,7 +145,7 @@ describe "CompileManager", ->
|
||||||
|
|
||||||
it "should delete the aux files", ->
|
it "should delete the aux files", ->
|
||||||
@ClsiManager.deleteAuxFiles
|
@ClsiManager.deleteAuxFiles
|
||||||
.calledWith(@project_id, @limits)
|
.calledWith(@project_id, @user_id, @limits)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should call the callback", ->
|
it "should call the callback", ->
|
||||||
|
@ -260,8 +260,8 @@ describe "CompileManager", ->
|
||||||
describe "wordCount", ->
|
describe "wordCount", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@CompileManager.getProjectCompileLimits = sinon.stub().callsArgWith 1, null, @limits = { compileGroup: "mock-compile-group" }
|
@CompileManager.getProjectCompileLimits = sinon.stub().callsArgWith 1, null, @limits = { compileGroup: "mock-compile-group" }
|
||||||
@ClsiManager.wordCount = sinon.stub().callsArg(3)
|
@ClsiManager.wordCount = sinon.stub().callsArg(4)
|
||||||
@CompileManager.wordCount @project_id, false, @callback
|
@CompileManager.wordCount @project_id, @user_id, false, @callback
|
||||||
|
|
||||||
it "should look up the compile group to use", ->
|
it "should look up the compile group to use", ->
|
||||||
@CompileManager.getProjectCompileLimits
|
@CompileManager.getProjectCompileLimits
|
||||||
|
@ -270,7 +270,7 @@ describe "CompileManager", ->
|
||||||
|
|
||||||
it "should call wordCount for project", ->
|
it "should call wordCount for project", ->
|
||||||
@ClsiManager.wordCount
|
@ClsiManager.wordCount
|
||||||
.calledWith(@project_id, false, @limits)
|
.calledWith(@project_id, @user_id, false, @limits)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should call the callback", ->
|
it "should call the callback", ->
|
||||||
|
|
Loading…
Reference in a new issue