import { describe, test, vi, expect, beforeEach } from 'vitest' import { render, screen, within } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { LassoToolsInlineUI } from './lasso-tool-inline' import { DEFAULT_LASSO_TOOLS_MODES_MAPPING } from './const' import type { LassoToolsModes } from '../types' import { changeLassoToolsModeOptions, DEFAULT_LASSO_TOOLS_MODES, } from '../../../tests/config' type LassoToolsMode = 'polygon' | 'rectangle' | 'circle' | 'lasso' | 'edit' describe('LassoToolsInlineUI', () => { const mockOnChangeMode = vi.fn() const mockOnChipToggle = vi.fn() const mockOnDelete = vi.fn() const mockOnAllChipToggle = vi.fn() const mockOnAllDelete = vi.fn() beforeEach(() => { vi.clearAllMocks() }) for (const [mode, label] of Object.entries(changeLassoToolsModeOptions)) { test(`should change mode to ${label}`, async () => { const { container } = render( , ) const modeButton = within(container).getByLabelText(mode) await userEvent.click(modeButton) expect(mockOnChangeMode).toHaveBeenCalled() }) } test('should change polygons visibility when clicking on the chip', async () => { const { container } = render( , ) const chip = within(container).getAllByLabelText('Show drawing')[0]! await userEvent.click(chip) expect(mockOnChipToggle).toHaveBeenCalledWith('polygon-id-1', true) }) test('should remove a polygon when clicking on chip-cancel-icon', async () => { render( , ) const cancelButton = screen.getAllByTestId('CancelIcon')[0]! await userEvent.click(cancelButton) expect(mockOnDelete).toHaveBeenCalledWith('polygon-id-1') }) test('should change polygons visibility when clicking on Show/Hide All', async () => { const { container } = render( , ) const showAllButton = within(container).getByText('Show all') await userEvent.click(showAllButton) expect(mockOnAllChipToggle).toHaveBeenCalled() }) test('should remove all polygons when clicking on Delete All', async () => { const { container } = render( , ) const deleteAllButton = within(container).getByText('Remove all') await userEvent.click(deleteAllButton) expect(mockOnAllDelete).toHaveBeenCalled() }) }) // Aux interface ComponentProps { enabled: boolean modeSelected: LassoToolsMode mockOnChangeMode: () => void mockOnChipToggle: () => void mockOnDelete: () => void mockOnAllChipToggle: () => void mockOnAllDelete: () => void } describe('LassoToolsInlineUI branches', () => { const mockOnChipToggle = vi.fn() const mockOnDelete = vi.fn() const mockOnAllChipToggle = vi.fn() const mockOnAllDelete = vi.fn() const mockOnChangeMode = vi.fn() const requiredCallbacks = { onChangeMode: mockOnChangeMode, onAllChipToggle: mockOnAllChipToggle, onAllDelete: mockOnAllDelete, } beforeEach(() => { vi.clearAllMocks() }) test('renders empty-state NoData when there are no values', () => { const { container } = render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} modeSelected='polygon' onChipToggle={mockOnChipToggle} onDelete={mockOnDelete} {...requiredCallbacks} />, ) // The "no data" Typography branch should have rendered expect(container.querySelector('.inline')).toBeDefined() }) test('renders without onChangeMode prop (optional callback)', async () => { const { container } = render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} modeSelected='polygon' onChipToggle={mockOnChipToggle} onDelete={mockOnDelete} {...requiredCallbacks} />, ) // Clicking the mode should not throw despite missing onChangeMode const modeButton = within(container).getByLabelText('rectangle') await expect(userEvent.click(modeButton)).resolves.toBeUndefined() }) test('uses the first mode when modeSelected is not in the modes map', () => { expect(() => render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} // bogus mode → modeExists=false → falls back to first key modeSelected={'not-a-mode' as never} onChipToggle={mockOnChipToggle} {...requiredCallbacks} onDelete={mockOnDelete} />, ), ).not.toThrow() }) test('renders with modeSelectedValue=null when disabled (enabled=false)', () => { expect(() => render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} modeSelected='polygon' onChipToggle={mockOnChipToggle} {...requiredCallbacks} onDelete={mockOnDelete} />, ), ).not.toThrow() }) test('Actions block is hidden when there is only one value (Actions returns null branch)', () => { const { container } = render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} modeSelected='polygon' onChipToggle={mockOnChipToggle} onDelete={mockOnDelete} {...requiredCallbacks} />, ) // With ≤1 values, the "Show all / Delete all" buttons should not render expect(within(container).queryByText(/Show all/i)).toBeNull() expect(within(container).queryByText(/Delete all/i)).toBeNull() }) test('uses custom labels.actions when provided', () => { const { container } = render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} modeSelected='polygon' labels={{ actions: { toggleAll: { active: 'Hide everything', inactive: 'Show all (custom)', }, deleteAll: 'Wipe everything', }, }} onChipToggle={mockOnChipToggle} onDelete={mockOnDelete} {...requiredCallbacks} />, ) expect(within(container).queryByText('Show all (custom)')).not.toBeNull() expect(within(container).queryByText('Wipe everything')).not.toBeNull() }) test('renders a single mode without the ModeList title (data.length <= 1)', () => { expect(() => render( > } modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} modeSelected='polygon' onChipToggle={mockOnChipToggle} {...requiredCallbacks} onDelete={mockOnDelete} />, ), ).not.toThrow() }) }) const Component = ({ enabled, modeSelected, mockOnChangeMode, mockOnChipToggle, mockOnDelete, mockOnAllChipToggle, mockOnAllDelete, }: ComponentProps) => { return ( > } modeSelected={modeSelected} modesMapping={DEFAULT_LASSO_TOOLS_MODES_MAPPING} onChangeMode={mockOnChangeMode} onChipToggle={mockOnChipToggle} onDelete={mockOnDelete} onAllChipToggle={mockOnAllChipToggle} onAllDelete={mockOnAllDelete} /> ) }