123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- import { fireEvent } from '@testing-library/vue'
- import { beforeEach, describe, expect } from 'vitest'
- import renderComponent, {
- type ExtendedRenderResult,
- } from '#tests/support/components/renderComponent.ts'
- import LayoutSidebar from '#desktop/components/layout/LayoutSidebar.vue'
- import { SidebarPosition } from '../types.ts'
- describe('LayoutSidebar', () => {
- describe('Feature: Collapsible', () => {
- let view: ExtendedRenderResult
- beforeEach(() => {
- view = renderComponent(LayoutSidebar, {
- props: {
- name: 'testBar-collapsible',
- id: 'sidebar-test',
- collapsible: true,
- resizable: false,
- },
- })
- })
- it('shows CollapseButton in expanded state when collapsible is true', async () => {
- expect(view.queryByLabelText('Expand sidebar')).not.toBeInTheDocument()
- // By default, is expanded and aria label shows collapse action
- expect(view.queryByLabelText('Collapse sidebar')).toBeInTheDocument()
- })
- it('does not show CollapseButton when collapsible is false', async () => {
- await view.rerender({ collapsible: false })
- expect(
- view.queryByLabelText('collapse this item'),
- ).not.toBeInTheDocument()
- expect(view.queryByLabelText('expand this item')).not.toBeInTheDocument()
- })
- it('hides action Button when no iconCollapsed is provided', async () => {
- expect(view.queryByTestId('action-button')).not.toBeInTheDocument()
- })
- it('shows an action Button when iconCollapsed is provided and sidebar is collapsed', async () => {
- await view.rerender({ iconCollapsed: 'person-gear' })
- const collapseButton = await view.findByLabelText('Collapse sidebar')
- await view.events.click(collapseButton)
- expect(view.queryByTestId('action-button')).toBeInTheDocument()
- })
- })
- describe('Feature: Resizable', () => {
- let view: ExtendedRenderResult
- beforeEach(() => {
- view = renderComponent(LayoutSidebar, {
- props: {
- name: 'testBar-resize',
- id: 'sidebar-test',
- collapsible: false,
- resizable: true,
- },
- })
- })
- it('shows ResizeLine when resizable is true', async () => {
- expect(view.queryByLabelText('Resize sidebar')).toBeInTheDocument()
- })
- it('does not show ResizeLine when resizable is false', async () => {
- await view.rerender({ resizable: false })
- expect(view.queryByLabelText('Resize sidebar')).not.toBeInTheDocument()
- })
- it('resizes sidebar when ResizeLine is clicked and dragged', async () => {
- const resizeLine = await view.findByLabelText('Resize sidebar')
- await view.events.click(resizeLine)
- // Emulate mouse down on resize handle and mouse move on document
- await fireEvent.mouseDown(resizeLine, { clientX: 0 })
- await fireEvent.mouseMove(document, { clientX: 100 })
- await fireEvent.mouseUp(document, { clientX: 100 })
- expect(view.emitted('resize-horizontal')).toEqual([[100]])
- })
- it('resizes sidebar when ResizeLine is touched and dragged', async () => {
- const resizeLine = await view.findByLabelText('Resize sidebar')
- await view.events.click(resizeLine)
- // Touch device
- await fireEvent.touchStart(resizeLine, { pageX: 0 })
- await fireEvent.touchMove(document, { pageX: 100 })
- await fireEvent.touchEnd(document, { pageX: 100 })
- // :TODO check why we can not use toEqual([[100]])
- expect(view.emitted('resize-horizontal')).toBeTruthy()
- })
- it('resets width when ResizeLine is double clicked', async () => {
- const resizeLine = await view.findByLabelText('Resize sidebar')
- await fireEvent.dblClick(resizeLine)
- expect(view.emitted('reset-width')).toBeTruthy()
- })
- })
- describe('Feature: Position', () => {
- let view: ExtendedRenderResult
- beforeEach(() => {
- view = renderComponent(LayoutSidebar, {
- props: {
- name: 'testBar-position',
- id: 'sidebar-test',
- collapsible: true,
- resizable: true,
- },
- })
- })
- it('defaults to start position (left)', async () => {
- const aside = view.getByRole('complementary')
- expect(aside).not.toHaveClass('border-e')
- const collapseButton = view.getByLabelText('Collapse sidebar')
- expect(collapseButton.parentElement).toHaveClasses([
- 'focus-within:opacity-100',
- 'hover:opacity-100',
- ])
- const resizeLine = view.getByLabelText('Resize sidebar')
- expect(resizeLine.parentElement).toHaveClasses([
- 'ltr:right-0',
- 'ltr:translate-x-1/2',
- 'rtl:left-0',
- 'rtl:-translate-x-1/2',
- ])
- })
- it('supports end position (right)', async () => {
- await view.rerender({ position: SidebarPosition.End })
- const aside = view.getByRole('complementary')
- expect(aside).toHaveClass('border-s')
- const resizeLine = view.getByLabelText('Resize sidebar')
- expect(resizeLine.parentElement).toHaveClasses([
- 'ltr:left-0',
- 'rtl:right-0',
- 'ltr:-translate-x-1/2',
- 'rtl:right-0',
- 'rtl:translate-x-1/2',
- ])
- })
- })
- })
|