2019-05-29 05:21:06 -04:00
|
|
|
/* eslint-disable
|
|
|
|
camelcase,
|
|
|
|
max-len,
|
|
|
|
no-return-assign,
|
|
|
|
no-unused-vars,
|
|
|
|
*/
|
|
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
// Fix any style issues and re-enable lint.
|
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
|
|
|
const sinon = require('sinon')
|
2021-03-31 08:20:55 -04:00
|
|
|
const { assert, expect } = require('chai')
|
2019-05-29 05:21:06 -04:00
|
|
|
const modulePath = '../../../../app/src/Features/Compile/CompileController.js'
|
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const MockRequest = require('../helpers/MockRequest')
|
|
|
|
const MockResponse = require('../helpers/MockResponse')
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('CompileController', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.user_id = 'wat'
|
|
|
|
this.user = {
|
|
|
|
_id: this.user_id,
|
|
|
|
email: 'user@example.com',
|
|
|
|
features: {
|
|
|
|
compileGroup: 'premium',
|
2021-04-27 03:52:58 -04:00
|
|
|
compileTimeout: 100,
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.CompileManager = { compile: sinon.stub() }
|
|
|
|
this.ClsiManager = {}
|
|
|
|
this.UserGetter = { getUser: sinon.stub() }
|
|
|
|
this.RateLimiter = { addCount: sinon.stub() }
|
|
|
|
this.settings = {
|
|
|
|
apis: {
|
|
|
|
clsi: {
|
2021-04-27 03:52:58 -04:00
|
|
|
url: 'clsi.example.com',
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
clsi_priority: {
|
2021-04-27 03:52:58 -04:00
|
|
|
url: 'clsi-priority.example.com',
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
defaultFeatures: {
|
|
|
|
compileGroup: 'standard',
|
2021-04-27 03:52:58 -04:00
|
|
|
compileTimeout: 60,
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.jar = { cookie: 'stuff' }
|
|
|
|
this.ClsiCookieManager = {
|
2022-05-13 05:35:31 -04:00
|
|
|
getCookieJar: sinon.stub().yields(null, this.jar),
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2021-07-28 04:51:20 -04:00
|
|
|
this.SessionManager = {
|
2019-05-29 05:21:06 -04:00
|
|
|
getLoggedInUser: sinon.stub().callsArgWith(1, null, this.user),
|
|
|
|
getLoggedInUserId: sinon.stub().returns(this.user_id),
|
|
|
|
getSessionUser: sinon.stub().returns(this.user),
|
2021-04-27 03:52:58 -04:00
|
|
|
isUserLoggedIn: sinon.stub().returns(true),
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.CompileController = SandboxedModule.require(modulePath, {
|
|
|
|
requires: {
|
2021-07-07 05:38:56 -04:00
|
|
|
'@overleaf/settings': this.settings,
|
2019-05-29 05:21:06 -04:00
|
|
|
request: (this.request = sinon.stub()),
|
|
|
|
'../Project/ProjectGetter': (this.ProjectGetter = {}),
|
2020-10-30 04:10:50 -04:00
|
|
|
'@overleaf/metrics': (this.Metrics = { inc: sinon.stub() }),
|
2019-05-29 05:21:06 -04:00
|
|
|
'./CompileManager': this.CompileManager,
|
|
|
|
'../User/UserGetter': this.UserGetter,
|
|
|
|
'./ClsiManager': this.ClsiManager,
|
2021-07-28 04:51:20 -04:00
|
|
|
'../Authentication/SessionManager': this.SessionManager,
|
2019-05-29 05:21:06 -04:00
|
|
|
'../../infrastructure/RateLimiter': this.RateLimiter,
|
2021-04-27 03:52:58 -04:00
|
|
|
'./ClsiCookieManager': () => this.ClsiCookieManager,
|
2022-05-23 11:12:55 -04:00
|
|
|
'../SplitTests/SplitTestHandler': {
|
|
|
|
getAssignment: (this.getAssignment = sinon.stub().yields(null, {
|
|
|
|
variant: 'default',
|
|
|
|
})),
|
|
|
|
},
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
this.project_id = 'project-id'
|
|
|
|
this.next = sinon.stub()
|
|
|
|
this.req = new MockRequest()
|
|
|
|
return (this.res = new MockResponse())
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('compile', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.params = { Project_id: this.project_id }
|
|
|
|
this.req.session = {}
|
2022-05-23 11:12:55 -04:00
|
|
|
return (this.CompileManager.compile = sinon.stub().callsArgWith(
|
|
|
|
3,
|
|
|
|
null,
|
|
|
|
(this.status = 'success'),
|
|
|
|
(this.outputFiles = [
|
|
|
|
{
|
|
|
|
path: 'output.pdf',
|
|
|
|
url: `/zone/b/project/${this.project_id}/user/${this.user_id}/build/id/output.pdf`,
|
|
|
|
type: 'pdf',
|
|
|
|
},
|
|
|
|
])
|
|
|
|
))
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('zonal downloads', function () {
|
|
|
|
describe('when in the default split test variant', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.getAssignment.yields(null, { variant: 'default' })
|
|
|
|
this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should remove the zone prefix', function () {
|
|
|
|
this.res.statusCode.should.equal(200)
|
|
|
|
this.res.body.should.equal(
|
|
|
|
JSON.stringify({
|
|
|
|
status: this.status,
|
|
|
|
outputFiles: [
|
|
|
|
{
|
|
|
|
path: 'output.pdf',
|
|
|
|
url: `/project/${this.project_id}/user/${this.user_id}/build/id/output.pdf`,
|
|
|
|
type: 'pdf',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('when in the zonal split test variant', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.getAssignment.yields(null, { variant: 'zonal' })
|
|
|
|
this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should keep the zone prefix', function () {
|
|
|
|
this.res.statusCode.should.equal(200)
|
|
|
|
this.res.body.should.equal(
|
|
|
|
JSON.stringify({
|
|
|
|
status: this.status,
|
|
|
|
outputFiles: [
|
|
|
|
{
|
|
|
|
path: 'output.pdf',
|
|
|
|
url: `/zone/b/project/${this.project_id}/user/${this.user_id}/build/id/output.pdf`,
|
|
|
|
type: 'pdf',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when not an auto compile', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should look up the user id', function () {
|
2021-07-28 04:51:20 -04:00
|
|
|
return this.SessionManager.getLoggedInUserId
|
|
|
|
.calledWith(this.req.session)
|
2019-05-29 05:21:06 -04:00
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should do the compile without the auto compile flag', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileManager.compile
|
2021-05-17 05:38:18 -04:00
|
|
|
.calledWith(this.project_id, this.user_id, {
|
|
|
|
isAutoCompile: false,
|
|
|
|
enablePdfCaching: false,
|
2021-09-21 04:56:44 -04:00
|
|
|
fileLineErrors: false,
|
2021-05-17 05:38:18 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should set the content-type of the response to application/json', function () {
|
2020-02-27 07:46:37 -05:00
|
|
|
this.res.type.should.equal('application/json')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should send a successful response reporting the status and files', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.res.statusCode.should.equal(200)
|
2020-02-27 07:46:37 -05:00
|
|
|
this.res.body.should.equal(
|
2019-05-29 05:21:06 -04:00
|
|
|
JSON.stringify({
|
|
|
|
status: this.status,
|
2021-04-27 03:52:58 -04:00
|
|
|
outputFiles: this.outputFiles,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when an auto compile', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.query = { auto_compile: 'true' }
|
|
|
|
return this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should do the compile with the auto compile flag', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileManager.compile
|
2021-05-17 05:38:18 -04:00
|
|
|
.calledWith(this.project_id, this.user_id, {
|
|
|
|
isAutoCompile: true,
|
|
|
|
enablePdfCaching: false,
|
2021-09-21 04:56:44 -04:00
|
|
|
fileLineErrors: false,
|
2021-05-17 05:38:18 -04:00
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('with the draft attribute', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.body = { draft: true }
|
|
|
|
return this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should do the compile without the draft compile flag', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileManager.compile
|
|
|
|
.calledWith(this.project_id, this.user_id, {
|
|
|
|
isAutoCompile: false,
|
2021-05-17 05:38:18 -04:00
|
|
|
enablePdfCaching: false,
|
2021-04-27 03:52:58 -04:00
|
|
|
draft: true,
|
2021-09-21 04:56:44 -04:00
|
|
|
fileLineErrors: false,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('compileSubmission', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.submission_id = 'sub-1234'
|
|
|
|
this.req.params = { submission_id: this.submission_id }
|
|
|
|
this.req.body = {}
|
|
|
|
return (this.ClsiManager.sendExternalRequest = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(
|
|
|
|
3,
|
|
|
|
null,
|
|
|
|
(this.status = 'success'),
|
|
|
|
(this.outputFiles = ['mock-output-files']),
|
|
|
|
(this.clsiServerId = 'mock-server-id'),
|
|
|
|
(this.validationProblems = null)
|
|
|
|
))
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should set the content-type of the response to application/json', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileController.compileSubmission(this.req, this.res, this.next)
|
|
|
|
return this.res.contentType
|
|
|
|
.calledWith('application/json')
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should send a successful response reporting the status and files', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileController.compileSubmission(this.req, this.res, this.next)
|
|
|
|
this.res.statusCode.should.equal(200)
|
|
|
|
return this.res.body.should.equal(
|
|
|
|
JSON.stringify({
|
|
|
|
status: this.status,
|
|
|
|
outputFiles: this.outputFiles,
|
|
|
|
clsiServerId: 'mock-server-id',
|
2021-04-27 03:52:58 -04:00
|
|
|
validationProblems: null,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('with compileGroup and timeout', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.body = {
|
|
|
|
compileGroup: 'special',
|
2021-04-27 03:52:58 -04:00
|
|
|
timeout: 600,
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
return this.CompileController.compileSubmission(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should use the supplied values', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.ClsiManager.sendExternalRequest
|
|
|
|
.calledWith(
|
|
|
|
this.submission_id,
|
|
|
|
{ compileGroup: 'special', timeout: 600 },
|
|
|
|
{ compileGroup: 'special', timeout: 600 }
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('with other supported options but not compileGroup and timeout', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.body = {
|
|
|
|
rootResourcePath: 'main.tex',
|
|
|
|
compiler: 'lualatex',
|
|
|
|
draft: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
check: 'validate',
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
return this.CompileController.compileSubmission(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should use the other options but default values for compileGroup and timeout', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.ClsiManager.sendExternalRequest
|
|
|
|
.calledWith(
|
|
|
|
this.submission_id,
|
|
|
|
{
|
|
|
|
rootResourcePath: 'main.tex',
|
|
|
|
compiler: 'lualatex',
|
|
|
|
draft: true,
|
2021-04-27 03:52:58 -04:00
|
|
|
check: 'validate',
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
{
|
|
|
|
rootResourcePath: 'main.tex',
|
|
|
|
compiler: 'lualatex',
|
|
|
|
draft: true,
|
|
|
|
check: 'validate',
|
|
|
|
compileGroup: 'standard',
|
2021-04-27 03:52:58 -04:00
|
|
|
timeout: 60,
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('downloadPdf', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.params = { Project_id: this.project_id }
|
|
|
|
|
|
|
|
this.req.query = { pdfng: true }
|
|
|
|
this.project = { name: 'test namè' }
|
|
|
|
return (this.ProjectGetter.getProject = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(2, null, this.project))
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when downloading for embedding', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileController.proxyToClsi = sinon.stub()
|
|
|
|
this.RateLimiter.addCount.callsArgWith(1, null, true)
|
|
|
|
return this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should look up the project', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.ProjectGetter.getProject
|
|
|
|
.calledWith(this.project_id, { name: 1 })
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should set the content-type of the response to application/pdf', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.res.contentType
|
|
|
|
.calledWith('application/pdf')
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should set the content-disposition header with a safe version of the project name', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.res.setContentDisposition
|
|
|
|
.calledWith('', { filename: 'test_nam_.pdf' })
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should increment the pdf-downloads metric', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.Metrics.inc.calledWith('pdf-downloads').should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy the PDF from the CLSI', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileController.proxyToClsi
|
|
|
|
.calledWith(
|
|
|
|
this.project_id,
|
2020-12-15 05:23:54 -05:00
|
|
|
`/project/${this.project_id}/user/${this.user_id}/output/output.pdf`,
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when the a build-id is provided', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.params.build_id = this.buildId = '1234-5678'
|
|
|
|
this.CompileController.proxyToClsi = sinon.stub()
|
|
|
|
this.RateLimiter.addCount.callsArgWith(1, null, true)
|
|
|
|
return this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy the PDF from the CLSI, with a build-id', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileController.proxyToClsi
|
|
|
|
.calledWith(
|
|
|
|
this.project_id,
|
2020-12-15 05:23:54 -05:00
|
|
|
`/project/${this.project_id}/user/${this.user_id}/build/${this.buildId}/output/output.pdf`,
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('when the pdf is not going to be used in pdfjs viewer', function () {
|
|
|
|
it('should check the rate limiter when pdfng is not set', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.query = {}
|
|
|
|
this.RateLimiter.addCount.callsArgWith(1, null, true)
|
|
|
|
this.CompileController.proxyToClsi = (project_id, url) => {
|
|
|
|
this.RateLimiter.addCount.args[0][0].throttle.should.equal(1000)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
return this.CompileController.downloadPdf(this.req, this.res)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should check the rate limiter when pdfng is false', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.query = { pdfng: false }
|
|
|
|
this.RateLimiter.addCount.callsArgWith(1, null, true)
|
|
|
|
this.CompileController.proxyToClsi = (project_id, url) => {
|
|
|
|
this.RateLimiter.addCount.args[0][0].throttle.should.equal(1000)
|
|
|
|
return done()
|
|
|
|
}
|
|
|
|
return this.CompileController.downloadPdf(this.req, this.res)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('getFileFromClsiWithoutUser', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.submission_id = 'sub-1234'
|
|
|
|
this.build_id = 123456
|
|
|
|
this.file = 'project.pdf'
|
|
|
|
this.req.params = {
|
|
|
|
submission_id: this.submission_id,
|
|
|
|
build_id: this.build_id,
|
2021-04-27 03:52:58 -04:00
|
|
|
file: this.file,
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.req.body = {}
|
2020-12-15 05:23:54 -05:00
|
|
|
this.expected_url = `/project/${this.submission_id}/build/${this.build_id}/output/${this.file}`
|
2019-05-29 05:21:06 -04:00
|
|
|
return (this.CompileController.proxyToClsiWithLimits = sinon.stub())
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('without limits specified', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileController.getFileFromClsiWithoutUser(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to CLSI with correct URL and default limits', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileController.proxyToClsiWithLimits
|
|
|
|
.calledWith(this.submission_id, this.expected_url, {
|
2021-04-27 03:52:58 -04:00
|
|
|
compileGroup: 'standard',
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('with limits specified', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.body = { compileTimeout: 600, compileGroup: 'special' }
|
|
|
|
return this.CompileController.getFileFromClsiWithoutUser(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to CLSI with correct URL and specified limits', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileController.proxyToClsiWithLimits
|
|
|
|
.calledWith(this.submission_id, this.expected_url, {
|
2021-04-27 03:52:58 -04:00
|
|
|
compileGroup: 'special',
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('proxySyncCode', function () {
|
2021-03-30 11:40:36 -04:00
|
|
|
let file, line, column, imageName
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
beforeEach(function (done) {
|
2021-03-30 11:40:36 -04:00
|
|
|
this.req.params = { Project_id: this.project_id }
|
|
|
|
file = 'main.tex'
|
|
|
|
line = String(Date.now())
|
|
|
|
column = String(Date.now() + 1)
|
|
|
|
this.req.query = { file, line, column }
|
|
|
|
|
|
|
|
imageName = 'foo/bar:tag-0'
|
|
|
|
this.ProjectGetter.getProject = sinon.stub().yields(null, { imageName })
|
|
|
|
|
|
|
|
this.next.callsFake(done)
|
|
|
|
this.res.callback = done
|
|
|
|
this.CompileController.proxyToClsi = sinon.stub().callsFake(() => done())
|
|
|
|
|
|
|
|
this.CompileController.proxySyncCode(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy the request with an imageName', function () {
|
2021-03-30 11:40:36 -04:00
|
|
|
expect(this.CompileController.proxyToClsi).to.have.been.calledWith(
|
|
|
|
this.project_id,
|
|
|
|
{
|
|
|
|
url: `/project/${this.project_id}/user/${this.user_id}/sync/code`,
|
2021-04-27 03:52:58 -04:00
|
|
|
qs: { file, line, column, imageName },
|
2021-03-30 11:40:36 -04:00
|
|
|
},
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('proxySyncPdf', function () {
|
2021-03-30 11:40:36 -04:00
|
|
|
let page, h, v, imageName
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
beforeEach(function (done) {
|
2021-03-30 11:40:36 -04:00
|
|
|
this.req.params = { Project_id: this.project_id }
|
|
|
|
page = String(Date.now())
|
|
|
|
h = String(Math.random())
|
|
|
|
v = String(Math.random())
|
|
|
|
this.req.query = { page, h, v }
|
|
|
|
|
|
|
|
imageName = 'foo/bar:tag-1'
|
|
|
|
this.ProjectGetter.getProject = sinon.stub().yields(null, { imageName })
|
|
|
|
|
|
|
|
this.next.callsFake(done)
|
|
|
|
this.res.callback = done
|
|
|
|
this.CompileController.proxyToClsi = sinon.stub().callsFake(() => done())
|
|
|
|
|
|
|
|
this.CompileController.proxySyncPdf(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy the request with an imageName', function () {
|
2021-03-30 11:40:36 -04:00
|
|
|
expect(this.CompileController.proxyToClsi).to.have.been.calledWith(
|
|
|
|
this.project_id,
|
|
|
|
{
|
|
|
|
url: `/project/${this.project_id}/user/${this.user_id}/sync/pdf`,
|
2021-04-27 03:52:58 -04:00
|
|
|
qs: { page, h, v, imageName },
|
2021-03-30 11:40:36 -04:00
|
|
|
},
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('proxyToClsi', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.request.returns(
|
|
|
|
(this.proxy = {
|
|
|
|
pipe: sinon.stub(),
|
2021-04-27 03:52:58 -04:00
|
|
|
on: sinon.stub(),
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
this.upstream = {
|
|
|
|
statusCode: 204,
|
2021-04-27 03:52:58 -04:00
|
|
|
headers: { mock: 'header' },
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.req.method = 'mock-method'
|
|
|
|
return (this.req.headers = {
|
|
|
|
Mock: 'Headers',
|
|
|
|
Range: '123-456',
|
|
|
|
'If-Range': 'abcdef',
|
2021-04-27 03:52:58 -04:00
|
|
|
'If-Modified-Since': 'Mon, 15 Dec 2014 15:23:56 GMT',
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('old pdf viewer', function () {
|
|
|
|
describe('user with standard priority', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { compileGroup: 'standard' })
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should open a request to the CLSI', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.request
|
|
|
|
.calledWith({
|
|
|
|
jar: this.jar,
|
|
|
|
method: this.req.method,
|
|
|
|
url: `${this.settings.apis.clsi.url}${this.url}`,
|
2021-04-27 03:52:58 -04:00
|
|
|
timeout: 60 * 1000,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should pass the request on to the client', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.proxy.pipe.calledWith(this.res).should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should bind an error handle to the request proxy', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.proxy.on.calledWith('error').should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('user with priority compile', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { compileGroup: 'priority' })
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('user with standard priority via query string', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.query = { compileGroup: 'standard' }
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should open a request to the CLSI', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.request
|
|
|
|
.calledWith({
|
|
|
|
jar: this.jar,
|
|
|
|
method: this.req.method,
|
|
|
|
url: `${this.settings.apis.clsi.url}${this.url}`,
|
2021-04-27 03:52:58 -04:00
|
|
|
timeout: 60 * 1000,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should pass the request on to the client', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.proxy.pipe.calledWith(this.res).should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should bind an error handle to the request proxy', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.proxy.on.calledWith('error').should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('user with non-existent priority via query string', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.query = { compileGroup: 'foobar' }
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to the standard url', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.request
|
|
|
|
.calledWith({
|
|
|
|
jar: this.jar,
|
|
|
|
method: this.req.method,
|
|
|
|
url: `${this.settings.apis.clsi.url}${this.url}`,
|
2021-04-27 03:52:58 -04:00
|
|
|
timeout: 60 * 1000,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('user with build parameter via query string', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { compileGroup: 'standard' })
|
|
|
|
this.req.query = { build: 1234 }
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to the standard url without the build parameter', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.request
|
|
|
|
.calledWith({
|
|
|
|
jar: this.jar,
|
|
|
|
method: this.req.method,
|
|
|
|
url: `${this.settings.apis.clsi.url}${this.url}`,
|
2021-04-27 03:52:58 -04:00
|
|
|
timeout: 60 * 1000,
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('new pdf viewer', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return (this.req.query = { pdfng: true })
|
|
|
|
})
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('user with standard priority', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { compileGroup: 'standard' })
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should open a request to the CLSI', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.request
|
|
|
|
.calledWith({
|
|
|
|
jar: this.jar,
|
|
|
|
method: this.req.method,
|
|
|
|
url: `${this.settings.apis.clsi.url}${this.url}`,
|
|
|
|
timeout: 60 * 1000,
|
|
|
|
headers: {
|
|
|
|
Range: '123-456',
|
|
|
|
'If-Range': 'abcdef',
|
2021-04-27 03:52:58 -04:00
|
|
|
'If-Modified-Since': 'Mon, 15 Dec 2014 15:23:56 GMT',
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should pass the request on to the client', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.proxy.pipe.calledWith(this.res).should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should bind an error handle to the request proxy', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.proxy.on.calledWith('error').should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('user with build parameter via query string', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { compileGroup: 'standard' })
|
|
|
|
this.req.query = { build: 1234, pdfng: true }
|
|
|
|
return this.CompileController.proxyToClsi(
|
|
|
|
this.project_id,
|
|
|
|
(this.url = '/test'),
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to the standard url with the build parameter', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.request
|
|
|
|
.calledWith({
|
|
|
|
jar: this.jar,
|
|
|
|
method: this.req.method,
|
|
|
|
qs: { build: 1234 },
|
|
|
|
url: `${this.settings.apis.clsi.url}${this.url}`,
|
|
|
|
timeout: 60 * 1000,
|
|
|
|
headers: {
|
|
|
|
Range: '123-456',
|
|
|
|
'If-Range': 'abcdef',
|
2021-04-27 03:52:58 -04:00
|
|
|
'If-Modified-Since': 'Mon, 15 Dec 2014 15:23:56 GMT',
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('deleteAuxFiles', function () {
|
|
|
|
beforeEach(function () {
|
2021-01-21 07:20:55 -05:00
|
|
|
this.CompileManager.deleteAuxFiles = sinon.stub().yields()
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.params = { Project_id: this.project_id }
|
2021-01-21 07:20:55 -05:00
|
|
|
this.req.query = { clsiserverid: 'node-1' }
|
2019-05-29 05:21:06 -04:00
|
|
|
this.res.sendStatus = sinon.stub()
|
|
|
|
return this.CompileController.deleteAuxFiles(
|
|
|
|
this.req,
|
|
|
|
this.res,
|
|
|
|
this.next
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to the CLSI', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileManager.deleteAuxFiles
|
2021-01-21 07:20:55 -05:00
|
|
|
.calledWith(this.project_id, this.user_id, 'node-1')
|
2019-05-29 05:21:06 -04:00
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a 200', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.res.sendStatus.calledWith(200).should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('compileAndDownloadPdf', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req = {
|
|
|
|
params: {
|
2021-04-27 03:52:58 -04:00
|
|
|
project_id: this.project_id,
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.CompileManager.compile.callsArgWith(3)
|
|
|
|
this.CompileController.proxyToClsi = sinon.stub()
|
|
|
|
return (this.res = { send: () => {} })
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should call compile in the compile manager', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
this.CompileManager.compile.calledWith(this.project_id).should.equal(true)
|
|
|
|
return done()
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy the res to the clsi with correct url', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
sinon.assert.calledWith(
|
|
|
|
this.CompileController.proxyToClsi,
|
|
|
|
this.project_id,
|
|
|
|
`/project/${this.project_id}/output/output.pdf`,
|
|
|
|
this.req,
|
|
|
|
this.res
|
|
|
|
)
|
|
|
|
|
|
|
|
this.CompileController.proxyToClsi
|
|
|
|
.calledWith(
|
|
|
|
this.project_id,
|
|
|
|
`/project/${this.project_id}/output/output.pdf`,
|
|
|
|
this.req,
|
|
|
|
this.res
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
return done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('wordCount', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.CompileManager.wordCount = sinon
|
|
|
|
.stub()
|
2021-01-21 07:20:55 -05:00
|
|
|
.yields(null, { content: 'body' })
|
2019-05-29 05:21:06 -04:00
|
|
|
this.req.params = { Project_id: this.project_id }
|
2021-01-21 07:20:55 -05:00
|
|
|
this.req.query = { clsiserverid: 'node-42' }
|
2022-01-17 05:19:53 -05:00
|
|
|
this.res.json = sinon.stub()
|
2019-05-29 05:21:06 -04:00
|
|
|
this.res.contentType = sinon.stub()
|
|
|
|
return this.CompileController.wordCount(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should proxy to the CLSI', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
return this.CompileManager.wordCount
|
2021-01-21 07:20:55 -05:00
|
|
|
.calledWith(this.project_id, this.user_id, false, 'node-42')
|
2019-05-29 05:21:06 -04:00
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a 200 and body', function () {
|
2022-01-17 05:19:53 -05:00
|
|
|
return this.res.json.calledWith({ content: 'body' }).should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|