preview-download-button.test.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. function renderPreviewDownloadButton(
  19. isCompiling,
  20. outputFiles,
  21. pdfDownloadUrl,
  22. showText
  23. ) {
  24. if (isCompiling === undefined) isCompiling = false
  25. if (showText === undefined) showText = true
  26. render(
  27. <PreviewDownloadButton
  28. isCompiling={isCompiling}
  29. outputFiles={outputFiles || []}
  30. pdfDownloadUrl={pdfDownloadUrl}
  31. showText={showText}
  32. />
  33. )
  34. }
  35. it('should disable the button and dropdown toggle when compiling', function() {
  36. const isCompiling = true
  37. const outputFiles = undefined
  38. renderPreviewDownloadButton(isCompiling, outputFiles)
  39. expect(
  40. screen
  41. .getByText('Download PDF')
  42. .closest('a')
  43. .getAttribute('disabled')
  44. ).to.exist
  45. const buttons = screen.getAllByRole('button')
  46. expect(buttons.length).to.equal(1) // the dropdown toggle
  47. expect(buttons[0].getAttribute('disabled')).to.exist
  48. expect(buttons[0].getAttribute('aria-label')).to.equal(
  49. 'Toggle output files list'
  50. )
  51. })
  52. it('should disable the PDF button when there is no PDF', function() {
  53. const isCompiling = false
  54. const outputFiles = []
  55. renderPreviewDownloadButton(isCompiling, outputFiles)
  56. expect(
  57. screen
  58. .getByText('Download PDF')
  59. .closest('a')
  60. .getAttribute('disabled')
  61. ).to.exist
  62. })
  63. it('should enable the PDF button when there is a main PDF', function() {
  64. const isCompiling = false
  65. const outputFiles = []
  66. renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
  67. expect(
  68. screen
  69. .getByText('Download PDF')
  70. .closest('a')
  71. .getAttribute('href')
  72. ).to.equal(pdfDownloadUrl)
  73. expect(
  74. screen
  75. .getByText('Download PDF')
  76. .closest('a')
  77. .getAttribute('disabled')
  78. ).to.not.exist
  79. })
  80. it('should enable the dropdown when not compiling', function() {
  81. const isCompiling = false
  82. const outputFiles = []
  83. renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
  84. const buttons = screen.getAllByRole('button')
  85. expect(buttons[0]).to.exist
  86. expect(buttons[0].getAttribute('disabled')).to.not.exist
  87. })
  88. it('should list all output files and group them', function() {
  89. const isCompiling = false
  90. const outputFiles = [
  91. makeFile('output.ind'),
  92. makeFile('output.log'),
  93. makeFile('output.pdf', true),
  94. makeFile('alt.pdf'),
  95. makeFile('output.stderr'),
  96. makeFile('output.stdout'),
  97. makeFile('output.aux'),
  98. makeFile('output.bbl'),
  99. makeFile('output.blg')
  100. ]
  101. renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
  102. const menuItems = screen.getAllByRole('menuitem')
  103. expect(menuItems.length).to.equal(outputFiles.length - 1) // main PDF is listed separately
  104. const fileTypes = outputFiles.map(file => {
  105. return file.type
  106. })
  107. menuItems.forEach((item, index) => {
  108. // check displayed text
  109. const itemTextParts = item.textContent.split(' ')
  110. expect(itemTextParts[0]).to.equal('Download')
  111. const fileType = itemTextParts[1].split('.').pop()
  112. expect(fileTypes).to.include(fileType)
  113. expect(itemTextParts[2]).to.equal('file')
  114. })
  115. // check grouped correctly
  116. expect(topFileTypes).to.exist
  117. expect(topFileTypes.length).to.be.above(0)
  118. const outputTopFileTypes = outputFiles
  119. .filter(file => {
  120. if (topFileTypes.includes(file.type)) return file.type
  121. })
  122. .map(file => file.type)
  123. const topMenuItems = menuItems.slice(0, outputTopFileTypes.length)
  124. topMenuItems.forEach(item => {
  125. const fileType = item.textContent
  126. .split('.')
  127. .pop()
  128. .replace(' file', '')
  129. expect(topFileTypes.includes(fileType)).to.be.true
  130. })
  131. })
  132. it('should list all files when there are duplicate types', function() {
  133. const isCompiling = false
  134. const pdfFile = makeFile('output.pdf', true)
  135. const bblFile = makeFile('output.bbl')
  136. const outputFiles = [Object.assign({}, { ...bblFile }), bblFile, pdfFile]
  137. renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
  138. const bblMenuItems = screen.getAllByText((content, element) => {
  139. return (
  140. content !== '' && element.textContent === 'Download output.bbl file'
  141. )
  142. })
  143. expect(bblMenuItems.length).to.equal(2)
  144. })
  145. it('should list the non-main PDF in the dropdown', function() {
  146. const isCompiling = false
  147. const pdfFile = makeFile('output.pdf', true)
  148. const pdfAltFile = makeFile('alt.pdf')
  149. const outputFiles = [pdfFile, pdfAltFile]
  150. renderPreviewDownloadButton(isCompiling, outputFiles, pdfDownloadUrl)
  151. screen.getAllByRole('menuitem', { name: 'Download alt.pdf file' })
  152. })
  153. it('should show the button text when prop showText=true', function() {
  154. const isCompiling = false
  155. const showText = true
  156. renderPreviewDownloadButton(isCompiling, [], pdfDownloadUrl, showText)
  157. expect(screen.getByText('Download PDF').getAttribute('style')).to.be.null
  158. })
  159. it('should not show the button text when prop showText=false', function() {
  160. const isCompiling = false
  161. const showText = false
  162. renderPreviewDownloadButton(isCompiling, [], pdfDownloadUrl, showText)
  163. expect(screen.getByText('Download PDF').getAttribute('style')).to.equal(
  164. 'position: absolute; right: -100vw;'
  165. )
  166. })
  167. describe('list divider and header', function() {
  168. it('should display when there are top files and other files', function() {
  169. const outputFiles = [
  170. makeFile('output.bbl'),
  171. makeFile('output.ind'),
  172. makeFile('output.gls'),
  173. makeFile('output.log')
  174. ]
  175. renderPreviewDownloadButton(false, outputFiles, pdfDownloadUrl, true)
  176. screen.getByText('Other output files')
  177. screen.getByRole('separator')
  178. })
  179. it('should not display when there are top files and no other files', function() {
  180. const outputFiles = [
  181. makeFile('output.bbl'),
  182. makeFile('output.ind'),
  183. makeFile('output.gls')
  184. ]
  185. renderPreviewDownloadButton(false, outputFiles, pdfDownloadUrl, true)
  186. expect(screen.queryByText('Other output files')).to.not.exist
  187. expect(screen.queryByRole('separator')).to.not.exist
  188. })
  189. it('should not display when there are other files and no top files', function() {
  190. const outputFiles = [makeFile('output.log')]
  191. renderPreviewDownloadButton(false, outputFiles, pdfDownloadUrl, true)
  192. expect(screen.queryByText('Other output files')).to.not.exist
  193. expect(screen.queryByRole('separator')).to.not.exist
  194. })
  195. })
  196. })