dify/web/app/components/base/tab-slider-plain/__tests__/index.spec.tsx
Coding On Star 335b500aea
test: add unit tests for base components (#32818)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-03-02 11:40:43 +08:00

101 lines
3.7 KiB
TypeScript

import { render, screen, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { describe, expect, it, vi } from 'vitest'
import TabSlider from '../index'
describe('TabSlider Component', () => {
const mockOptions = [
{ value: 'tab1', text: 'Overview' },
{ value: 'tab2', text: 'Settings' },
{ value: 'tab3', text: <span data-testid="custom-jsx">Advanced</span> },
]
it('should render all options correctly', () => {
render(<TabSlider value="tab1" options={mockOptions} onChange={() => { }} />)
expect(screen.getByText('Overview')).toBeInTheDocument()
expect(screen.getByText('Settings')).toBeInTheDocument()
expect(screen.getByTestId('custom-jsx')).toBeInTheDocument()
})
it('should call onChange when an inactive tab is clicked', async () => {
const user = userEvent.setup()
const handleChange = vi.fn()
render(<TabSlider value="tab1" options={mockOptions} onChange={handleChange} />)
const settingsTab = screen.getByTestId('tab-slider-item-tab2')
await user.click(settingsTab)
expect(handleChange).toHaveBeenCalledWith('tab2')
})
it('should not call onChange when the active tab is clicked', async () => {
const user = userEvent.setup()
const handleChange = vi.fn()
render(<TabSlider value="tab1" options={mockOptions} onChange={handleChange} />)
const activeTab = screen.getByTestId('tab-slider-item-tab1')
await user.click(activeTab)
expect(handleChange).not.toHaveBeenCalled()
})
it('should apply active styles and render indicator for the active tab', () => {
render(<TabSlider value="tab2" options={mockOptions} onChange={() => { }} />)
const activeTab = screen.getByTestId('tab-slider-item-tab2')
const activeText = within(activeTab).getByTestId('tab-slider-item-text')
const indicator = within(activeTab).getByTestId('tab-active-indicator')
expect(activeText).toHaveClass('text-text-primary')
expect(indicator).toBeInTheDocument()
const inactiveTab = screen.getByTestId('tab-slider-item-tab1')
const inactiveText = within(inactiveTab).getByTestId('tab-slider-item-text')
expect(inactiveText).toHaveClass('text-text-tertiary')
expect(within(inactiveTab).queryByTestId('tab-active-indicator')).not.toBeInTheDocument()
})
it('should apply smallItem styles when smallItem prop is true', () => {
render(<TabSlider value="tab1" options={mockOptions} onChange={() => { }} smallItem />)
const item = screen.getByTestId('tab-slider-item-tab1')
expect(item).toHaveClass('system-sm-semibold-uppercase')
expect(item).not.toHaveClass('system-xl-semibold')
})
it('should apply standard sizing when smallItem prop is false', () => {
render(<TabSlider value="tab1" options={mockOptions} onChange={() => { }} />)
const item = screen.getByTestId('tab-slider-item-tab1')
expect(item).toHaveClass('system-xl-semibold')
})
it('should handle border styles based on noBorderBottom prop', () => {
const { rerender } = render(
<TabSlider value="tab1" options={mockOptions} onChange={() => { }} />,
)
expect(screen.getByTestId('tab-slider')).toHaveClass('border-b')
rerender(
<TabSlider value="tab1" options={mockOptions} onChange={() => { }} noBorderBottom />,
)
expect(screen.getByTestId('tab-slider')).not.toHaveClass('border-b')
})
it('should apply custom itemClassName to all items', () => {
const customClass = 'my-custom-item'
render(
<TabSlider
value="tab1"
options={mockOptions}
onChange={() => { }}
itemClassName={customClass}
/>,
)
expect(screen.getByTestId('tab-slider-item-tab1')).toHaveClass(customClass)
expect(screen.getByTestId('tab-slider-item-tab2')).toHaveClass(customClass)
})
})