CompileControllerTests.coffee 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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() }
  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.send = sinon.stub()
  46. describe "successfully", ->
  47. beforeEach ->
  48. @CompileManager.doCompile = sinon.stub().callsArgWith(1, null, @output_files)
  49. @CompileController.compile @req, @res
  50. it "should parse the request", ->
  51. @RequestParser.parse
  52. .calledWith(@req.body)
  53. .should.equal true
  54. it "should run the compile for the specified project", ->
  55. @CompileManager.doCompile
  56. .calledWith(@request_with_project_id)
  57. .should.equal true
  58. it "should mark the project as accessed", ->
  59. @ProjectPersistenceManager.markProjectAsJustAccessed
  60. .calledWith(@project_id)
  61. .should.equal true
  62. it "should return the JSON response", ->
  63. @res.send
  64. .calledWith(200,
  65. compile:
  66. status: "success"
  67. error: null
  68. outputFiles: @output_files.map (file) =>
  69. url: "#{@Settings.apis.clsi.url}/project/#{@project_id}/output/#{file.path}"
  70. type: file.type
  71. build: file.build
  72. )
  73. .should.equal true
  74. describe "with an error", ->
  75. beforeEach ->
  76. @CompileManager.doCompile = sinon.stub().callsArgWith(1, new Error(@message = "error message"), null)
  77. @CompileController.compile @req, @res
  78. it "should return the JSON response with the error", ->
  79. @res.send
  80. .calledWith(500,
  81. compile:
  82. status: "error"
  83. error: @message
  84. outputFiles: []
  85. )
  86. .should.equal true
  87. describe "when the request times out", ->
  88. beforeEach ->
  89. @error = new Error(@message = "container timed out")
  90. @error.timedout = true
  91. @CompileManager.doCompile = sinon.stub().callsArgWith(1, @error, null)
  92. @CompileController.compile @req, @res
  93. it "should return the JSON response with the timeout status", ->
  94. @res.send
  95. .calledWith(200,
  96. compile:
  97. status: "timedout"
  98. error: @message
  99. outputFiles: []
  100. )
  101. .should.equal true
  102. describe "when the request returns no output files", ->
  103. beforeEach ->
  104. @CompileManager.doCompile = sinon.stub().callsArgWith(1, null, [])
  105. @CompileController.compile @req, @res
  106. it "should return the JSON response with the failure status", ->
  107. @res.send
  108. .calledWith(200,
  109. compile:
  110. error: null
  111. status: "failure"
  112. outputFiles: []
  113. )
  114. .should.equal true
  115. describe "syncFromCode", ->
  116. beforeEach ->
  117. @file = "main.tex"
  118. @line = 42
  119. @column = 5
  120. @project_id = "mock-project-id"
  121. @req.params =
  122. project_id: @project_id
  123. @req.query =
  124. file: @file
  125. line: @line.toString()
  126. column: @column.toString()
  127. @res.send = sinon.stub()
  128. @CompileManager.syncFromCode = sinon.stub().callsArgWith(4, null, @pdfPositions = ["mock-positions"])
  129. @CompileController.syncFromCode @req, @res, @next
  130. it "should find the corresponding location in the PDF", ->
  131. @CompileManager.syncFromCode
  132. .calledWith(@project_id, @file, @line, @column)
  133. .should.equal true
  134. it "should return the positions", ->
  135. @res.send
  136. .calledWith(JSON.stringify
  137. pdf: @pdfPositions
  138. )
  139. .should.equal true
  140. describe "syncFromPdf", ->
  141. beforeEach ->
  142. @page = 5
  143. @h = 100.23
  144. @v = 45.67
  145. @project_id = "mock-project-id"
  146. @req.params =
  147. project_id: @project_id
  148. @req.query =
  149. page: @page.toString()
  150. h: @h.toString()
  151. v: @v.toString()
  152. @res.send = sinon.stub()
  153. @CompileManager.syncFromPdf = sinon.stub().callsArgWith(4, null, @codePositions = ["mock-positions"])
  154. @CompileController.syncFromPdf @req, @res, @next
  155. it "should find the corresponding location in the code", ->
  156. @CompileManager.syncFromPdf
  157. .calledWith(@project_id, @page, @h, @v)
  158. .should.equal true
  159. it "should return the positions", ->
  160. @res.send
  161. .calledWith(JSON.stringify
  162. code: @codePositions
  163. )
  164. .should.equal true