CommonFilePreview.spec.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 link = view.getByRole('link')
  41. expect(link).toHaveAttribute('aria-label', 'Preview name.png')
  42. expect(link).toHaveAttribute('download')
  43. expect(link).toHaveAttribute('href', '/api/url')
  44. const thumbnail = view.getByAltText('Image of name.png')
  45. expect(thumbnail).toHaveAttribute('src', '/api/url?preview')
  46. await view.events.click(link)
  47. expect(view.emitted().preview).toBeTruthy()
  48. expect(previewMock).toHaveBeenCalled()
  49. })
  50. it('renders downloadble file', async () => {
  51. const view = renderFilePreview({
  52. file: {
  53. name: 'name.word',
  54. type: 'application/msword',
  55. size: 1025,
  56. },
  57. downloadUrl: '#/api/url',
  58. previewUrl: '#/api/url?preview',
  59. onPreview: vi.fn(),
  60. })
  61. const link = view.getByRole('link')
  62. expect(link).toHaveAttribute('aria-label', 'Download name.word')
  63. expect(link).toHaveAttribute('download')
  64. expect(link).toHaveAttribute('href', '#/api/url')
  65. expect(view.getByIconName('template')).toBeInTheDocument()
  66. await view.events.click(link)
  67. expect(view.emitted().preview).toBeFalsy()
  68. })
  69. it('renders pdf/html', async () => {
  70. const view = renderFilePreview({
  71. file: {
  72. name: 'name.pdf',
  73. type: 'text/html',
  74. size: 1025,
  75. },
  76. downloadUrl: '#/api/url',
  77. previewUrl: '#/api/url?preview',
  78. onPreview: vi.fn(),
  79. })
  80. const link = view.getByRole('link')
  81. expect(link).toHaveAttribute('aria-label', 'Open name.pdf')
  82. expect(link).not.toHaveAttribute('download')
  83. expect(link).toHaveAttribute('href', '#/api/url')
  84. expect(link).toHaveAttribute('target', '_blank')
  85. })
  86. it('renders uploaded image', async () => {
  87. const view = renderFilePreview({
  88. file: {
  89. name: 'name.png',
  90. type: 'image/png',
  91. size: 1025,
  92. },
  93. previewUrl: 'data:image/png;base64,',
  94. onPreview: vi.fn(),
  95. })
  96. const button = view.getByRole('button', { name: 'Preview name.png' })
  97. const thumbnail = view.getByAltText('Image of name.png')
  98. expect(thumbnail).toHaveAttribute('src', 'data:image/png;base64,')
  99. await view.events.click(button)
  100. expect(view.emitted().preview).toBeTruthy()
  101. })
  102. it('renders uploaded non-image', async () => {
  103. const view = renderFilePreview({
  104. file: {
  105. name: 'name.word',
  106. type: 'application/msword',
  107. size: 1025,
  108. },
  109. previewUrl: 'data:application/msword;base64,',
  110. onPreview: vi.fn(),
  111. })
  112. const div = view.getByLabelText('name.word')
  113. expect(div.tagName, 'not interactable link').not.toBe('A')
  114. expect(div.tagName, 'not interactable button').not.toBe('BUTTON')
  115. expect(view.getByIconName('template')).toBeInTheDocument()
  116. await view.events.click(div)
  117. expect(view.emitted().preview).toBeFalsy()
  118. })
  119. it('can remove file', async () => {
  120. const view = renderFilePreview({
  121. file: {
  122. name: 'name.word',
  123. type: 'application/msword',
  124. size: 1025,
  125. },
  126. })
  127. const button = view.getByRole('button', { name: 'Remove name.word' })
  128. expect(button).toBeInTheDocument()
  129. expect(getByIconName(button, 'close-small')).toBeInTheDocument()
  130. await view.events.click(button)
  131. expect(view.emitted().remove).toBeTruthy()
  132. await view.rerender({ noRemove: true })
  133. expect(
  134. view.queryByRole('button', { name: 'Remove name.word' }),
  135. ).not.toBeInTheDocument()
  136. })
  137. })