dify/web/app/components/base/param-item/__tests__/top-k-item.spec.tsx
yyh a8e1ff85db
feat(web): base-ui slider (#34064)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-03-25 16:03:49 +08:00

130 lines
3.9 KiB
TypeScript

import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import TopKItem from '../top-k-item'
vi.mock('@/env', () => ({
env: {
NEXT_PUBLIC_TOP_K_MAX_VALUE: 10,
},
}))
describe('TopKItem', () => {
const defaultProps = {
value: 2,
enable: true,
onChange: vi.fn(),
}
beforeEach(() => {
vi.clearAllMocks()
})
const getSlider = () => screen.getByLabelText('appDebug.datasetConfig.top_k')
describe('Rendering', () => {
it('should render the translated parameter name', () => {
render(<TopKItem {...defaultProps} />)
expect(screen.getByText('appDebug.datasetConfig.top_k')).toBeInTheDocument()
})
it('should render tooltip trigger', () => {
const { container } = render(<TopKItem {...defaultProps} />)
// Tooltip trigger icon should be rendered
expect(container.querySelector('[data-state]')).toBeInTheDocument()
})
it('should render InputNumber and Slider', () => {
render(<TopKItem {...defaultProps} />)
expect(screen.getByRole('textbox')).toBeInTheDocument()
expect(getSlider()).toBeInTheDocument()
})
})
describe('Props', () => {
it('should apply custom className', () => {
const { container } = render(<TopKItem {...defaultProps} className="custom-cls" />)
expect(container.firstChild).toHaveClass('custom-cls')
})
it('should disable controls when enable is false', () => {
render(<TopKItem {...defaultProps} enable={false} />)
expect(screen.getByRole('textbox')).toBeDisabled()
expect(getSlider()).toBeDisabled()
})
})
describe('Value Limits', () => {
it('should use step of 1', () => {
render(<TopKItem {...defaultProps} />)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('2')
})
it('should use minimum of 1', () => {
render(<TopKItem {...defaultProps} />)
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should use maximum from env (10)', () => {
render(<TopKItem {...defaultProps} />)
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should render slider with max >= 5 so no scaling is applied', () => {
render(<TopKItem {...defaultProps} />)
const slider = getSlider()
// max=10 >= 5 so slider shows raw values
expect(slider).toHaveAttribute('max', '10')
})
it('should not render a switch (no hasSwitch prop)', () => {
render(<TopKItem {...defaultProps} />)
expect(screen.queryByRole('switch')).not.toBeInTheDocument()
})
})
describe('User Interactions', () => {
it('should call onChange with clamped integer value via increment button', async () => {
const user = userEvent.setup()
render(<TopKItem {...defaultProps} value={5} />)
const incrementBtn = screen.getByRole('button', { name: /increment/i })
await user.click(incrementBtn)
// step=1, so 5 + 1 = 6, clamped to [1,10] → 6
expect(defaultProps.onChange).toHaveBeenCalledWith('top_k', 6)
})
it('should call onChange with clamped integer value via decrement button', async () => {
const user = userEvent.setup()
render(<TopKItem {...defaultProps} value={5} />)
const decrementBtn = screen.getByRole('button', { name: /decrement/i })
await user.click(decrementBtn)
// step=1, so 5 - 1 = 4, clamped to [1,10] → 4
expect(defaultProps.onChange).toHaveBeenCalledWith('top_k', 4)
})
it('should call onChange with integer value when slider changes', async () => {
const user = userEvent.setup()
render(<TopKItem {...defaultProps} value={2} />)
const slider = getSlider()
slider.focus()
await user.keyboard('{ArrowRight}')
expect(defaultProps.onChange).toHaveBeenLastCalledWith('top_k', 3)
})
})
})