/** * Tests for LassoGeometryToolbarUI — type toggle, rename popover (Enter/blur * commit, no-op on empty/unchanged), lock toggle, delete, and the locked * read-only behavior (every action but unlock disabled). */ import { describe, it, expect, vi } from 'vitest' import { render, fireEvent, screen } from '@testing-library/react' import { LassoGeometryToolbarUI } from './geometry-toolbar' function setup( props: Partial[0]> = {}, ) { const handlers = { onToggleType: vi.fn(), onRename: vi.fn(), onToggleLock: vi.fn(), onDelete: vi.fn(), } render( , ) return handlers } describe('LassoGeometryToolbarUI', () => { it('toggles mask -> draw', () => { const { onToggleType } = setup({ type: 'mask' }) fireEvent.click(screen.getByRole('button', { name: 'Switch to drawing' })) expect(onToggleType).toHaveBeenCalledWith('draw') }) it('toggles draw -> mask', () => { const { onToggleType } = setup({ type: 'draw' }) fireEvent.click(screen.getByRole('button', { name: 'Switch to mask' })) expect(onToggleType).toHaveBeenCalledWith('mask') }) it('marks the mask button pressed when type is mask', () => { setup({ type: 'mask' }) expect( screen .getByRole('button', { name: 'Switch to drawing' }) .getAttribute('aria-pressed'), ).toBe('true') }) it('marks the mask button not-pressed when type is draw', () => { setup({ type: 'draw' }) expect( screen .getByRole('button', { name: 'Switch to mask' }) .getAttribute('aria-pressed'), ).toBe('false') }) it('marks the lock button pressed when locked', () => { setup({ locked: true }) expect( screen .getByRole('button', { name: 'Unlock' }) .getAttribute('aria-pressed'), ).toBe('true') }) it('commits a new label on Enter', () => { const { onRename } = setup({ label: 'Mask 1' }) fireEvent.click(screen.getByRole('button', { name: 'Rename' })) const input = screen.getByRole('textbox') fireEvent.change(input, { target: { value: 'Downtown' } }) fireEvent.keyDown(input, { key: 'Enter' }) expect(onRename).toHaveBeenCalledWith('Downtown') }) it('does not call onRename when the label is unchanged', () => { const { onRename } = setup({ label: 'Mask 1' }) fireEvent.click(screen.getByRole('button', { name: 'Rename' })) const input = screen.getByRole('textbox') fireEvent.keyDown(input, { key: 'Enter' }) expect(onRename).not.toHaveBeenCalled() }) it('commits the rename only once (blur after Enter does not double-fire)', () => { const { onRename } = setup({ label: 'Mask 1' }) fireEvent.click(screen.getByRole('button', { name: 'Rename' })) const input = screen.getByRole('textbox') fireEvent.change(input, { target: { value: 'Downtown' } }) fireEvent.keyDown(input, { key: 'Enter' }) fireEvent.blur(input) expect(onRename).toHaveBeenCalledTimes(1) }) it('discards the rename on Escape (does not call onRename)', () => { const { onRename } = setup({ label: 'Mask 1' }) fireEvent.click(screen.getByRole('button', { name: 'Rename' })) const input = screen.getByRole('textbox') fireEvent.change(input, { target: { value: 'Downtown' } }) fireEvent.keyDown(input, { key: 'Escape' }) fireEvent.blur(input) expect(onRename).not.toHaveBeenCalled() }) it('locks an unlocked geometry', () => { const { onToggleLock } = setup({ locked: false }) fireEvent.click(screen.getByRole('button', { name: 'Lock' })) expect(onToggleLock).toHaveBeenCalledWith(true) }) it('unlocks a locked geometry', () => { const { onToggleLock } = setup({ locked: true }) fireEvent.click(screen.getByRole('button', { name: 'Unlock' })) expect(onToggleLock).toHaveBeenCalledWith(false) }) it('deletes the geometry', () => { const { onDelete } = setup() fireEvent.click(screen.getByRole('button', { name: 'Delete' })) expect(onDelete).toHaveBeenCalledTimes(1) }) it('disables every action but unlock when locked', () => { const handlers = setup({ locked: true }) const disabled = (name: string) => screen.getByRole('button', { name }).hasAttribute('disabled') expect(disabled('Switch to drawing')).toBe(true) expect(disabled('Rename')).toBe(true) expect(disabled('Delete')).toBe(true) // Unlock stays enabled. const unlock = screen.getByRole('button', { name: 'Unlock' }) expect(unlock.hasAttribute('disabled')).toBe(false) fireEvent.click(unlock) expect(handlers.onToggleLock).toHaveBeenCalledWith(false) }) })