CommonFilePreview.spec.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { getByIconName } from '#tests/support/components/iconQueries.ts'
  3. import { renderComponent } from '#tests/support/components/index.ts'
  4. import { mockApplicationConfig } from '#tests/support/mock-applicationConfig.ts'
  5. import CommonFilePreview, { type Props } from '../CommonFilePreview.vue'
  6. const renderFilePreview = (
  7. props: Props & { onPreview?(event: Event): void },
  8. ) => {
  9. return renderComponent(CommonFilePreview, {
  10. props,
  11. router: true,
  12. store: true,
  13. })
  14. }
  15. describe('preview file component', () => {
  16. beforeEach(() => {
  17. mockApplicationConfig({
  18. ui_ticket_zoom_attachments_preview: true,
  19. api_path: '/api',
  20. 'active_storage.web_image_content_types': [
  21. 'image/png',
  22. 'image/jpeg',
  23. 'image/jpg',
  24. 'image/gif',
  25. ],
  26. })
  27. })
  28. it('renders previewable image', async () => {
  29. const previewMock = vi.fn((event: Event) => event.preventDefault())
  30. const view = renderFilePreview({
  31. file: {
  32. name: 'name.png',
  33. type: 'image/png',
  34. size: 1025,
  35. },
  36. downloadUrl: '/api/url',
  37. previewUrl: '/api/url?preview',
  38. onPreview: previewMock,
  39. })
  40. const button = view.getByRole('button', { name: 'Preview name.png' })
  41. const thumbnail = view.getByAltText('Image of name.png')
  42. expect(thumbnail).toHaveAttribute('src', '/api/url?preview')
  43. await view.events.click(button)
  44. expect(view.emitted().preview).toBeTruthy()
  45. expect(previewMock).toHaveBeenCalled()
  46. })
  47. it('renders downloadable file', async () => {
  48. const view = renderFilePreview({
  49. file: {
  50. name: 'name.word',
  51. type: 'application/msword',
  52. size: 1025,
  53. },
  54. downloadUrl: '#/api/url',
  55. previewUrl: '#/api/url?preview',
  56. onPreview: vi.fn(),
  57. })
  58. const link = view.getByRole('link')
  59. expect(link).toHaveAttribute('aria-label', 'Download name.word')
  60. expect(link).toHaveAttribute('download')
  61. expect(link).toHaveAttribute('href', '#/api/url')
  62. expect(view.getByIconName('template')).toBeInTheDocument()
  63. await view.events.click(link)
  64. expect(view.emitted().preview).toBeFalsy()
  65. })
  66. it('renders pdf/html', async () => {
  67. const view = renderFilePreview({
  68. file: {
  69. name: 'name.pdf',
  70. type: 'text/html',
  71. size: 1025,
  72. },
  73. downloadUrl: '#/api/url',
  74. previewUrl: '#/api/url?preview',
  75. onPreview: vi.fn(),
  76. })
  77. const link = view.getByRole('link')
  78. expect(link).toHaveAttribute('aria-label', 'Open name.pdf')
  79. expect(link).not.toHaveAttribute('download')
  80. expect(link).toHaveAttribute('href', '#/api/url')
  81. expect(link).toHaveAttribute('target', '_blank')
  82. })
  83. it('renders uploaded image', async () => {
  84. const view = renderFilePreview({
  85. file: {
  86. name: 'name.png',
  87. type: 'image/png',
  88. size: 1025,
  89. },
  90. previewUrl: 'data:image/png;base64,',
  91. onPreview: vi.fn(),
  92. })
  93. const button = view.getByRole('button', { name: 'Preview name.png' })
  94. const thumbnail = view.getByAltText('Image of name.png')
  95. expect(thumbnail).toHaveAttribute('src', 'data:image/png;base64,')
  96. await view.events.click(button)
  97. expect(view.emitted().preview).toBeTruthy()
  98. })
  99. it('renders uploaded non-image', async () => {
  100. const view = renderFilePreview({
  101. file: {
  102. name: 'name.word',
  103. type: 'application/msword',
  104. size: 1025,
  105. },
  106. previewUrl: 'data:application/msword;base64,',
  107. onPreview: vi.fn(),
  108. })
  109. const div = view.getByLabelText('name.word')
  110. expect(div.tagName, 'not interactable link').not.toBe('A')
  111. expect(div.tagName, 'not interactable button').not.toBe('BUTTON')
  112. expect(view.getByIconName('template')).toBeInTheDocument()
  113. await view.events.click(div)
  114. expect(view.emitted().preview).toBeFalsy()
  115. })
  116. it('can remove file', async () => {
  117. const view = renderFilePreview({
  118. file: {
  119. name: 'name.word',
  120. type: 'application/msword',
  121. size: 1025,
  122. },
  123. })
  124. const button = view.getByRole('button', { name: 'Remove name.word' })
  125. expect(button).toBeInTheDocument()
  126. expect(getByIconName(button, 'close-small')).toBeInTheDocument()
  127. await view.events.click(button)
  128. expect(view.emitted().remove).toBeTruthy()
  129. await view.rerender({ noRemove: true })
  130. expect(
  131. view.queryByRole('button', { name: 'Remove name.word' }),
  132. ).not.toBeInTheDocument()
  133. })
  134. })