123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- import { renderComponent } from '#tests/support/components/index.ts'
- import { EnumTextDirection } from '#shared/graphql/types.ts'
- import { useLocaleStore } from '#shared/stores/locale.ts'
- import CollapseButton from '#desktop/components/CollapseButton/CollapseButton.vue'
- describe('CollapseButton', () => {
- it.each([
- {
- collapsed: true,
- orientation: 'horizontal',
- inverse: false,
- icon: 'arrow-bar-right',
- },
- {
- collapsed: false,
- orientation: 'horizontal',
- inverse: false,
- icon: 'arrow-bar-left',
- },
- {
- collapsed: true,
- orientation: 'vertical',
- inverse: false,
- icon: 'arrows-expand',
- },
- {
- collapsed: false,
- orientation: 'vertical',
- inverse: false,
- icon: 'arrows-collapse',
- },
- {
- collapsed: true,
- orientation: 'horizontal',
- inverse: true,
- icon: 'arrow-bar-left',
- },
- {
- collapsed: false,
- orientation: 'horizontal',
- inverse: true,
- icon: 'arrow-bar-right',
- },
- {
- collapsed: true,
- orientation: 'vertical',
- inverse: true,
- icon: 'arrows-expand',
- },
- {
- collapsed: false,
- orientation: 'vertical',
- inverse: true,
- icon: 'arrows-collapse',
- },
- ])(
- 'displays correct LTR icon (collapsed: $collapsed, orientation: $orientation, inverse: $inverse)',
- async ({ collapsed, orientation, inverse, icon }) => {
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- collapsed,
- inverse,
- orientation,
- },
- })
- expect(wrapper.getByIconName(icon)).toBeInTheDocument()
- },
- )
- it.each([
- {
- collapsed: true,
- orientation: 'horizontal',
- inverse: false,
- icon: 'arrow-bar-left',
- },
- {
- collapsed: false,
- orientation: 'horizontal',
- inverse: false,
- icon: 'arrow-bar-right',
- },
- {
- collapsed: true,
- orientation: 'vertical',
- inverse: false,
- icon: 'arrows-expand',
- },
- {
- collapsed: false,
- orientation: 'vertical',
- inverse: false,
- icon: 'arrows-collapse',
- },
- {
- collapsed: true,
- orientation: 'horizontal',
- inverse: true,
- icon: 'arrow-bar-right',
- },
- {
- collapsed: false,
- orientation: 'horizontal',
- inverse: true,
- icon: 'arrow-bar-left',
- },
- {
- collapsed: true,
- orientation: 'vertical',
- inverse: true,
- icon: 'arrows-expand',
- },
- {
- collapsed: false,
- orientation: 'vertical',
- inverse: true,
- icon: 'arrows-collapse',
- },
- ])(
- 'displays correct RTL icon (collapsed: $collapsed, orientation: $orientation, inverse: $inverse)',
- async ({ collapsed, orientation, inverse, icon }) => {
- const locale = useLocaleStore()
- locale.localeData = {
- dir: EnumTextDirection.Rtl,
- } as any
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- collapsed,
- inverse,
- orientation,
- },
- })
- expect(wrapper.getByIconName(icon)).toBeInTheDocument()
- },
- )
- it('emits toggle-collapse event on click', async () => {
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- collapsed: true,
- },
- })
- await wrapper.events.click(wrapper.getByRole('button'))
- expect(wrapper.emitted('toggle-collapse')).toBeTruthy()
- })
- it('renders the button by default', () => {
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- },
- })
- expect(wrapper.getByRole('button')).toBeInTheDocument()
- })
- it('shows only on hover for non-touch devices', () => {
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- },
- })
- expect(wrapper.getByRole('button').parentElement).toHaveClasses([
- 'opacity-0',
- ])
- })
- it.each(['tertiary-gray', 'none'])(
- 'renders variant %s correctly',
- (variant) => {
- const wrapper = renderComponent(CollapseButton, {
- props: {
- variant,
- ownerId: 'test',
- },
- })
- if (variant === 'tertiary-gray') {
- expect(wrapper.getByRole('button')).toHaveClasses([
- 'focus-visible:bg-blue-800',
- 'active:dark:bg-blue-800',
- 'focus:dark:bg-blue-800',
- 'active:bg-blue-800',
- 'focus:bg-blue-800',
- 'hover:bg-blue-600',
- 'hover:dark:bg-blue-900',
- 'text-black',
- 'dark:bg-gray-200',
- 'dark:text-white',
- ])
- }
- expect(wrapper.getByRole('button')).toHaveClasses([])
- },
- )
- it('shows always for touch devices', () => {
- // Impersonate a touch device by mocking the corresponding media query.
- Object.defineProperty(window, 'matchMedia', {
- value: vi.fn().mockImplementation(() => ({
- matches: true,
- addEventListener: vi.fn(),
- removeEventListener: vi.fn(),
- })),
- })
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- },
- })
- expect(wrapper.getByRole('button')).not.toHaveClasses([
- 'transition-opacity',
- 'opacity-0',
- 'group-hover/test:opacity-100',
- ])
- })
- it('supports custom labels for expand and collapse', async () => {
- const wrapper = renderComponent(CollapseButton, {
- props: {
- ownerId: 'test',
- collapsed: true,
- expandLabel: 'expand foo',
- collapseLabel: 'collapse foo',
- },
- })
- expect(wrapper.getByLabelText('expand foo')).toBeInTheDocument()
- await wrapper.rerender({
- collapsed: false,
- })
- expect(wrapper.getByLabelText('collapse foo')).toBeInTheDocument()
- })
- })
|