CompileControllerTests.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. /* eslint-disable
  2. camelcase,
  3. max-len,
  4. no-return-assign,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS102: Remove unnecessary code created because of implicit returns
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. const sinon = require('sinon')
  15. const { assert, expect } = require('chai')
  16. const modulePath = '../../../../app/src/Features/Compile/CompileController.js'
  17. const SandboxedModule = require('sandboxed-module')
  18. const MockRequest = require('../helpers/MockRequest')
  19. const MockResponse = require('../helpers/MockResponse')
  20. describe('CompileController', function () {
  21. beforeEach(function () {
  22. this.user_id = 'wat'
  23. this.user = {
  24. _id: this.user_id,
  25. email: 'user@example.com',
  26. features: {
  27. compileGroup: 'premium',
  28. compileTimeout: 100,
  29. },
  30. }
  31. this.CompileManager = { compile: sinon.stub() }
  32. this.ClsiManager = {}
  33. this.UserGetter = { getUser: sinon.stub() }
  34. this.RateLimiter = { addCount: sinon.stub() }
  35. this.settings = {
  36. apis: {
  37. clsi: {
  38. url: 'clsi.example.com',
  39. },
  40. clsi_priority: {
  41. url: 'clsi-priority.example.com',
  42. },
  43. },
  44. defaultFeatures: {
  45. compileGroup: 'standard',
  46. compileTimeout: 60,
  47. },
  48. }
  49. this.jar = { cookie: 'stuff' }
  50. this.ClsiCookieManager = {
  51. getCookieJar: sinon.stub().callsArgWith(1, null, this.jar),
  52. }
  53. this.AuthenticationController = {
  54. getLoggedInUser: sinon.stub().callsArgWith(1, null, this.user),
  55. getLoggedInUserId: sinon.stub().returns(this.user_id),
  56. getSessionUser: sinon.stub().returns(this.user),
  57. isUserLoggedIn: sinon.stub().returns(true),
  58. }
  59. this.CompileController = SandboxedModule.require(modulePath, {
  60. requires: {
  61. 'settings-sharelatex': this.settings,
  62. request: (this.request = sinon.stub()),
  63. '../Project/ProjectGetter': (this.ProjectGetter = {}),
  64. '@overleaf/metrics': (this.Metrics = { inc: sinon.stub() }),
  65. './CompileManager': this.CompileManager,
  66. '../User/UserGetter': this.UserGetter,
  67. './ClsiManager': this.ClsiManager,
  68. '../Authentication/AuthenticationController': this
  69. .AuthenticationController,
  70. '../../infrastructure/RateLimiter': this.RateLimiter,
  71. './ClsiCookieManager': () => this.ClsiCookieManager,
  72. },
  73. })
  74. this.project_id = 'project-id'
  75. this.next = sinon.stub()
  76. this.req = new MockRequest()
  77. return (this.res = new MockResponse())
  78. })
  79. describe('compile', function () {
  80. beforeEach(function () {
  81. this.req.params = { Project_id: this.project_id }
  82. this.req.session = {}
  83. return (this.CompileManager.compile = sinon
  84. .stub()
  85. .callsArgWith(
  86. 3,
  87. null,
  88. (this.status = 'success'),
  89. (this.outputFiles = ['mock-output-files'])
  90. ))
  91. })
  92. describe('when not an auto compile', function () {
  93. beforeEach(function () {
  94. return this.CompileController.compile(this.req, this.res, this.next)
  95. })
  96. it('should look up the user id', function () {
  97. return this.AuthenticationController.getLoggedInUserId
  98. .calledWith(this.req)
  99. .should.equal(true)
  100. })
  101. it('should do the compile without the auto compile flag', function () {
  102. return this.CompileManager.compile
  103. .calledWith(this.project_id, this.user_id, {
  104. isAutoCompile: false,
  105. enablePdfCaching: false,
  106. })
  107. .should.equal(true)
  108. })
  109. it('should set the content-type of the response to application/json', function () {
  110. this.res.type.should.equal('application/json')
  111. })
  112. it('should send a successful response reporting the status and files', function () {
  113. this.res.statusCode.should.equal(200)
  114. this.res.body.should.equal(
  115. JSON.stringify({
  116. status: this.status,
  117. outputFiles: this.outputFiles,
  118. })
  119. )
  120. })
  121. })
  122. describe('when an auto compile', function () {
  123. beforeEach(function () {
  124. this.req.query = { auto_compile: 'true' }
  125. return this.CompileController.compile(this.req, this.res, this.next)
  126. })
  127. it('should do the compile with the auto compile flag', function () {
  128. return this.CompileManager.compile
  129. .calledWith(this.project_id, this.user_id, {
  130. isAutoCompile: true,
  131. enablePdfCaching: false,
  132. })
  133. .should.equal(true)
  134. })
  135. })
  136. describe('with the draft attribute', function () {
  137. beforeEach(function () {
  138. this.req.body = { draft: true }
  139. return this.CompileController.compile(this.req, this.res, this.next)
  140. })
  141. it('should do the compile without the draft compile flag', function () {
  142. return this.CompileManager.compile
  143. .calledWith(this.project_id, this.user_id, {
  144. isAutoCompile: false,
  145. enablePdfCaching: false,
  146. draft: true,
  147. })
  148. .should.equal(true)
  149. })
  150. })
  151. })
  152. describe('compileSubmission', function () {
  153. beforeEach(function () {
  154. this.submission_id = 'sub-1234'
  155. this.req.params = { submission_id: this.submission_id }
  156. this.req.body = {}
  157. return (this.ClsiManager.sendExternalRequest = sinon
  158. .stub()
  159. .callsArgWith(
  160. 3,
  161. null,
  162. (this.status = 'success'),
  163. (this.outputFiles = ['mock-output-files']),
  164. (this.clsiServerId = 'mock-server-id'),
  165. (this.validationProblems = null)
  166. ))
  167. })
  168. it('should set the content-type of the response to application/json', function () {
  169. this.CompileController.compileSubmission(this.req, this.res, this.next)
  170. return this.res.contentType
  171. .calledWith('application/json')
  172. .should.equal(true)
  173. })
  174. it('should send a successful response reporting the status and files', function () {
  175. this.CompileController.compileSubmission(this.req, this.res, this.next)
  176. this.res.statusCode.should.equal(200)
  177. return this.res.body.should.equal(
  178. JSON.stringify({
  179. status: this.status,
  180. outputFiles: this.outputFiles,
  181. clsiServerId: 'mock-server-id',
  182. validationProblems: null,
  183. })
  184. )
  185. })
  186. describe('with compileGroup and timeout', function () {
  187. beforeEach(function () {
  188. this.req.body = {
  189. compileGroup: 'special',
  190. timeout: 600,
  191. }
  192. return this.CompileController.compileSubmission(
  193. this.req,
  194. this.res,
  195. this.next
  196. )
  197. })
  198. it('should use the supplied values', function () {
  199. return this.ClsiManager.sendExternalRequest
  200. .calledWith(
  201. this.submission_id,
  202. { compileGroup: 'special', timeout: 600 },
  203. { compileGroup: 'special', timeout: 600 }
  204. )
  205. .should.equal(true)
  206. })
  207. })
  208. describe('with other supported options but not compileGroup and timeout', function () {
  209. beforeEach(function () {
  210. this.req.body = {
  211. rootResourcePath: 'main.tex',
  212. compiler: 'lualatex',
  213. draft: true,
  214. check: 'validate',
  215. }
  216. return this.CompileController.compileSubmission(
  217. this.req,
  218. this.res,
  219. this.next
  220. )
  221. })
  222. it('should use the other options but default values for compileGroup and timeout', function () {
  223. return this.ClsiManager.sendExternalRequest
  224. .calledWith(
  225. this.submission_id,
  226. {
  227. rootResourcePath: 'main.tex',
  228. compiler: 'lualatex',
  229. draft: true,
  230. check: 'validate',
  231. },
  232. {
  233. rootResourcePath: 'main.tex',
  234. compiler: 'lualatex',
  235. draft: true,
  236. check: 'validate',
  237. compileGroup: 'standard',
  238. timeout: 60,
  239. }
  240. )
  241. .should.equal(true)
  242. })
  243. })
  244. })
  245. describe('downloadPdf', function () {
  246. beforeEach(function () {
  247. this.req.params = { Project_id: this.project_id }
  248. this.req.query = { pdfng: true }
  249. this.project = { name: 'test namè' }
  250. return (this.ProjectGetter.getProject = sinon
  251. .stub()
  252. .callsArgWith(2, null, this.project))
  253. })
  254. describe('when downloading for embedding', function () {
  255. beforeEach(function () {
  256. this.CompileController.proxyToClsi = sinon.stub()
  257. this.RateLimiter.addCount.callsArgWith(1, null, true)
  258. return this.CompileController.downloadPdf(this.req, this.res, this.next)
  259. })
  260. it('should look up the project', function () {
  261. return this.ProjectGetter.getProject
  262. .calledWith(this.project_id, { name: 1 })
  263. .should.equal(true)
  264. })
  265. it('should set the content-type of the response to application/pdf', function () {
  266. return this.res.contentType
  267. .calledWith('application/pdf')
  268. .should.equal(true)
  269. })
  270. it('should set the content-disposition header with a safe version of the project name', function () {
  271. return this.res.setContentDisposition
  272. .calledWith('', { filename: 'test_nam_.pdf' })
  273. .should.equal(true)
  274. })
  275. it('should increment the pdf-downloads metric', function () {
  276. return this.Metrics.inc.calledWith('pdf-downloads').should.equal(true)
  277. })
  278. it('should proxy the PDF from the CLSI', function () {
  279. return this.CompileController.proxyToClsi
  280. .calledWith(
  281. this.project_id,
  282. `/project/${this.project_id}/user/${this.user_id}/output/output.pdf`,
  283. this.req,
  284. this.res,
  285. this.next
  286. )
  287. .should.equal(true)
  288. })
  289. })
  290. describe('when the a build-id is provided', function () {
  291. beforeEach(function () {
  292. this.req.params.build_id = this.buildId = '1234-5678'
  293. this.CompileController.proxyToClsi = sinon.stub()
  294. this.RateLimiter.addCount.callsArgWith(1, null, true)
  295. return this.CompileController.downloadPdf(this.req, this.res, this.next)
  296. })
  297. it('should proxy the PDF from the CLSI, with a build-id', function () {
  298. return this.CompileController.proxyToClsi
  299. .calledWith(
  300. this.project_id,
  301. `/project/${this.project_id}/user/${this.user_id}/build/${this.buildId}/output/output.pdf`,
  302. this.req,
  303. this.res,
  304. this.next
  305. )
  306. .should.equal(true)
  307. })
  308. })
  309. describe('when the pdf is not going to be used in pdfjs viewer', function () {
  310. it('should check the rate limiter when pdfng is not set', function (done) {
  311. this.req.query = {}
  312. this.RateLimiter.addCount.callsArgWith(1, null, true)
  313. this.CompileController.proxyToClsi = (project_id, url) => {
  314. this.RateLimiter.addCount.args[0][0].throttle.should.equal(1000)
  315. return done()
  316. }
  317. return this.CompileController.downloadPdf(this.req, this.res)
  318. })
  319. it('should check the rate limiter when pdfng is false', function (done) {
  320. this.req.query = { pdfng: false }
  321. this.RateLimiter.addCount.callsArgWith(1, null, true)
  322. this.CompileController.proxyToClsi = (project_id, url) => {
  323. this.RateLimiter.addCount.args[0][0].throttle.should.equal(1000)
  324. return done()
  325. }
  326. return this.CompileController.downloadPdf(this.req, this.res)
  327. })
  328. })
  329. })
  330. describe('getFileFromClsiWithoutUser', function () {
  331. beforeEach(function () {
  332. this.submission_id = 'sub-1234'
  333. this.build_id = 123456
  334. this.file = 'project.pdf'
  335. this.req.params = {
  336. submission_id: this.submission_id,
  337. build_id: this.build_id,
  338. file: this.file,
  339. }
  340. this.req.body = {}
  341. this.expected_url = `/project/${this.submission_id}/build/${this.build_id}/output/${this.file}`
  342. return (this.CompileController.proxyToClsiWithLimits = sinon.stub())
  343. })
  344. describe('without limits specified', function () {
  345. beforeEach(function () {
  346. return this.CompileController.getFileFromClsiWithoutUser(
  347. this.req,
  348. this.res,
  349. this.next
  350. )
  351. })
  352. it('should proxy to CLSI with correct URL and default limits', function () {
  353. return this.CompileController.proxyToClsiWithLimits
  354. .calledWith(this.submission_id, this.expected_url, {
  355. compileGroup: 'standard',
  356. })
  357. .should.equal(true)
  358. })
  359. })
  360. describe('with limits specified', function () {
  361. beforeEach(function () {
  362. this.req.body = { compileTimeout: 600, compileGroup: 'special' }
  363. return this.CompileController.getFileFromClsiWithoutUser(
  364. this.req,
  365. this.res,
  366. this.next
  367. )
  368. })
  369. it('should proxy to CLSI with correct URL and specified limits', function () {
  370. return this.CompileController.proxyToClsiWithLimits
  371. .calledWith(this.submission_id, this.expected_url, {
  372. compileGroup: 'special',
  373. })
  374. .should.equal(true)
  375. })
  376. })
  377. })
  378. describe('proxySyncCode', function () {
  379. let file, line, column, imageName
  380. beforeEach(function (done) {
  381. this.req.params = { Project_id: this.project_id }
  382. file = 'main.tex'
  383. line = String(Date.now())
  384. column = String(Date.now() + 1)
  385. this.req.query = { file, line, column }
  386. imageName = 'foo/bar:tag-0'
  387. this.ProjectGetter.getProject = sinon.stub().yields(null, { imageName })
  388. this.next.callsFake(done)
  389. this.res.callback = done
  390. this.CompileController.proxyToClsi = sinon.stub().callsFake(() => done())
  391. this.CompileController.proxySyncCode(this.req, this.res, this.next)
  392. })
  393. it('should proxy the request with an imageName', function () {
  394. expect(this.CompileController.proxyToClsi).to.have.been.calledWith(
  395. this.project_id,
  396. {
  397. url: `/project/${this.project_id}/user/${this.user_id}/sync/code`,
  398. qs: { file, line, column, imageName },
  399. },
  400. this.req,
  401. this.res,
  402. this.next
  403. )
  404. })
  405. })
  406. describe('proxySyncPdf', function () {
  407. let page, h, v, imageName
  408. beforeEach(function (done) {
  409. this.req.params = { Project_id: this.project_id }
  410. page = String(Date.now())
  411. h = String(Math.random())
  412. v = String(Math.random())
  413. this.req.query = { page, h, v }
  414. imageName = 'foo/bar:tag-1'
  415. this.ProjectGetter.getProject = sinon.stub().yields(null, { imageName })
  416. this.next.callsFake(done)
  417. this.res.callback = done
  418. this.CompileController.proxyToClsi = sinon.stub().callsFake(() => done())
  419. this.CompileController.proxySyncPdf(this.req, this.res, this.next)
  420. })
  421. it('should proxy the request with an imageName', function () {
  422. expect(this.CompileController.proxyToClsi).to.have.been.calledWith(
  423. this.project_id,
  424. {
  425. url: `/project/${this.project_id}/user/${this.user_id}/sync/pdf`,
  426. qs: { page, h, v, imageName },
  427. },
  428. this.req,
  429. this.res,
  430. this.next
  431. )
  432. })
  433. })
  434. describe('proxyToClsi', function () {
  435. beforeEach(function () {
  436. this.request.returns(
  437. (this.proxy = {
  438. pipe: sinon.stub(),
  439. on: sinon.stub(),
  440. })
  441. )
  442. this.upstream = {
  443. statusCode: 204,
  444. headers: { mock: 'header' },
  445. }
  446. this.req.method = 'mock-method'
  447. return (this.req.headers = {
  448. Mock: 'Headers',
  449. Range: '123-456',
  450. 'If-Range': 'abcdef',
  451. 'If-Modified-Since': 'Mon, 15 Dec 2014 15:23:56 GMT',
  452. })
  453. })
  454. describe('old pdf viewer', function () {
  455. describe('user with standard priority', function () {
  456. beforeEach(function () {
  457. this.CompileManager.getProjectCompileLimits = sinon
  458. .stub()
  459. .callsArgWith(1, null, { compileGroup: 'standard' })
  460. return this.CompileController.proxyToClsi(
  461. this.project_id,
  462. (this.url = '/test'),
  463. this.req,
  464. this.res,
  465. this.next
  466. )
  467. })
  468. it('should open a request to the CLSI', function () {
  469. return this.request
  470. .calledWith({
  471. jar: this.jar,
  472. method: this.req.method,
  473. url: `${this.settings.apis.clsi.url}${this.url}`,
  474. timeout: 60 * 1000,
  475. })
  476. .should.equal(true)
  477. })
  478. it('should pass the request on to the client', function () {
  479. return this.proxy.pipe.calledWith(this.res).should.equal(true)
  480. })
  481. it('should bind an error handle to the request proxy', function () {
  482. return this.proxy.on.calledWith('error').should.equal(true)
  483. })
  484. })
  485. describe('user with priority compile', function () {
  486. beforeEach(function () {
  487. this.CompileManager.getProjectCompileLimits = sinon
  488. .stub()
  489. .callsArgWith(1, null, { compileGroup: 'priority' })
  490. return this.CompileController.proxyToClsi(
  491. this.project_id,
  492. (this.url = '/test'),
  493. this.req,
  494. this.res,
  495. this.next
  496. )
  497. })
  498. })
  499. describe('user with standard priority via query string', function () {
  500. beforeEach(function () {
  501. this.req.query = { compileGroup: 'standard' }
  502. return this.CompileController.proxyToClsi(
  503. this.project_id,
  504. (this.url = '/test'),
  505. this.req,
  506. this.res,
  507. this.next
  508. )
  509. })
  510. it('should open a request to the CLSI', function () {
  511. return this.request
  512. .calledWith({
  513. jar: this.jar,
  514. method: this.req.method,
  515. url: `${this.settings.apis.clsi.url}${this.url}`,
  516. timeout: 60 * 1000,
  517. })
  518. .should.equal(true)
  519. })
  520. it('should pass the request on to the client', function () {
  521. return this.proxy.pipe.calledWith(this.res).should.equal(true)
  522. })
  523. it('should bind an error handle to the request proxy', function () {
  524. return this.proxy.on.calledWith('error').should.equal(true)
  525. })
  526. })
  527. describe('user with non-existent priority via query string', function () {
  528. beforeEach(function () {
  529. this.req.query = { compileGroup: 'foobar' }
  530. return this.CompileController.proxyToClsi(
  531. this.project_id,
  532. (this.url = '/test'),
  533. this.req,
  534. this.res,
  535. this.next
  536. )
  537. })
  538. it('should proxy to the standard url', function () {
  539. return this.request
  540. .calledWith({
  541. jar: this.jar,
  542. method: this.req.method,
  543. url: `${this.settings.apis.clsi.url}${this.url}`,
  544. timeout: 60 * 1000,
  545. })
  546. .should.equal(true)
  547. })
  548. })
  549. describe('user with build parameter via query string', function () {
  550. beforeEach(function () {
  551. this.CompileManager.getProjectCompileLimits = sinon
  552. .stub()
  553. .callsArgWith(1, null, { compileGroup: 'standard' })
  554. this.req.query = { build: 1234 }
  555. return this.CompileController.proxyToClsi(
  556. this.project_id,
  557. (this.url = '/test'),
  558. this.req,
  559. this.res,
  560. this.next
  561. )
  562. })
  563. it('should proxy to the standard url without the build parameter', function () {
  564. return this.request
  565. .calledWith({
  566. jar: this.jar,
  567. method: this.req.method,
  568. url: `${this.settings.apis.clsi.url}${this.url}`,
  569. timeout: 60 * 1000,
  570. })
  571. .should.equal(true)
  572. })
  573. })
  574. })
  575. describe('new pdf viewer', function () {
  576. beforeEach(function () {
  577. return (this.req.query = { pdfng: true })
  578. })
  579. describe('user with standard priority', function () {
  580. beforeEach(function () {
  581. this.CompileManager.getProjectCompileLimits = sinon
  582. .stub()
  583. .callsArgWith(1, null, { compileGroup: 'standard' })
  584. return this.CompileController.proxyToClsi(
  585. this.project_id,
  586. (this.url = '/test'),
  587. this.req,
  588. this.res,
  589. this.next
  590. )
  591. })
  592. it('should open a request to the CLSI', function () {
  593. return this.request
  594. .calledWith({
  595. jar: this.jar,
  596. method: this.req.method,
  597. url: `${this.settings.apis.clsi.url}${this.url}`,
  598. timeout: 60 * 1000,
  599. headers: {
  600. Range: '123-456',
  601. 'If-Range': 'abcdef',
  602. 'If-Modified-Since': 'Mon, 15 Dec 2014 15:23:56 GMT',
  603. },
  604. })
  605. .should.equal(true)
  606. })
  607. it('should pass the request on to the client', function () {
  608. return this.proxy.pipe.calledWith(this.res).should.equal(true)
  609. })
  610. it('should bind an error handle to the request proxy', function () {
  611. return this.proxy.on.calledWith('error').should.equal(true)
  612. })
  613. })
  614. describe('user with build parameter via query string', function () {
  615. beforeEach(function () {
  616. this.CompileManager.getProjectCompileLimits = sinon
  617. .stub()
  618. .callsArgWith(1, null, { compileGroup: 'standard' })
  619. this.req.query = { build: 1234, pdfng: true }
  620. return this.CompileController.proxyToClsi(
  621. this.project_id,
  622. (this.url = '/test'),
  623. this.req,
  624. this.res,
  625. this.next
  626. )
  627. })
  628. it('should proxy to the standard url with the build parameter', function () {
  629. return this.request
  630. .calledWith({
  631. jar: this.jar,
  632. method: this.req.method,
  633. qs: { build: 1234 },
  634. url: `${this.settings.apis.clsi.url}${this.url}`,
  635. timeout: 60 * 1000,
  636. headers: {
  637. Range: '123-456',
  638. 'If-Range': 'abcdef',
  639. 'If-Modified-Since': 'Mon, 15 Dec 2014 15:23:56 GMT',
  640. },
  641. })
  642. .should.equal(true)
  643. })
  644. })
  645. })
  646. })
  647. describe('deleteAuxFiles', function () {
  648. beforeEach(function () {
  649. this.CompileManager.deleteAuxFiles = sinon.stub().yields()
  650. this.req.params = { Project_id: this.project_id }
  651. this.req.query = { clsiserverid: 'node-1' }
  652. this.res.sendStatus = sinon.stub()
  653. return this.CompileController.deleteAuxFiles(
  654. this.req,
  655. this.res,
  656. this.next
  657. )
  658. })
  659. it('should proxy to the CLSI', function () {
  660. return this.CompileManager.deleteAuxFiles
  661. .calledWith(this.project_id, this.user_id, 'node-1')
  662. .should.equal(true)
  663. })
  664. it('should return a 200', function () {
  665. return this.res.sendStatus.calledWith(200).should.equal(true)
  666. })
  667. })
  668. describe('compileAndDownloadPdf', function () {
  669. beforeEach(function () {
  670. this.req = {
  671. params: {
  672. project_id: this.project_id,
  673. },
  674. }
  675. this.CompileManager.compile.callsArgWith(3)
  676. this.CompileController.proxyToClsi = sinon.stub()
  677. return (this.res = { send: () => {} })
  678. })
  679. it('should call compile in the compile manager', function (done) {
  680. this.CompileController.compileAndDownloadPdf(this.req, this.res)
  681. this.CompileManager.compile.calledWith(this.project_id).should.equal(true)
  682. return done()
  683. })
  684. it('should proxy the res to the clsi with correct url', function (done) {
  685. this.CompileController.compileAndDownloadPdf(this.req, this.res)
  686. sinon.assert.calledWith(
  687. this.CompileController.proxyToClsi,
  688. this.project_id,
  689. `/project/${this.project_id}/output/output.pdf`,
  690. this.req,
  691. this.res
  692. )
  693. this.CompileController.proxyToClsi
  694. .calledWith(
  695. this.project_id,
  696. `/project/${this.project_id}/output/output.pdf`,
  697. this.req,
  698. this.res
  699. )
  700. .should.equal(true)
  701. return done()
  702. })
  703. })
  704. describe('wordCount', function () {
  705. beforeEach(function () {
  706. this.CompileManager.wordCount = sinon
  707. .stub()
  708. .yields(null, { content: 'body' })
  709. this.req.params = { Project_id: this.project_id }
  710. this.req.query = { clsiserverid: 'node-42' }
  711. this.res.send = sinon.stub()
  712. this.res.contentType = sinon.stub()
  713. return this.CompileController.wordCount(this.req, this.res, this.next)
  714. })
  715. it('should proxy to the CLSI', function () {
  716. return this.CompileManager.wordCount
  717. .calledWith(this.project_id, this.user_id, false, 'node-42')
  718. .should.equal(true)
  719. })
  720. it('should return a 200 and body', function () {
  721. return this.res.send.calledWith({ content: 'body' }).should.equal(true)
  722. })
  723. })
  724. })