CompileControllerTests.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /* eslint-disable
  2. no-return-assign,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const SandboxedModule = require('sandboxed-module');
  13. const sinon = require('sinon');
  14. require('chai').should();
  15. const modulePath = require('path').join(__dirname, '../../../app/js/CompileController');
  16. const tk = require("timekeeper");
  17. describe("CompileController", function() {
  18. beforeEach(function() {
  19. this.CompileController = SandboxedModule.require(modulePath, { requires: {
  20. "./CompileManager": (this.CompileManager = {}),
  21. "./RequestParser": (this.RequestParser = {}),
  22. "settings-sharelatex": (this.Settings = {
  23. apis: {
  24. clsi: {
  25. url: "http://clsi.example.com"
  26. }
  27. }
  28. }),
  29. "./ProjectPersistenceManager": (this.ProjectPersistenceManager = {}),
  30. "logger-sharelatex": (this.logger = { log: sinon.stub(), error: sinon.stub(), err:sinon.stub(), warn: sinon.stub()})
  31. }
  32. });
  33. this.Settings.externalUrl = "http://www.example.com";
  34. this.req = {};
  35. this.res = {};
  36. return this.next = sinon.stub();
  37. });
  38. describe("compile", function() {
  39. beforeEach(function() {
  40. this.req.body = {
  41. compile: "mock-body"
  42. };
  43. this.req.params =
  44. {project_id: (this.project_id = "project-id-123")};
  45. this.request = {
  46. compile: "mock-parsed-request"
  47. };
  48. this.request_with_project_id = {
  49. compile: this.request.compile,
  50. project_id: this.project_id
  51. };
  52. this.output_files = [{
  53. path: "output.pdf",
  54. type: "pdf",
  55. build: 1234
  56. }, {
  57. path: "output.log",
  58. type: "log",
  59. build: 1234
  60. }];
  61. this.RequestParser.parse = sinon.stub().callsArgWith(1, null, this.request);
  62. this.ProjectPersistenceManager.markProjectAsJustAccessed = sinon.stub().callsArg(1);
  63. this.res.status = sinon.stub().returnsThis();
  64. return this.res.send = sinon.stub();
  65. });
  66. describe("successfully", function() {
  67. beforeEach(function() {
  68. this.CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, null, this.output_files);
  69. return this.CompileController.compile(this.req, this.res);
  70. });
  71. it("should parse the request", function() {
  72. return this.RequestParser.parse
  73. .calledWith(this.req.body)
  74. .should.equal(true);
  75. });
  76. it("should run the compile for the specified project", function() {
  77. return this.CompileManager.doCompileWithLock
  78. .calledWith(this.request_with_project_id)
  79. .should.equal(true);
  80. });
  81. it("should mark the project as accessed", function() {
  82. return this.ProjectPersistenceManager.markProjectAsJustAccessed
  83. .calledWith(this.project_id)
  84. .should.equal(true);
  85. });
  86. return it("should return the JSON response", function() {
  87. this.res.status.calledWith(200).should.equal(true);
  88. return this.res.send
  89. .calledWith({
  90. compile: {
  91. status: "success",
  92. error: null,
  93. outputFiles: this.output_files.map(file => {
  94. return {
  95. url: `${this.Settings.apis.clsi.url}/project/${this.project_id}/build/${file.build}/output/${file.path}`,
  96. path: file.path,
  97. type: file.type,
  98. build: file.build
  99. };
  100. })
  101. }
  102. })
  103. .should.equal(true);
  104. });
  105. });
  106. describe("with an error", function() {
  107. beforeEach(function() {
  108. this.CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, new Error(this.message = "error message"), null);
  109. return this.CompileController.compile(this.req, this.res);
  110. });
  111. return it("should return the JSON response with the error", function() {
  112. this.res.status.calledWith(500).should.equal(true);
  113. return this.res.send
  114. .calledWith({
  115. compile: {
  116. status: "error",
  117. error: this.message,
  118. outputFiles: []
  119. }
  120. })
  121. .should.equal(true);
  122. });
  123. });
  124. describe("when the request times out", function() {
  125. beforeEach(function() {
  126. this.error = new Error(this.message = "container timed out");
  127. this.error.timedout = true;
  128. this.CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, this.error, null);
  129. return this.CompileController.compile(this.req, this.res);
  130. });
  131. return it("should return the JSON response with the timeout status", function() {
  132. this.res.status.calledWith(200).should.equal(true);
  133. return this.res.send
  134. .calledWith({
  135. compile: {
  136. status: "timedout",
  137. error: this.message,
  138. outputFiles: []
  139. }
  140. })
  141. .should.equal(true);
  142. });
  143. });
  144. return describe("when the request returns no output files", function() {
  145. beforeEach(function() {
  146. this.CompileManager.doCompileWithLock = sinon.stub().callsArgWith(1, null, []);
  147. return this.CompileController.compile(this.req, this.res);
  148. });
  149. return it("should return the JSON response with the failure status", function() {
  150. this.res.status.calledWith(200).should.equal(true);
  151. return this.res.send
  152. .calledWith({
  153. compile: {
  154. error: null,
  155. status: "failure",
  156. outputFiles: []
  157. }
  158. })
  159. .should.equal(true);
  160. });
  161. });
  162. });
  163. describe("syncFromCode", function() {
  164. beforeEach(function() {
  165. this.file = "main.tex";
  166. this.line = 42;
  167. this.column = 5;
  168. this.project_id = "mock-project-id";
  169. this.req.params =
  170. {project_id: this.project_id};
  171. this.req.query = {
  172. file: this.file,
  173. line: this.line.toString(),
  174. column: this.column.toString()
  175. };
  176. this.res.json = sinon.stub();
  177. this.CompileManager.syncFromCode = sinon.stub().callsArgWith(5, null, (this.pdfPositions = ["mock-positions"]));
  178. return this.CompileController.syncFromCode(this.req, this.res, this.next);
  179. });
  180. it("should find the corresponding location in the PDF", function() {
  181. return this.CompileManager.syncFromCode
  182. .calledWith(this.project_id, undefined, this.file, this.line, this.column)
  183. .should.equal(true);
  184. });
  185. return it("should return the positions", function() {
  186. return this.res.json
  187. .calledWith({
  188. pdf: this.pdfPositions
  189. })
  190. .should.equal(true);
  191. });
  192. });
  193. describe("syncFromPdf", function() {
  194. beforeEach(function() {
  195. this.page = 5;
  196. this.h = 100.23;
  197. this.v = 45.67;
  198. this.project_id = "mock-project-id";
  199. this.req.params =
  200. {project_id: this.project_id};
  201. this.req.query = {
  202. page: this.page.toString(),
  203. h: this.h.toString(),
  204. v: this.v.toString()
  205. };
  206. this.res.json = sinon.stub();
  207. this.CompileManager.syncFromPdf = sinon.stub().callsArgWith(5, null, (this.codePositions = ["mock-positions"]));
  208. return this.CompileController.syncFromPdf(this.req, this.res, this.next);
  209. });
  210. it("should find the corresponding location in the code", function() {
  211. return this.CompileManager.syncFromPdf
  212. .calledWith(this.project_id, undefined, this.page, this.h, this.v)
  213. .should.equal(true);
  214. });
  215. return it("should return the positions", function() {
  216. return this.res.json
  217. .calledWith({
  218. code: this.codePositions
  219. })
  220. .should.equal(true);
  221. });
  222. });
  223. return describe("wordcount", function() {
  224. beforeEach(function() {
  225. this.file = "main.tex";
  226. this.project_id = "mock-project-id";
  227. this.req.params =
  228. {project_id: this.project_id};
  229. this.req.query = {
  230. file: this.file,
  231. image: (this.image = "example.com/image")
  232. };
  233. this.res.json = sinon.stub();
  234. this.CompileManager.wordcount = sinon.stub().callsArgWith(4, null, (this.texcount = ["mock-texcount"]));
  235. return this.CompileController.wordcount(this.req, this.res, this.next);
  236. });
  237. it("should return the word count of a file", function() {
  238. return this.CompileManager.wordcount
  239. .calledWith(this.project_id, undefined, this.file, this.image)
  240. .should.equal(true);
  241. });
  242. return it("should return the texcount info", function() {
  243. return this.res.json
  244. .calledWith({
  245. texcount: this.texcount
  246. })
  247. .should.equal(true);
  248. });
  249. });
  250. });