import { afterEach, describe, it, expect } from 'vitest' import { act, fireEvent, render, screen } from '@testing-library/react' import { LegendProvider } from '../../provider' import { LegendVisibleLayers } from './legend-visible-layers' import { clearAllLegendStores, getLegendStore, type LegendLayerInput, type LegendVariable, } from '../../stores' const cat: LegendVariable = { type: 'category', items: [{ label: 'A', color: '#123456' }], } const layers: LegendLayerInput[] = [ { id: 'a', name: 'Suitability', groupId: 'g1', variables: [cat] }, { id: 'b', name: 'Population', groupId: 'g2', variables: [cat] }, { id: 'c', name: 'Facilities', variables: [cat] }, // ungrouped → last ] const groups = [ { id: 'g1', label: 'Site selection' }, { id: 'g2', label: 'Demographics' }, ] afterEach(() => clearAllLegendStores()) function renderSummary(id: string, layerInputs = layers) { return render( , ) } describe('', () => { it('lists only visible layers grouped under their captions, ungrouped last', () => { renderSummary('vl1', [ ...layers.slice(0, 2), { ...layers[2]!, visible: false } as LegendLayerInput, ]) fireEvent.click(screen.getByLabelText('Enabled layers')) // Count excludes the hidden ungrouped layer. expect(screen.getByText('Enabled layers (2)')).toBeTruthy() expect(screen.getByText('Site selection')).toBeTruthy() expect(screen.getByText('Suitability')).toBeTruthy() expect(screen.getByText('Population')).toBeTruthy() // Hidden layer (and its would-be section) not listed. expect(screen.queryByText('Facilities')).toBeNull() }) it('clicking an entry hides the layer and removes it without closing the menu', () => { renderSummary('vl2') fireEvent.click(screen.getByLabelText('Enabled layers')) expect(screen.getByText('Enabled layers (3)')).toBeTruthy() // The whole item is the hide action (keyboard-reachable menu item). fireEvent.click(screen.getByRole('menuitem', { name: 'Suitability' })) expect(getLegendStore('vl2').getState().layers.a!.visible).toBe(false) // Menu stayed open, entry gone, count updated live. expect(screen.getByText('Enabled layers (2)')).toBeTruthy() expect(screen.queryByText('Suitability')).toBeNull() }) it('hiding the last visible layer closes the menu and disables the trigger', () => { renderSummary('vl3', [layers[0]!]) const trigger = screen.getByLabelText('Enabled layers') fireEvent.click(trigger) fireEvent.click(screen.getByRole('menuitem', { name: 'Suitability' })) // Nothing left to list → the menu closed itself (role queries skip the // aria-hidden exit transition)… expect(screen.queryByRole('menu')).toBeNull() // …and the trigger is disabled until a layer is shown again. expect(trigger.disabled).toBe(true) }) it('closes when the last visible layer is hidden from elsewhere', () => { renderSummary('vl4', [layers[0]!]) fireEvent.click(screen.getByLabelText('Enabled layers')) expect(screen.getByRole('menu')).toBeTruthy() // External change (e.g. a row eye) while the menu is open. act(() => getLegendStore('vl4').getState().setVisibility('a', false)) expect(screen.queryByRole('menu')).toBeNull() }) })