|
@@ -1,4 +1,3 @@
|
|
|
-/* eslint-disable mocha/handle-done-callback */
|
|
|
|
|
const sinon = require('sinon')
|
|
const sinon = require('sinon')
|
|
|
const { expect } = require('chai')
|
|
const { expect } = require('chai')
|
|
|
const modulePath = '../../../../app/src/Features/Compile/CompileController.js'
|
|
const modulePath = '../../../../app/src/Features/Compile/CompileController.js'
|
|
@@ -19,8 +18,15 @@ describe('CompileController', function () {
|
|
|
compileTimeout: 100,
|
|
compileTimeout: 100,
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
- this.CompileManager = { compile: sinon.stub() }
|
|
|
|
|
- this.ClsiManager = {}
|
|
|
|
|
|
|
+ this.CompileManager = {
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ compile: sinon.stub(),
|
|
|
|
|
+ getProjectCompileLimits: sinon.stub(),
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+ this.ClsiManager = {
|
|
|
|
|
+ promises: {},
|
|
|
|
|
+ }
|
|
|
this.UserGetter = { getUser: sinon.stub() }
|
|
this.UserGetter = { getUser: sinon.stub() }
|
|
|
this.rateLimiter = {
|
|
this.rateLimiter = {
|
|
|
consume: sinon.stub().resolves(),
|
|
consume: sinon.stub().resolves(),
|
|
@@ -47,10 +53,11 @@ describe('CompileController', function () {
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
this.ClsiCookieManager = {
|
|
this.ClsiCookieManager = {
|
|
|
- getServerId: sinon.stub().yields(null, 'clsi-server-id-from-redis'),
|
|
|
|
|
|
|
+ promises: {
|
|
|
|
|
+ getServerId: sinon.stub().resolves('clsi-server-id-from-redis'),
|
|
|
|
|
+ },
|
|
|
}
|
|
}
|
|
|
this.SessionManager = {
|
|
this.SessionManager = {
|
|
|
- getLoggedInUser: sinon.stub().callsArgWith(1, null, this.user),
|
|
|
|
|
getLoggedInUserId: sinon.stub().returns(this.user_id),
|
|
getLoggedInUserId: sinon.stub().returns(this.user_id),
|
|
|
getSessionUser: sinon.stub().returns(this.user),
|
|
getSessionUser: sinon.stub().returns(this.user),
|
|
|
isUserLoggedIn: sinon.stub().returns(true),
|
|
isUserLoggedIn: sinon.stub().returns(true),
|
|
@@ -76,8 +83,9 @@ describe('CompileController', function () {
|
|
|
'stream/promises': { pipeline: this.pipeline },
|
|
'stream/promises': { pipeline: this.pipeline },
|
|
|
'@overleaf/settings': this.settings,
|
|
'@overleaf/settings': this.settings,
|
|
|
'@overleaf/fetch-utils': this.fetchUtils,
|
|
'@overleaf/fetch-utils': this.fetchUtils,
|
|
|
- request: (this.request = sinon.stub()),
|
|
|
|
|
- '../Project/ProjectGetter': (this.ProjectGetter = {}),
|
|
|
|
|
|
|
+ '../Project/ProjectGetter': (this.ProjectGetter = {
|
|
|
|
|
+ promises: {},
|
|
|
|
|
+ }),
|
|
|
'@overleaf/metrics': (this.Metrics = {
|
|
'@overleaf/metrics': (this.Metrics = {
|
|
|
inc: sinon.stub(),
|
|
inc: sinon.stub(),
|
|
|
Timer: class {
|
|
Timer: class {
|
|
@@ -121,25 +129,23 @@ describe('CompileController', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
this.req.params = { Project_id: this.projectId }
|
|
this.req.params = { Project_id: this.projectId }
|
|
|
this.req.session = {}
|
|
this.req.session = {}
|
|
|
- this.CompileManager.compile = sinon.stub().callsArgWith(
|
|
|
|
|
- 3,
|
|
|
|
|
- null,
|
|
|
|
|
- (this.status = 'success'),
|
|
|
|
|
- (this.outputFiles = [
|
|
|
|
|
|
|
+ this.CompileManager.promises.compile = sinon.stub().resolves({
|
|
|
|
|
+ status: (this.status = 'success'),
|
|
|
|
|
+ outputFiles: (this.outputFiles = [
|
|
|
{
|
|
{
|
|
|
path: 'output.pdf',
|
|
path: 'output.pdf',
|
|
|
url: `/project/${this.projectId}/user/${this.user_id}/build/id/output.pdf`,
|
|
url: `/project/${this.projectId}/user/${this.user_id}/build/id/output.pdf`,
|
|
|
type: 'pdf',
|
|
type: 'pdf',
|
|
|
},
|
|
},
|
|
|
]),
|
|
]),
|
|
|
- undefined,
|
|
|
|
|
- undefined,
|
|
|
|
|
- undefined,
|
|
|
|
|
- undefined,
|
|
|
|
|
- undefined,
|
|
|
|
|
- undefined,
|
|
|
|
|
- this.build_id
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ clsiServerId: undefined,
|
|
|
|
|
+ limits: undefined,
|
|
|
|
|
+ validationProblems: undefined,
|
|
|
|
|
+ stats: undefined,
|
|
|
|
|
+ timings: undefined,
|
|
|
|
|
+ outputUrlPrefix: undefined,
|
|
|
|
|
+ buildId: this.build_id,
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('pdfDownloadDomain', function () {
|
|
describe('pdfDownloadDomain', function () {
|
|
@@ -148,9 +154,8 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when clsi does not emit zone prefix', function () {
|
|
describe('when clsi does not emit zone prefix', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ await this.CompileController.compile(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should add domain verbatim', function () {
|
|
it('should add domain verbatim', function () {
|
|
@@ -177,28 +182,25 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when clsi emits a zone prefix', function () {
|
|
describe('when clsi emits a zone prefix', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileManager.compile = sinon.stub().callsArgWith(
|
|
|
|
|
- 3,
|
|
|
|
|
- null,
|
|
|
|
|
- (this.status = 'success'),
|
|
|
|
|
- (this.outputFiles = [
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CompileManager.promises.compile = sinon.stub().resolves({
|
|
|
|
|
+ status: (this.status = 'success'),
|
|
|
|
|
+ outputFiles: (this.outputFiles = [
|
|
|
{
|
|
{
|
|
|
path: 'output.pdf',
|
|
path: 'output.pdf',
|
|
|
url: `/project/${this.projectId}/user/${this.user_id}/build/id/output.pdf`,
|
|
url: `/project/${this.projectId}/user/${this.user_id}/build/id/output.pdf`,
|
|
|
type: 'pdf',
|
|
type: 'pdf',
|
|
|
},
|
|
},
|
|
|
]),
|
|
]),
|
|
|
- undefined, // clsiServerId
|
|
|
|
|
- undefined, // limits
|
|
|
|
|
- undefined, // validationProblems
|
|
|
|
|
- undefined, // stats
|
|
|
|
|
- undefined, // timings
|
|
|
|
|
- '/zone/b',
|
|
|
|
|
- this.build_id
|
|
|
|
|
- )
|
|
|
|
|
- this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ clsiServerId: undefined,
|
|
|
|
|
+ limits: undefined,
|
|
|
|
|
+ validationProblems: undefined,
|
|
|
|
|
+ stats: undefined,
|
|
|
|
|
+ timings: undefined,
|
|
|
|
|
+ outputUrlPrefix: '/zone/b',
|
|
|
|
|
+ buildId: this.build_id,
|
|
|
|
|
+ })
|
|
|
|
|
+ await this.CompileController.compile(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should add the zone prefix', function () {
|
|
it('should add the zone prefix', function () {
|
|
@@ -227,9 +229,8 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when not an auto compile', function () {
|
|
describe('when not an auto compile', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ await this.CompileController.compile(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should look up the user id', function () {
|
|
it('should look up the user id', function () {
|
|
@@ -239,7 +240,7 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should do the compile without the auto compile flag', function () {
|
|
it('should do the compile without the auto compile flag', function () {
|
|
|
- this.CompileManager.compile.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.CompileManager.promises.compile.should.have.been.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
this.user_id,
|
|
this.user_id,
|
|
|
{
|
|
{
|
|
@@ -275,14 +276,13 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when an auto compile', function () {
|
|
describe('when an auto compile', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.query = { auto_compile: 'true' }
|
|
this.req.query = { auto_compile: 'true' }
|
|
|
- this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.compile(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should do the compile with the auto compile flag', function () {
|
|
it('should do the compile with the auto compile flag', function () {
|
|
|
- this.CompileManager.compile.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.CompileManager.promises.compile.should.have.been.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
this.user_id,
|
|
this.user_id,
|
|
|
{
|
|
{
|
|
@@ -299,14 +299,13 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('with the draft attribute', function () {
|
|
describe('with the draft attribute', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.body = { draft: true }
|
|
this.req.body = { draft: true }
|
|
|
- this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.compile(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should do the compile without the draft compile flag', function () {
|
|
it('should do the compile without the draft compile flag', function () {
|
|
|
- this.CompileManager.compile.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.CompileManager.promises.compile.should.have.been.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
this.user_id,
|
|
this.user_id,
|
|
|
{
|
|
{
|
|
@@ -324,14 +323,13 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('with an editor id', function () {
|
|
describe('with an editor id', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.body = { editorId: 'the-editor-id' }
|
|
this.req.body = { editorId: 'the-editor-id' }
|
|
|
- this.CompileController.compile(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.compile(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should pass the editor id to the compiler', function () {
|
|
it('should pass the editor id to the compiler', function () {
|
|
|
- this.CompileManager.compile.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.CompileManager.promises.compile.should.have.been.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
this.user_id,
|
|
this.user_id,
|
|
|
{
|
|
{
|
|
@@ -353,25 +351,29 @@ describe('CompileController', function () {
|
|
|
this.submission_id = 'sub-1234'
|
|
this.submission_id = 'sub-1234'
|
|
|
this.req.params = { submission_id: this.submission_id }
|
|
this.req.params = { submission_id: this.submission_id }
|
|
|
this.req.body = {}
|
|
this.req.body = {}
|
|
|
- this.ClsiManager.sendExternalRequest = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .callsArgWith(
|
|
|
|
|
- 3,
|
|
|
|
|
- null,
|
|
|
|
|
- (this.status = 'success'),
|
|
|
|
|
- (this.outputFiles = ['mock-output-files']),
|
|
|
|
|
- (this.clsiServerId = 'mock-server-id'),
|
|
|
|
|
- (this.validationProblems = null)
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ this.ClsiManager.promises.sendExternalRequest = sinon.stub().resolves({
|
|
|
|
|
+ status: (this.status = 'success'),
|
|
|
|
|
+ outputFiles: (this.outputFiles = ['mock-output-files']),
|
|
|
|
|
+ clsiServerId: 'mock-server-id',
|
|
|
|
|
+ validationProblems: null,
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should set the content-type of the response to application/json', function () {
|
|
|
|
|
- this.CompileController.compileSubmission(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ it('should set the content-type of the response to application/json', async function () {
|
|
|
|
|
+ await this.CompileController.compileSubmission(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ this.res,
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
this.res.contentType.calledWith('application/json').should.equal(true)
|
|
this.res.contentType.calledWith('application/json').should.equal(true)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should send a successful response reporting the status and files', function () {
|
|
|
|
|
- this.CompileController.compileSubmission(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ it('should send a successful response reporting the status and files', async function () {
|
|
|
|
|
+ await this.CompileController.compileSubmission(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ this.res,
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
this.res.statusCode.should.equal(200)
|
|
this.res.statusCode.should.equal(200)
|
|
|
this.res.body.should.equal(
|
|
this.res.body.should.equal(
|
|
|
JSON.stringify({
|
|
JSON.stringify({
|
|
@@ -393,7 +395,7 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should use the supplied values', function () {
|
|
it('should use the supplied values', function () {
|
|
|
- this.ClsiManager.sendExternalRequest.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.ClsiManager.promises.sendExternalRequest.should.have.been.calledWith(
|
|
|
this.submission_id,
|
|
this.submission_id,
|
|
|
{ compileGroup: 'special', timeout: 600 },
|
|
{ compileGroup: 'special', timeout: 600 },
|
|
|
{ compileGroup: 'special', compileBackendClass: 'n2d', timeout: 600 }
|
|
{ compileGroup: 'special', compileBackendClass: 'n2d', timeout: 600 }
|
|
@@ -413,7 +415,7 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should use the other options but default values for compileGroup and timeout', function () {
|
|
it('should use the other options but default values for compileGroup and timeout', function () {
|
|
|
- this.ClsiManager.sendExternalRequest.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.ClsiManager.promises.sendExternalRequest.should.have.been.calledWith(
|
|
|
this.submission_id,
|
|
this.submission_id,
|
|
|
{
|
|
{
|
|
|
rootResourcePath: 'main.tex',
|
|
rootResourcePath: 'main.tex',
|
|
@@ -437,24 +439,21 @@ describe('CompileController', function () {
|
|
|
|
|
|
|
|
describe('downloadPdf', function () {
|
|
describe('downloadPdf', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
|
|
+ this.CompileController._proxyToClsi = sinon.stub().resolves()
|
|
|
this.req.params = { Project_id: this.projectId }
|
|
this.req.params = { Project_id: this.projectId }
|
|
|
-
|
|
|
|
|
this.project = { name: 'test namè; 1' }
|
|
this.project = { name: 'test namè; 1' }
|
|
|
- this.ProjectGetter.getProject = sinon
|
|
|
|
|
|
|
+ this.ProjectGetter.promises.getProject = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .callsArgWith(2, null, this.project)
|
|
|
|
|
|
|
+ .resolves(this.project)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when downloading for embedding', function () {
|
|
describe('when downloading for embedding', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.CompileController.proxyToClsi = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .callsFake(() => done())
|
|
|
|
|
- this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ await this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should look up the project', function () {
|
|
it('should look up the project', function () {
|
|
|
- this.ProjectGetter.getProject
|
|
|
|
|
|
|
+ this.ProjectGetter.promises.getProject
|
|
|
.calledWith(this.projectId, { name: 1 })
|
|
.calledWith(this.projectId, { name: 1 })
|
|
|
.should.equal(true)
|
|
.should.equal(true)
|
|
|
})
|
|
})
|
|
@@ -474,43 +473,66 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy the PDF from the CLSI', function () {
|
|
it('should proxy the PDF from the CLSI', function () {
|
|
|
- this.CompileController.proxyToClsi
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi
|
|
|
.calledWith(
|
|
.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
`/project/${this.projectId}/user/${this.user_id}/output/output.pdf`,
|
|
`/project/${this.projectId}/user/${this.user_id}/output/output.pdf`,
|
|
|
{},
|
|
{},
|
|
|
this.req,
|
|
this.req,
|
|
|
- this.res,
|
|
|
|
|
- this.next
|
|
|
|
|
|
|
+ this.res
|
|
|
)
|
|
)
|
|
|
.should.equal(true)
|
|
.should.equal(true)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('when a build-id is provided', function () {
|
|
describe('when a build-id is provided', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.params.build_id = this.build_id
|
|
this.req.params.build_id = this.build_id
|
|
|
- this.CompileController.proxyToClsi = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .callsFake(() => done())
|
|
|
|
|
- this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy the PDF from the CLSI, with a build-id', function () {
|
|
it('should proxy the PDF from the CLSI, with a build-id', function () {
|
|
|
- this.CompileController.proxyToClsi
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi
|
|
|
.calledWith(
|
|
.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
`/project/${this.projectId}/user/${this.user_id}/build/${this.build_id}/output/output.pdf`,
|
|
`/project/${this.projectId}/user/${this.user_id}/build/${this.build_id}/output/output.pdf`,
|
|
|
{},
|
|
{},
|
|
|
this.req,
|
|
this.req,
|
|
|
- this.res,
|
|
|
|
|
- this.next
|
|
|
|
|
|
|
+ this.res
|
|
|
)
|
|
)
|
|
|
.should.equal(true)
|
|
.should.equal(true)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
|
|
+ describe('when rate-limited', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.rateLimiter.consume.rejects({
|
|
|
|
|
+ msBeforeNext: 250,
|
|
|
|
|
+ remainingPoints: 0,
|
|
|
|
|
+ consumedPoints: 5,
|
|
|
|
|
+ isFirstInDuration: false,
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+ it('should return 500', async function () {
|
|
|
|
|
+ await this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
|
|
+ // should it be 429 instead?
|
|
|
|
|
+ this.res.sendStatus.calledWith(500).should.equal(true)
|
|
|
|
|
+ this.CompileController._proxyToClsi.should.not.have.been.called
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ describe('when rate-limit errors', function () {
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.rateLimiter.consume.rejects(new Error('uh oh'))
|
|
|
|
|
+ })
|
|
|
|
|
+ it('should return 500', async function () {
|
|
|
|
|
+ await this.CompileController.downloadPdf(this.req, this.res, this.next)
|
|
|
|
|
+ this.res.sendStatus.calledWith(500).should.equal(true)
|
|
|
|
|
+ this.CompileController._proxyToClsi.should.not.have.been.called
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('getFileFromClsiWithoutUser', function () {
|
|
describe('getFileFromClsiWithoutUser', function () {
|
|
@@ -524,12 +546,12 @@ describe('CompileController', function () {
|
|
|
}
|
|
}
|
|
|
this.req.body = {}
|
|
this.req.body = {}
|
|
|
this.expected_url = `/project/${this.submission_id}/build/${this.build_id}/output/${this.file}`
|
|
this.expected_url = `/project/${this.submission_id}/build/${this.build_id}/output/${this.file}`
|
|
|
- this.CompileController.proxyToClsiWithLimits = sinon.stub()
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsiWithLimits = sinon.stub()
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('without limits specified', function () {
|
|
describe('without limits specified', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.CompileController.getFileFromClsiWithoutUser(
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ await this.CompileController.getFileFromClsiWithoutUser(
|
|
|
this.req,
|
|
this.req,
|
|
|
this.res,
|
|
this.res,
|
|
|
this.next
|
|
this.next
|
|
@@ -537,15 +559,12 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy to CLSI with correct URL and default limits', function () {
|
|
it('should proxy to CLSI with correct URL and default limits', function () {
|
|
|
- this.CompileController.proxyToClsiWithLimits.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsiWithLimits.should.have.been.calledWith(
|
|
|
this.submission_id,
|
|
this.submission_id,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
this.expected_url,
|
|
this.expected_url,
|
|
|
{},
|
|
{},
|
|
|
- {
|
|
|
|
|
- compileGroup: 'standard',
|
|
|
|
|
- compileBackendClass: 'n2d',
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ { compileGroup: 'standard', compileBackendClass: 'n2d' }
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
@@ -561,7 +580,7 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy to CLSI with correct URL and specified limits', function () {
|
|
it('should proxy to CLSI with correct URL and specified limits', function () {
|
|
|
- this.CompileController.proxyToClsiWithLimits.should.have.been.calledWith(
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsiWithLimits.should.have.been.calledWith(
|
|
|
this.submission_id,
|
|
this.submission_id,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
this.expected_url,
|
|
this.expected_url,
|
|
@@ -577,7 +596,7 @@ describe('CompileController', function () {
|
|
|
describe('proxySyncCode', function () {
|
|
describe('proxySyncCode', function () {
|
|
|
let file, line, column, imageName, editorId, buildId
|
|
let file, line, column, imageName, editorId, buildId
|
|
|
|
|
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.params = { Project_id: this.projectId }
|
|
this.req.params = { Project_id: this.projectId }
|
|
|
file = 'main.tex'
|
|
file = 'main.tex'
|
|
|
line = String(Date.now())
|
|
line = String(Date.now())
|
|
@@ -587,17 +606,17 @@ describe('CompileController', function () {
|
|
|
this.req.query = { file, line, column, editorId, buildId }
|
|
this.req.query = { file, line, column, editorId, buildId }
|
|
|
|
|
|
|
|
imageName = 'foo/bar:tag-0'
|
|
imageName = 'foo/bar:tag-0'
|
|
|
- this.ProjectGetter.getProject = sinon.stub().yields(null, { imageName })
|
|
|
|
|
|
|
+ this.ProjectGetter.promises.getProject = sinon
|
|
|
|
|
+ .stub()
|
|
|
|
|
+ .resolves({ imageName })
|
|
|
|
|
|
|
|
- this.next.callsFake(done)
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileController.proxyToClsi = sinon.stub().callsFake(() => done())
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi = sinon.stub().resolves()
|
|
|
|
|
|
|
|
- this.CompileController.proxySyncCode(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.proxySyncCode(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy the request with an imageName', function () {
|
|
it('should proxy the request with an imageName', function () {
|
|
|
- expect(this.CompileController.proxyToClsi).to.have.been.calledWith(
|
|
|
|
|
|
|
+ expect(this.CompileController._proxyToClsi).to.have.been.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'sync-to-code',
|
|
'sync-to-code',
|
|
|
`/project/${this.projectId}/user/${this.user_id}/sync/code`,
|
|
`/project/${this.projectId}/user/${this.user_id}/sync/code`,
|
|
@@ -611,8 +630,7 @@ describe('CompileController', function () {
|
|
|
compileFromClsiCache: false,
|
|
compileFromClsiCache: false,
|
|
|
},
|
|
},
|
|
|
this.req,
|
|
this.req,
|
|
|
- this.res,
|
|
|
|
|
- this.next
|
|
|
|
|
|
|
+ this.res
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
@@ -620,7 +638,7 @@ describe('CompileController', function () {
|
|
|
describe('proxySyncPdf', function () {
|
|
describe('proxySyncPdf', function () {
|
|
|
let page, h, v, imageName, editorId, buildId
|
|
let page, h, v, imageName, editorId, buildId
|
|
|
|
|
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.params = { Project_id: this.projectId }
|
|
this.req.params = { Project_id: this.projectId }
|
|
|
page = String(Date.now())
|
|
page = String(Date.now())
|
|
|
h = String(Math.random())
|
|
h = String(Math.random())
|
|
@@ -630,17 +648,17 @@ describe('CompileController', function () {
|
|
|
this.req.query = { page, h, v, editorId, buildId }
|
|
this.req.query = { page, h, v, editorId, buildId }
|
|
|
|
|
|
|
|
imageName = 'foo/bar:tag-1'
|
|
imageName = 'foo/bar:tag-1'
|
|
|
- this.ProjectGetter.getProject = sinon.stub().yields(null, { imageName })
|
|
|
|
|
|
|
+ this.ProjectGetter.promises.getProject = sinon
|
|
|
|
|
+ .stub()
|
|
|
|
|
+ .resolves({ imageName })
|
|
|
|
|
|
|
|
- this.next.callsFake(done)
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileController.proxyToClsi = sinon.stub().callsFake(() => done())
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi = sinon.stub()
|
|
|
|
|
|
|
|
- this.CompileController.proxySyncPdf(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.proxySyncPdf(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy the request with an imageName', function () {
|
|
it('should proxy the request with an imageName', function () {
|
|
|
- expect(this.CompileController.proxyToClsi).to.have.been.calledWith(
|
|
|
|
|
|
|
+ expect(this.CompileController._proxyToClsi).to.have.been.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'sync-to-pdf',
|
|
'sync-to-pdf',
|
|
|
`/project/${this.projectId}/user/${this.user_id}/sync/pdf`,
|
|
`/project/${this.projectId}/user/${this.user_id}/sync/pdf`,
|
|
@@ -654,13 +672,12 @@ describe('CompileController', function () {
|
|
|
compileFromClsiCache: false,
|
|
compileFromClsiCache: false,
|
|
|
},
|
|
},
|
|
|
this.req,
|
|
this.req,
|
|
|
- this.res,
|
|
|
|
|
- this.next
|
|
|
|
|
|
|
+ this.res
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- describe('proxyToClsi', function () {
|
|
|
|
|
|
|
+ describe('_proxyToClsi', function () {
|
|
|
beforeEach(function () {
|
|
beforeEach(function () {
|
|
|
this.req.method = 'mock-method'
|
|
this.req.method = 'mock-method'
|
|
|
this.req.headers = {
|
|
this.req.headers = {
|
|
@@ -673,15 +690,14 @@ describe('CompileController', function () {
|
|
|
|
|
|
|
|
describe('old pdf viewer', function () {
|
|
describe('old pdf viewer', function () {
|
|
|
describe('user with standard priority', function () {
|
|
describe('user with standard priority', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CompileManager.promises.getProjectCompileLimits = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .callsArgWith(1, null, {
|
|
|
|
|
|
|
+ .resolves({
|
|
|
compileGroup: 'standard',
|
|
compileGroup: 'standard',
|
|
|
compileBackendClass: 'e2',
|
|
compileBackendClass: 'e2',
|
|
|
})
|
|
})
|
|
|
- this.CompileController.proxyToClsi(
|
|
|
|
|
|
|
+ await this.CompileController._proxyToClsi(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
(this.url = '/test'),
|
|
(this.url = '/test'),
|
|
@@ -704,15 +720,14 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('user with priority compile', function () {
|
|
describe('user with priority compile', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CompileManager.promises.getProjectCompileLimits = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .callsArgWith(1, null, {
|
|
|
|
|
|
|
+ .resolves({
|
|
|
compileGroup: 'priority',
|
|
compileGroup: 'priority',
|
|
|
compileBackendClass: 'c2d',
|
|
compileBackendClass: 'c2d',
|
|
|
})
|
|
})
|
|
|
- this.CompileController.proxyToClsi(
|
|
|
|
|
|
|
+ await this.CompileController._proxyToClsi(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
(this.url = '/test'),
|
|
(this.url = '/test'),
|
|
@@ -731,16 +746,15 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('user with standard priority via query string', function () {
|
|
describe('user with standard priority via query string', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.query = { compileGroup: 'standard' }
|
|
this.req.query = { compileGroup: 'standard' }
|
|
|
- this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
|
|
|
+ this.CompileManager.promises.getProjectCompileLimits = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .callsArgWith(1, null, {
|
|
|
|
|
|
|
+ .resolves({
|
|
|
compileGroup: 'standard',
|
|
compileGroup: 'standard',
|
|
|
compileBackendClass: 'e2',
|
|
compileBackendClass: 'e2',
|
|
|
})
|
|
})
|
|
|
- this.CompileController.proxyToClsi(
|
|
|
|
|
|
|
+ await this.CompileController._proxyToClsi(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
(this.url = '/test'),
|
|
(this.url = '/test'),
|
|
@@ -763,16 +777,15 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('user with non-existent priority via query string', function () {
|
|
describe('user with non-existent priority via query string', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
this.req.query = { compileGroup: 'foobar' }
|
|
this.req.query = { compileGroup: 'foobar' }
|
|
|
- this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
|
|
|
+ this.CompileManager.promises.getProjectCompileLimits = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .callsArgWith(1, null, {
|
|
|
|
|
|
|
+ .resolves({
|
|
|
compileGroup: 'standard',
|
|
compileGroup: 'standard',
|
|
|
compileBackendClass: 'e2',
|
|
compileBackendClass: 'e2',
|
|
|
})
|
|
})
|
|
|
- this.CompileController.proxyToClsi(
|
|
|
|
|
|
|
+ await this.CompileController._proxyToClsi(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
(this.url = '/test'),
|
|
(this.url = '/test'),
|
|
@@ -791,16 +804,15 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('user with build parameter via query string', function () {
|
|
describe('user with build parameter via query string', function () {
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.res.callback = done
|
|
|
|
|
- this.CompileManager.getProjectCompileLimits = sinon
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CompileManager.promises.getProjectCompileLimits = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .callsArgWith(1, null, {
|
|
|
|
|
|
|
+ .resolves({
|
|
|
compileGroup: 'standard',
|
|
compileGroup: 'standard',
|
|
|
compileBackendClass: 'e2',
|
|
compileBackendClass: 'e2',
|
|
|
})
|
|
})
|
|
|
this.req.query = { build: 1234 }
|
|
this.req.query = { build: 1234 }
|
|
|
- this.CompileController.proxyToClsi(
|
|
|
|
|
|
|
+ await this.CompileController._proxyToClsi(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
(this.url = '/test'),
|
|
(this.url = '/test'),
|
|
@@ -821,16 +833,16 @@ describe('CompileController', function () {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('deleteAuxFiles', function () {
|
|
describe('deleteAuxFiles', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.CompileManager.deleteAuxFiles = sinon.stub().yields()
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CompileManager.promises.deleteAuxFiles = sinon.stub().resolves()
|
|
|
this.req.params = { Project_id: this.projectId }
|
|
this.req.params = { Project_id: this.projectId }
|
|
|
this.req.query = { clsiserverid: 'node-1' }
|
|
this.req.query = { clsiserverid: 'node-1' }
|
|
|
this.res.sendStatus = sinon.stub()
|
|
this.res.sendStatus = sinon.stub()
|
|
|
- this.CompileController.deleteAuxFiles(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.deleteAuxFiles(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy to the CLSI', function () {
|
|
it('should proxy to the CLSI', function () {
|
|
|
- this.CompileManager.deleteAuxFiles
|
|
|
|
|
|
|
+ this.CompileManager.promises.deleteAuxFiles
|
|
|
.calledWith(this.projectId, this.user_id, 'node-1')
|
|
.calledWith(this.projectId, this.user_id, 'node-1')
|
|
|
.should.equal(true)
|
|
.should.equal(true)
|
|
|
})
|
|
})
|
|
@@ -848,26 +860,25 @@ describe('CompileController', function () {
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
this.downloadPath = `/project/${this.projectId}/build/123/output/output.pdf`
|
|
this.downloadPath = `/project/${this.projectId}/build/123/output/output.pdf`
|
|
|
- this.CompileManager.compile.callsArgWith(3, null, 'success', [
|
|
|
|
|
- {
|
|
|
|
|
- path: 'output.pdf',
|
|
|
|
|
- url: this.downloadPath,
|
|
|
|
|
- },
|
|
|
|
|
- ])
|
|
|
|
|
- this.CompileController.proxyToClsi = sinon.stub()
|
|
|
|
|
|
|
+ this.CompileManager.promises.compile.resolves({
|
|
|
|
|
+ status: 'success',
|
|
|
|
|
+ outputFiles: [{ path: 'output.pdf', url: this.downloadPath }],
|
|
|
|
|
+ })
|
|
|
|
|
+ this.CompileController._proxyToClsi = sinon.stub()
|
|
|
this.res = { send: () => {}, sendStatus: sinon.stub() }
|
|
this.res = { send: () => {}, sendStatus: sinon.stub() }
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should call compile in the compile manager', function (done) {
|
|
|
|
|
- this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
|
- this.CompileManager.compile.calledWith(this.projectId).should.equal(true)
|
|
|
|
|
- done()
|
|
|
|
|
|
|
+ it('should call compile in the compile manager', async function () {
|
|
|
|
|
+ await this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
|
+ this.CompileManager.promises.compile
|
|
|
|
|
+ .calledWith(this.projectId)
|
|
|
|
|
+ .should.equal(true)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should proxy the res to the clsi with correct url', function (done) {
|
|
|
|
|
- this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
|
|
|
+ it('should proxy the res to the clsi with correct url', async function () {
|
|
|
|
|
+ await this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
sinon.assert.calledWith(
|
|
sinon.assert.calledWith(
|
|
|
- this.CompileController.proxyToClsi,
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi,
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
|
this.downloadPath,
|
|
this.downloadPath,
|
|
@@ -876,7 +887,7 @@ describe('CompileController', function () {
|
|
|
this.res
|
|
this.res
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
- this.CompileController.proxyToClsi
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi
|
|
|
.calledWith(
|
|
.calledWith(
|
|
|
this.projectId,
|
|
this.projectId,
|
|
|
'output-file',
|
|
'output-file',
|
|
@@ -886,38 +897,44 @@ describe('CompileController', function () {
|
|
|
this.res
|
|
this.res
|
|
|
)
|
|
)
|
|
|
.should.equal(true)
|
|
.should.equal(true)
|
|
|
- done()
|
|
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should not download anything on compilation failures', function () {
|
|
|
|
|
- this.CompileManager.compile.yields(new Error('failed'))
|
|
|
|
|
- this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
|
|
|
+ it('should not download anything on compilation failures', async function () {
|
|
|
|
|
+ this.CompileManager.promises.compile.rejects(new Error('failed'))
|
|
|
|
|
+ await this.CompileController.compileAndDownloadPdf(
|
|
|
|
|
+ this.req,
|
|
|
|
|
+ this.res,
|
|
|
|
|
+ this.next
|
|
|
|
|
+ )
|
|
|
this.res.sendStatus.should.have.been.calledWith(500)
|
|
this.res.sendStatus.should.have.been.calledWith(500)
|
|
|
- this.CompileController.proxyToClsi.should.not.have.been.called
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi.should.not.have.been.called
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('should not download anything on missing pdf', function () {
|
|
|
|
|
- this.CompileManager.compile.yields(null, 'success', [])
|
|
|
|
|
- this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
|
|
|
|
+ it('should not download anything on missing pdf', async function () {
|
|
|
|
|
+ this.CompileManager.promises.compile.resolves({
|
|
|
|
|
+ status: 'success',
|
|
|
|
|
+ outputFiles: [],
|
|
|
|
|
+ })
|
|
|
|
|
+ await this.CompileController.compileAndDownloadPdf(this.req, this.res)
|
|
|
this.res.sendStatus.should.have.been.calledWith(500)
|
|
this.res.sendStatus.should.have.been.calledWith(500)
|
|
|
- this.CompileController.proxyToClsi.should.not.have.been.called
|
|
|
|
|
|
|
+ this.CompileController._proxyToClsi.should.not.have.been.called
|
|
|
})
|
|
})
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
describe('wordCount', function () {
|
|
describe('wordCount', function () {
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.CompileManager.wordCount = sinon
|
|
|
|
|
|
|
+ beforeEach(async function () {
|
|
|
|
|
+ this.CompileManager.promises.wordCount = sinon
|
|
|
.stub()
|
|
.stub()
|
|
|
- .yields(null, { content: 'body' })
|
|
|
|
|
|
|
+ .resolves({ content: 'body' })
|
|
|
this.req.params = { Project_id: this.projectId }
|
|
this.req.params = { Project_id: this.projectId }
|
|
|
this.req.query = { clsiserverid: 'node-42' }
|
|
this.req.query = { clsiserverid: 'node-42' }
|
|
|
this.res.json = sinon.stub()
|
|
this.res.json = sinon.stub()
|
|
|
this.res.contentType = sinon.stub()
|
|
this.res.contentType = sinon.stub()
|
|
|
- this.CompileController.wordCount(this.req, this.res, this.next)
|
|
|
|
|
|
|
+ await this.CompileController.wordCount(this.req, this.res, this.next)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
it('should proxy to the CLSI', function () {
|
|
it('should proxy to the CLSI', function () {
|
|
|
- this.CompileManager.wordCount
|
|
|
|
|
|
|
+ this.CompileManager.promises.wordCount
|
|
|
.calledWith(this.projectId, this.user_id, false, 'node-42')
|
|
.calledWith(this.projectId, this.user_id, false, 'node-42')
|
|
|
.should.equal(true)
|
|
.should.equal(true)
|
|
|
})
|
|
})
|