OutputControllerTests.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. const SandboxedModule = require('sandboxed-module')
  2. const sinon = require('sinon')
  3. const MODULE_PATH = require('path').join(
  4. __dirname,
  5. '../../../app/js/OutputController'
  6. )
  7. describe('OutputController', function () {
  8. describe('createOutputZip', function () {
  9. beforeEach(function () {
  10. this.archive = {
  11. on: sinon.stub(),
  12. pipe: sinon.stub(),
  13. }
  14. this.archiveFilesForBuild = sinon.stub().resolves(this.archive)
  15. this.OutputController = SandboxedModule.require(MODULE_PATH, {
  16. requires: {
  17. './OutputFileArchiveManager': {
  18. archiveFilesForBuild: this.archiveFilesForBuild,
  19. },
  20. },
  21. })
  22. })
  23. describe('when OutputFileArchiveManager creates an archive', function () {
  24. beforeEach(function (done) {
  25. this.res = {
  26. attachment: sinon.stub(),
  27. setHeader: sinon.stub(),
  28. }
  29. this.req = {
  30. params: {
  31. project_id: 'project-id-123',
  32. user_id: 'user-id-123',
  33. build_id: 'build-id-123',
  34. },
  35. query: {
  36. files: ['output.tex', 'not-output.tex'],
  37. },
  38. }
  39. this.archive.pipe.callsFake(() => done())
  40. this.OutputController.createOutputZip(this.req, this.res)
  41. })
  42. it('does not pass files that do not start with "output" to OutputFileArchiveManager', function () {
  43. sinon.assert.calledWith(
  44. this.archiveFilesForBuild,
  45. 'project-id-123',
  46. 'user-id-123',
  47. 'build-id-123',
  48. ['output.tex']
  49. )
  50. })
  51. it('pipes the archive to the response', function () {
  52. sinon.assert.calledWith(this.archive.pipe, this.res)
  53. })
  54. it('calls the express convenience method to set attachment headers', function () {
  55. sinon.assert.calledWith(this.res.attachment, 'output.zip')
  56. })
  57. it('sets the X-Content-Type-Options header to nosniff', function () {
  58. sinon.assert.calledWith(
  59. this.res.setHeader,
  60. 'X-Content-Type-Options',
  61. 'nosniff'
  62. )
  63. })
  64. })
  65. describe('when OutputFileArchiveManager throws an error', function () {
  66. let error
  67. beforeEach(function (done) {
  68. error = new Error('error message')
  69. this.archiveFilesForBuild.rejects(error)
  70. this.res = {
  71. status: sinon.stub().returnsThis(),
  72. send: sinon.stub(),
  73. }
  74. this.req = {
  75. params: {
  76. project_id: 'project-id-123',
  77. user_id: 'user-id-123',
  78. build_id: 'build-id-123',
  79. },
  80. query: {
  81. files: ['output.tex'],
  82. },
  83. }
  84. this.OutputController.createOutputZip(
  85. this.req,
  86. this.res,
  87. (this.next = sinon.stub().callsFake(() => {
  88. done()
  89. }))
  90. )
  91. })
  92. it('calls next with the error', function () {
  93. sinon.assert.calledWith(this.next, error)
  94. })
  95. })
  96. })
  97. })