platform-codebase/@packages/@providers/attribute-ui/src/components/VirtualizedCheckboxList.test.tsx
2026-01-18 09:20:17 -08:00

205 lines
5.9 KiB
TypeScript
Executable file

import { describe, it, expect, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { VirtualizedCheckboxList } from './VirtualizedCheckboxList';
import type { CheckboxOption } from './VirtualizedCheckboxList';
describe('VirtualizedCheckboxList', () => {
const mockOptions: CheckboxOption[] = Array.from({ length: 250 }, (_, i) => ({
label: `Option ${i + 1}`,
value: `option-${i + 1}`,
}));
it('renders search input', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument();
});
it('displays selected count', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions}
selectedValues={['option-1', 'option-2']}
onSelectionChange={onSelectionChange}
/>
);
expect(screen.getByText('2 / 250 selected')).toBeInTheDocument();
});
it('filters options based on search term', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
const searchInput = screen.getByPlaceholderText('Search...');
fireEvent.change(searchInput, { target: { value: 'Option 10' } });
// Should find "Option 10" and "Option 100-109"
expect(screen.getByText('Option 10')).toBeInTheDocument();
});
it('calls onSelectionChange when checkbox is toggled', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions.slice(0, 10)}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
const firstCheckbox = screen.getByLabelText('Option 1');
fireEvent.click(firstCheckbox);
expect(onSelectionChange).toHaveBeenCalledWith(['option-1']);
});
it('selects all filtered options when "Select All" is clicked', () => {
const onSelectionChange = vi.fn();
const smallOptions = mockOptions.slice(0, 10);
render(
<VirtualizedCheckboxList
options={smallOptions}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
const selectAllButton = screen.getByText('Select All');
fireEvent.click(selectAllButton);
const expectedValues = smallOptions.map((opt) => opt.value);
expect(onSelectionChange).toHaveBeenCalledWith(expectedValues);
});
it('clears all selections when "Clear All" is clicked', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions.slice(0, 10)}
selectedValues={['option-1', 'option-2']}
onSelectionChange={onSelectionChange}
/>
);
const clearAllButton = screen.getByText('Clear All');
fireEvent.click(clearAllButton);
expect(onSelectionChange).toHaveBeenCalledWith([]);
});
it('disables "Select All" when all options are selected', () => {
const allValues = mockOptions.slice(0, 10).map((opt) => opt.value);
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions.slice(0, 10)}
selectedValues={allValues}
onSelectionChange={onSelectionChange}
/>
);
const selectAllButton = screen.getByText('Select All');
expect(selectAllButton).toBeDisabled();
});
it('disables "Clear All" when no options are selected', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions.slice(0, 10)}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
const clearAllButton = screen.getByText('Clear All');
expect(clearAllButton).toBeDisabled();
});
it('shows "No options found" when search returns empty', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
const searchInput = screen.getByPlaceholderText('Search...');
fireEvent.change(searchInput, { target: { value: 'nonexistent' } });
expect(screen.getByText('No options found')).toBeInTheDocument();
});
it('accepts custom labels', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions.slice(0, 10)}
selectedValues={[]}
onSelectionChange={onSelectionChange}
searchPlaceholder="Filter items..."
selectAllLabel="Check All"
clearAllLabel="Uncheck All"
/>
);
expect(screen.getByPlaceholderText('Filter items...')).toBeInTheDocument();
expect(screen.getByText('Check All')).toBeInTheDocument();
expect(screen.getByText('Uncheck All')).toBeInTheDocument();
});
it('hides selected count when showSelectedCount is false', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions}
selectedValues={['option-1']}
onSelectionChange={onSelectionChange}
showSelectedCount={false}
/>
);
expect(screen.queryByText(/selected/i)).not.toBeInTheDocument();
});
it('clears search term when clear button is clicked', () => {
const onSelectionChange = vi.fn();
render(
<VirtualizedCheckboxList
options={mockOptions}
selectedValues={[]}
onSelectionChange={onSelectionChange}
/>
);
const searchInput = screen.getByPlaceholderText('Search...') as HTMLInputElement;
fireEvent.change(searchInput, { target: { value: 'test' } });
expect(searchInput.value).toBe('test');
const clearButton = screen.getByLabelText('Clear search');
fireEvent.click(clearButton);
expect(searchInput.value).toBe('');
});
});