CollapseButton.spec.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { renderComponent } from '#tests/support/components/index.ts'
  3. import { EnumTextDirection } from '#shared/graphql/types.ts'
  4. import { useLocaleStore } from '#shared/stores/locale.ts'
  5. import CollapseButton from '#desktop/components/CollapseButton/CollapseButton.vue'
  6. describe('CollapseButton', () => {
  7. it.each([
  8. {
  9. isCollapsed: true,
  10. orientation: 'horizontal',
  11. icon: 'arrow-bar-right',
  12. },
  13. {
  14. isCollapsed: false,
  15. orientation: 'horizontal',
  16. icon: 'arrow-bar-left',
  17. },
  18. {
  19. isCollapsed: true,
  20. orientation: 'vertical',
  21. icon: 'arrows-expand',
  22. },
  23. {
  24. isCollapsed: false,
  25. orientation: 'vertical',
  26. icon: 'arrows-collapse',
  27. },
  28. ])(
  29. 'displays correct LTR icon (isCollapsed: $isCollapsed, orientation: $orientation)',
  30. async ({ isCollapsed, orientation, icon }) => {
  31. const wrapper = renderComponent(CollapseButton, {
  32. props: {
  33. ownerId: 'test',
  34. isCollapsed,
  35. orientation,
  36. },
  37. })
  38. expect(wrapper.getByIconName(icon)).toBeInTheDocument()
  39. },
  40. )
  41. it.each([
  42. {
  43. isCollapsed: true,
  44. orientation: 'horizontal',
  45. icon: 'arrow-bar-left',
  46. },
  47. {
  48. isCollapsed: false,
  49. orientation: 'horizontal',
  50. icon: 'arrow-bar-right',
  51. },
  52. {
  53. isCollapsed: true,
  54. orientation: 'vertical',
  55. icon: 'arrows-expand',
  56. },
  57. {
  58. isCollapsed: false,
  59. orientation: 'vertical',
  60. icon: 'arrows-collapse',
  61. },
  62. ])(
  63. 'displays correct RTL icon (isCollapsed: $isCollapsed, orientation: $orientation)',
  64. async ({ isCollapsed, orientation, icon }) => {
  65. const locale = useLocaleStore()
  66. locale.localeData = {
  67. dir: EnumTextDirection.Rtl,
  68. } as any
  69. const wrapper = renderComponent(CollapseButton, {
  70. props: {
  71. ownerId: 'test',
  72. isCollapsed,
  73. orientation,
  74. },
  75. })
  76. expect(wrapper.getByIconName(icon)).toBeInTheDocument()
  77. },
  78. )
  79. it('emits toggle-collapse event on click', async () => {
  80. const wrapper = renderComponent(CollapseButton, {
  81. props: {
  82. ownerId: 'test',
  83. isCollapsed: true,
  84. },
  85. })
  86. await wrapper.events.click(wrapper.getByRole('button'))
  87. expect(wrapper.emitted('toggle-collapse')).toBeTruthy()
  88. })
  89. it('renders the button by default', () => {
  90. const wrapper = renderComponent(CollapseButton, {
  91. props: {
  92. ownerId: 'test',
  93. },
  94. })
  95. expect(wrapper.getByRole('button')).toBeInTheDocument()
  96. })
  97. it('shows only on hover for non-touch devices', () => {
  98. const wrapper = renderComponent(CollapseButton, {
  99. props: {
  100. ownerId: 'test',
  101. group: 'sidebar',
  102. },
  103. })
  104. expect(wrapper.getByRole('button')).toHaveClasses([
  105. 'transition-opacity',
  106. 'opacity-0',
  107. ])
  108. })
  109. it('shows always for touch devices', () => {
  110. // Impersonate a touch device by mocking the corresponding media query.
  111. Object.defineProperty(window, 'matchMedia', {
  112. value: vi.fn().mockImplementation(() => ({
  113. matches: true,
  114. addEventListener: vi.fn(),
  115. removeEventListener: vi.fn(),
  116. })),
  117. })
  118. const wrapper = renderComponent(CollapseButton, {
  119. props: {
  120. ownerId: 'test',
  121. group: 'test',
  122. },
  123. })
  124. expect(wrapper.getByRole('button')).not.toHaveClasses([
  125. 'transition-opacity',
  126. 'opacity-0',
  127. 'group-hover/test:opacity-100',
  128. ])
  129. })
  130. })