CompileControllerTests.coffee 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. SandboxedModule = require('sandboxed-module')
  2. sinon = require('sinon')
  3. require('chai').should()
  4. modulePath = require('path').join __dirname, '../../../app/js/CompileController'
  5. tk = require("timekeeper")
  6. describe "CompileController", ->
  7. beforeEach ->
  8. @CompileController = SandboxedModule.require modulePath, requires:
  9. "./CompileManager": @CompileManager = {}
  10. "./RequestParser": @RequestParser = {}
  11. "settings-sharelatex": @Settings =
  12. apis:
  13. clsi:
  14. url: "http://clsi.example.com"
  15. "./ProjectPersistenceManager": @ProjectPersistenceManager = {}
  16. "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub(), err:sinon.stub(), warn: sinon.stub()}
  17. @Settings.externalUrl = "http://www.example.com"
  18. @req = {}
  19. @res = {}
  20. @next = sinon.stub()
  21. describe "compile", ->
  22. beforeEach ->
  23. @req.body = {
  24. compile: "mock-body"
  25. }
  26. @req.params =
  27. project_id: @project_id = "project-id-123"
  28. @request = {
  29. compile: "mock-parsed-request"
  30. }
  31. @request_with_project_id =
  32. compile: @request.compile
  33. project_id: @project_id
  34. @output_files = [{
  35. path: "output.pdf"
  36. type: "pdf"
  37. build: 1234
  38. }, {
  39. path: "output.log"
  40. type: "log"
  41. build: 1234
  42. }]
  43. @RequestParser.parse = sinon.stub().callsArgWith(1, null, @request)
  44. @ProjectPersistenceManager.markProjectAsJustAccessed = sinon.stub().callsArg(1)
  45. @res.status = sinon.stub().returnsThis()
  46. @res.send = sinon.stub()
  47. describe "successfully", ->
  48. beforeEach ->
  49. @CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, null, @output_files)
  50. @CompileController.compile @req, @res
  51. it "should parse the request", ->
  52. @RequestParser.parse
  53. .calledWith(@req.body)
  54. .should.equal true
  55. it "should run the compile for the specified project", ->
  56. @CompileManager.doCompileWithLock
  57. .calledWith(@request_with_project_id)
  58. .should.equal true
  59. it "should mark the project as accessed", ->
  60. @ProjectPersistenceManager.markProjectAsJustAccessed
  61. .calledWith(@project_id)
  62. .should.equal true
  63. it "should return the JSON response", ->
  64. @res.status.calledWith(200).should.equal true
  65. @res.send
  66. .calledWith(
  67. compile:
  68. status: "success"
  69. error: null
  70. outputFiles: @output_files.map (file) =>
  71. url: "#{@Settings.apis.clsi.url}/project/#{@project_id}/build/#{file.build}/output/#{file.path}"
  72. path: file.path
  73. type: file.type
  74. build: file.build
  75. )
  76. .should.equal true
  77. describe "with an error", ->
  78. beforeEach ->
  79. @CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, new Error(@message = "error message"), null)
  80. @CompileController.compile @req, @res
  81. it "should return the JSON response with the error", ->
  82. @res.status.calledWith(500).should.equal true
  83. @res.send
  84. .calledWith(
  85. compile:
  86. status: "error"
  87. error: @message
  88. outputFiles: []
  89. )
  90. .should.equal true
  91. describe "when the request times out", ->
  92. beforeEach ->
  93. @error = new Error(@message = "container timed out")
  94. @error.timedout = true
  95. @CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, @error, null)
  96. @CompileController.compile @req, @res
  97. it "should return the JSON response with the timeout status", ->
  98. @res.status.calledWith(200).should.equal true
  99. @res.send
  100. .calledWith(
  101. compile:
  102. status: "timedout"
  103. error: @message
  104. outputFiles: []
  105. )
  106. .should.equal true
  107. describe "when the request returns no output files", ->
  108. beforeEach ->
  109. @CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, null, [])
  110. @CompileController.compile @req, @res
  111. it "should return the JSON response with the failure status", ->
  112. @res.status.calledWith(200).should.equal true
  113. @res.send
  114. .calledWith(
  115. compile:
  116. error: null
  117. status: "failure"
  118. outputFiles: []
  119. )
  120. .should.equal true
  121. describe "syncFromCode", ->
  122. beforeEach ->
  123. @file = "main.tex"
  124. @line = 42
  125. @column = 5
  126. @project_id = "mock-project-id"
  127. @req.params =
  128. project_id: @project_id
  129. @req.query =
  130. file: @file
  131. line: @line.toString()
  132. column: @column.toString()
  133. @res.json = sinon.stub()
  134. @CompileManager.syncFromCode = sinon.stub().callsArgWith(5, null, @pdfPositions = ["mock-positions"])
  135. @CompileController.syncFromCode @req, @res, @next
  136. it "should find the corresponding location in the PDF", ->
  137. @CompileManager.syncFromCode
  138. .calledWith(@project_id, undefined, @file, @line, @column)
  139. .should.equal true
  140. it "should return the positions", ->
  141. @res.json
  142. .calledWith(
  143. pdf: @pdfPositions
  144. )
  145. .should.equal true
  146. describe "syncFromPdf", ->
  147. beforeEach ->
  148. @page = 5
  149. @h = 100.23
  150. @v = 45.67
  151. @project_id = "mock-project-id"
  152. @req.params =
  153. project_id: @project_id
  154. @req.query =
  155. page: @page.toString()
  156. h: @h.toString()
  157. v: @v.toString()
  158. @res.json = sinon.stub()
  159. @CompileManager.syncFromPdf = sinon.stub().callsArgWith(5, null, @codePositions = ["mock-positions"])
  160. @CompileController.syncFromPdf @req, @res, @next
  161. it "should find the corresponding location in the code", ->
  162. @CompileManager.syncFromPdf
  163. .calledWith(@project_id, undefined, @page, @h, @v)
  164. .should.equal true
  165. it "should return the positions", ->
  166. @res.json
  167. .calledWith(
  168. code: @codePositions
  169. )
  170. .should.equal true
  171. describe "wordcount", ->
  172. beforeEach ->
  173. @file = "main.tex"
  174. @project_id = "mock-project-id"
  175. @req.params =
  176. project_id: @project_id
  177. @req.query =
  178. file: @file
  179. image: @image = "example.com/image"
  180. @res.json = sinon.stub()
  181. @CompileManager.wordcount = sinon.stub().callsArgWith(4, null, @texcount = ["mock-texcount"])
  182. @CompileController.wordcount @req, @res, @next
  183. it "should return the word count of a file", ->
  184. @CompileManager.wordcount
  185. .calledWith(@project_id, undefined, @file, @image)
  186. .should.equal true
  187. it "should return the texcount info", ->
  188. @res.json
  189. .calledWith(
  190. texcount: @texcount
  191. )
  192. .should.equal true