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()
})
})