preview-download-button.test.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import React from 'react'
  2. import { expect } from 'chai'
  3. import { screen, render } from '@testing-library/react'
  4. import PreviewDownloadButton, {
  5. topFileTypes
  6. } from '../../../../../frontend/js/features/preview/components/preview-download-button'
  7. describe('<PreviewDownloadButton />', function() {
  8. const projectId = 'projectId123'
  9. const pdfDownloadUrl = `/download/project/${projectId}/build/17523aaafdf-1ad9063af140f004/output/output.pdf?compileGroup=priority&popupDownload=true`
  10. function makeFile(fileName, main) {
  11. return {
  12. fileName,
  13. url: `/project/${projectId}/output/${fileName}`,
  14. type: fileName.split('.').pop(),
  15. main: main || false
  16. }
  17. }
  18. it('should disable the button and dropdown toggle when compiling', function() {
  19. const isCompiling = true
  20. const outputFiles = undefined
  21. render(
  22. <PreviewDownloadButton
  23. isCompiling={isCompiling}
  24. outputFiles={outputFiles}
  25. pdfDownloadUrl={undefined}
  26. />
  27. )
  28. expect(screen.getByText('Download PDF').getAttribute('disabled')).to.exist
  29. const buttons = screen.getAllByRole('button')
  30. expect(buttons.length).to.equal(1) // the dropdown toggle
  31. expect(buttons[0].getAttribute('disabled')).to.exist
  32. expect(buttons[0].getAttribute('aria-label')).to.equal(
  33. 'Toggle output files list'
  34. )
  35. })
  36. it('should disable the PDF button when there is no PDF', function() {
  37. const isCompiling = false
  38. const outputFiles = []
  39. render(
  40. <PreviewDownloadButton
  41. isCompiling={isCompiling}
  42. outputFiles={outputFiles}
  43. pdfDownloadUrl={undefined}
  44. />
  45. )
  46. expect(screen.getByText('Download PDF').getAttribute('disabled')).to.exist
  47. })
  48. it('should enable the PDF button when there is a main PDF', function() {
  49. const isCompiling = false
  50. const outputFiles = []
  51. render(
  52. <PreviewDownloadButton
  53. isCompiling={isCompiling}
  54. outputFiles={outputFiles}
  55. pdfDownloadUrl={pdfDownloadUrl}
  56. />
  57. )
  58. expect(screen.getByText('Download PDF').getAttribute('href')).to.equal(
  59. pdfDownloadUrl
  60. )
  61. expect(screen.getByText('Download PDF').getAttribute('disabled')).to.not
  62. .exist
  63. })
  64. it('should enable the dropdown when not compiling', function() {
  65. const isCompiling = false
  66. const outputFiles = []
  67. render(
  68. <PreviewDownloadButton
  69. isCompiling={isCompiling}
  70. outputFiles={outputFiles}
  71. pdfDownloadUrl={pdfDownloadUrl}
  72. />
  73. )
  74. const buttons = screen.getAllByRole('button')
  75. expect(buttons[0]).to.exist
  76. expect(buttons[0].getAttribute('disabled')).to.not.exist
  77. })
  78. it('should list all output files and group them', function() {
  79. const isCompiling = false
  80. const outputFiles = [
  81. makeFile('output.ind'),
  82. makeFile('output.log'),
  83. makeFile('output.pdf', true),
  84. makeFile('alt.pdf'),
  85. makeFile('output.stderr'),
  86. makeFile('output.stdout'),
  87. makeFile('output.aux'),
  88. makeFile('output.bbl'),
  89. makeFile('output.blg')
  90. ]
  91. render(
  92. <PreviewDownloadButton
  93. isCompiling={isCompiling}
  94. outputFiles={outputFiles}
  95. pdfDownloadUrl={pdfDownloadUrl}
  96. />
  97. )
  98. const menuItems = screen.getAllByRole('menuitem')
  99. expect(menuItems.length).to.equal(outputFiles.length - 1) // main PDF is listed separately
  100. const fileTypes = outputFiles.map(file => {
  101. return file.type
  102. })
  103. menuItems.forEach((item, index) => {
  104. // check displayed text
  105. const itemTextParts = item.textContent.split(' ')
  106. expect(itemTextParts[0]).to.equal('Download')
  107. const fileType = itemTextParts[1].split('.').pop()
  108. expect(fileTypes).to.include(fileType)
  109. expect(itemTextParts[2]).to.equal('file')
  110. })
  111. // check grouped correctly
  112. expect(topFileTypes).to.exist
  113. expect(topFileTypes.length).to.be.above(0)
  114. const outputTopFileTypes = outputFiles
  115. .filter(file => {
  116. if (topFileTypes.includes(file.type)) return file.type
  117. })
  118. .map(file => file.type)
  119. const topMenuItems = menuItems.slice(0, outputTopFileTypes.length)
  120. topMenuItems.forEach(item => {
  121. const fileType = item.textContent
  122. .split('.')
  123. .pop()
  124. .replace(' file', '')
  125. expect(topFileTypes.includes(fileType)).to.be.true
  126. })
  127. })
  128. it('should list all files when there are duplicate types', function() {
  129. const isCompiling = false
  130. const pdfFile = makeFile('output.pdf', true)
  131. const bblFile = makeFile('output.bbl')
  132. const outputFiles = [Object.assign({}, { ...bblFile }), bblFile, pdfFile]
  133. render(
  134. <PreviewDownloadButton
  135. isCompiling={isCompiling}
  136. outputFiles={outputFiles}
  137. pdfDownloadUrl={pdfDownloadUrl}
  138. />
  139. )
  140. const bblMenuItems = screen.getAllByText((content, element) => {
  141. return (
  142. content !== '' && element.textContent === 'Download output.bbl file'
  143. )
  144. })
  145. expect(bblMenuItems.length).to.equal(2)
  146. })
  147. it('should list the non-main PDF in the dropdown', function() {
  148. const isCompiling = false
  149. const pdfFile = makeFile('output.pdf', true)
  150. const pdfAltFile = makeFile('alt.pdf')
  151. const outputFiles = [pdfFile, pdfAltFile]
  152. render(
  153. <PreviewDownloadButton
  154. isCompiling={isCompiling}
  155. outputFiles={outputFiles}
  156. pdfDownloadUrl={pdfDownloadUrl}
  157. />
  158. )
  159. screen.getAllByRole('menuitem', { name: 'Download alt.pdf file' })
  160. })
  161. })