test: add tests for some base components (#32265)

This commit is contained in:
Saumya Talwani
2026-02-13 11:59:04 +05:30
committed by GitHub
parent a4e03d6284
commit 98466e2d29
27 changed files with 1985 additions and 23 deletions

View File

@ -0,0 +1,195 @@
/* eslint-disable next/no-img-element */
import type { ImgHTMLAttributes } from 'react'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import CheckboxList from '.'
vi.mock('next/image', () => ({
default: (props: ImgHTMLAttributes<HTMLImageElement>) => <img {...props} />,
}))
describe('checkbox list component', () => {
const options = [
{ label: 'Option 1', value: 'option1' },
{ label: 'Option 2', value: 'option2' },
{ label: 'Option 3', value: 'option3' },
{ label: 'Apple', value: 'apple' },
]
it('renders with title, description and options', () => {
render(
<CheckboxList
title="Test Title"
description="Test Description"
options={options}
/>,
)
expect(screen.getByText('Test Title')).toBeInTheDocument()
expect(screen.getByText('Test Description')).toBeInTheDocument()
options.forEach((option) => {
expect(screen.getByText(option.label)).toBeInTheDocument()
})
})
it('filters options by label', async () => {
render(<CheckboxList options={options} />)
const input = screen.getByRole('textbox')
await userEvent.type(input, 'app')
expect(screen.getByText('Apple')).toBeInTheDocument()
expect(screen.queryByText('Option 2')).not.toBeInTheDocument()
expect(screen.queryByText('Option 3')).not.toBeInTheDocument()
})
it('renders select-all checkbox', () => {
render(<CheckboxList options={options} showSelectAll />)
const checkboxes = screen.getByTestId('checkbox-selectAll')
expect(checkboxes).toBeInTheDocument()
})
it('selects all options when select-all is clicked', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={[]}
onChange={onChange}
showSelectAll
/>,
)
const selectAll = screen.getByTestId('checkbox-selectAll')
await userEvent.click(selectAll)
expect(onChange).toHaveBeenCalledWith(['option1', 'option2', 'option3', 'apple'])
})
it('does not select all options when select-all is clicked when disabled', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={[]}
disabled
showSelectAll
onChange={onChange}
/>,
)
const selectAll = screen.getByTestId('checkbox-selectAll')
await userEvent.click(selectAll)
expect(onChange).not.toHaveBeenCalled()
})
it('deselects all options when select-all is clicked', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={['option1', 'option2', 'option3', 'apple']}
onChange={onChange}
showSelectAll
/>,
)
const selectAll = screen.getByTestId('checkbox-selectAll')
await userEvent.click(selectAll)
expect(onChange).toHaveBeenCalledWith([])
})
it('selects select-all when all options are clicked', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={['option1', 'option2', 'option3', 'apple']}
onChange={onChange}
showSelectAll
/>,
)
const selectAll = screen.getByTestId('checkbox-selectAll')
expect(selectAll.querySelector('[data-testid="check-icon-selectAll"]')).toBeInTheDocument()
})
it('hides select-all checkbox when searching', async () => {
render(<CheckboxList options={options} />)
await userEvent.type(screen.getByRole('textbox'), 'app')
expect(screen.queryByTestId('checkbox-selectAll')).not.toBeInTheDocument()
})
it('selects options when checkbox is clicked', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={[]}
onChange={onChange}
showSelectAll={false}
/>,
)
const selectOption = screen.getByTestId('checkbox-option1')
await userEvent.click(selectOption)
expect(onChange).toHaveBeenCalledWith(['option1'])
})
it('deselects options when checkbox is clicked when selected', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={['option1']}
onChange={onChange}
showSelectAll={false}
/>,
)
const selectOption = screen.getByTestId('checkbox-option1')
await userEvent.click(selectOption)
expect(onChange).toHaveBeenCalledWith([])
})
it('does not select options when checkbox is clicked', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={[]}
onChange={onChange}
disabled
/>,
)
const selectOption = screen.getByTestId('checkbox-option1')
await userEvent.click(selectOption)
expect(onChange).not.toHaveBeenCalled()
})
it('Reset button works', async () => {
const onChange = vi.fn()
render(
<CheckboxList
options={options}
value={[]}
onChange={onChange}
/>,
)
const input = screen.getByRole('textbox')
await userEvent.type(input, 'ban')
await userEvent.click(screen.getByText('common.operation.resetKeywords'))
expect(input).toHaveValue('')
})
})

View File

@ -101,12 +101,12 @@ const CheckboxList: FC<CheckboxListProps> = ({
return (
<div className={cn('flex w-full flex-col gap-1', containerClassName)}>
{label && (
<div className="system-sm-medium text-text-secondary">
<div className="text-text-secondary system-sm-medium">
{label}
</div>
)}
{description && (
<div className="body-xs-regular text-text-tertiary">
<div className="text-text-tertiary body-xs-regular">
{description}
</div>
)}
@ -120,13 +120,14 @@ const CheckboxList: FC<CheckboxListProps> = ({
indeterminate={isIndeterminate}
onCheck={handleSelectAll}
disabled={disabled}
id="selectAll"
/>
)}
{!searchQuery
? (
<div className="flex min-w-0 flex-1 items-center gap-1">
{title && (
<span className="system-xs-semibold-uppercase truncate leading-5 text-text-secondary">
<span className="truncate leading-5 text-text-secondary system-xs-semibold-uppercase">
{title}
</span>
)}
@ -138,7 +139,7 @@ const CheckboxList: FC<CheckboxListProps> = ({
</div>
)
: (
<div className="system-sm-medium-uppercase flex-1 leading-6 text-text-secondary">
<div className="flex-1 leading-6 text-text-secondary system-sm-medium-uppercase">
{
filteredOptions.length > 0
? t('operation.searchCount', { ns: 'common', count: filteredOptions.length, content: title })
@ -168,7 +169,7 @@ const CheckboxList: FC<CheckboxListProps> = ({
? (
<div className="flex flex-col items-center justify-center gap-2">
<Image alt="search menu" src={SearchMenu} width={32} />
<span className="system-sm-regular text-text-secondary">{t('operation.noSearchResults', { ns: 'common', content: title })}</span>
<span className="text-text-secondary system-sm-regular">{t('operation.noSearchResults', { ns: 'common', content: title })}</span>
<Button variant="secondary-accent" size="small" onClick={() => setSearchQuery('')}>{t('operation.resetKeywords', { ns: 'common' })}</Button>
</div>
)
@ -198,9 +199,10 @@ const CheckboxList: FC<CheckboxListProps> = ({
handleToggleOption(option.value)
}}
disabled={option.disabled || disabled}
id={option.value}
/>
<div
className="system-sm-medium flex-1 truncate text-text-secondary"
className="flex-1 truncate text-text-secondary system-sm-medium"
title={option.label}
>
{option.label}