OutputControllerTests.js 2.8 KB

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