import { describe, test, expect, beforeEach } from 'vitest' import { render, screen, fireEvent } from '@testing-library/react' import { LockSelection, LOCK_SELECTION_TOOL_ID } from './lock-selection' import { useWidgetStore } from '../../stores/widget-store' import type { EchartWidgetData } from '../../echart/types' import type { LockSelectionState } from './types' import { WidgetLoader } from '../../loader/loader' // Test data const mockData: EchartWidgetData = [ [ { name: 'Electronics', value: 440 }, { name: 'Clothing', value: 280 }, { name: 'Books', value: 100 }, ], ] describe('LockSelection', () => { const widgetId = 'test-lock-selection' beforeEach(() => { useWidgetStore.getState().clearWidgets() }) test('renders nothing when no selections', () => { const { container } = render( , ) expect(container.firstChild).toBeNull() }) test('renders lock button when there are selections', () => { render() const button = screen.getByRole('button') expect(button).toBeTruthy() }) test('shows lock tooltip when unlocked', () => { render() const button = screen.getByRole('button', { name: 'Lock selection' }) expect(button).toBeTruthy() }) test('shows unlock tooltip when locked', () => { render() // Lock by clicking the button const button = screen.getByRole('button') fireEvent.click(button) const unlockedButton = screen.getByRole('button', { name: 'Unlock selection', }) expect(unlockedButton).toBeTruthy() }) test('toggles isLocked in tool state when clicked', () => { render() const button = screen.getByRole('button') fireEvent.click(button) const widget = useWidgetStore.getState().getWidget(widgetId) const tool = widget?.registeredTools?.find( (t) => t.id === LOCK_SELECTION_TOOL_ID, ) expect(tool?.enabled).toBe(true) }) test('filters data in store when locking', async () => { const selectedItems = ['Electronics'] render( , ) const button = screen.getByRole('button') fireEvent.click(button) await useWidgetStore.getState().executeToolPipeline(widgetId, mockData) const widget = useWidgetStore.getState().getWidget(widgetId) expect(widget?.data).toEqual([[{ name: 'Electronics', value: 440 }]]) }) test('clears locked items when unlocking', () => { render() // Lock first const button = screen.getByRole('button') fireEvent.click(button) // Then unlock fireEvent.click(button) const widget = useWidgetStore.getState().getWidget(widgetId) const tool = widget?.registeredTools?.find( (t) => t.id === LOCK_SELECTION_TOOL_ID, ) expect(tool?.enabled).toBe(false) }) test('clears lock state when selectedItems becomes empty while locked', () => { // Simulate remount: isLocked persists in store but selectedItems is now empty useWidgetStore .getState() .setWidget(widgetId, { isLocked: true, lockedItems: ['Electronics'] }) render() const widget = useWidgetStore.getState().getWidget(widgetId) expect((widget as LockSelectionState | undefined)?.isLocked).toBe(false) expect((widget as LockSelectionState | undefined)?.lockedItems).toEqual([]) }) test('has active state when locked', () => { render() const button = screen.getByRole('button') fireEvent.click(button) expect(button.getAttribute('data-active')).toBe('true') }) test('has inactive state when unlocked', () => { render() const button = screen.getByRole('button') expect(button.getAttribute('data-active')).toBe('false') }) test('uses custom labels', () => { render( , ) const button = screen.getByRole('button', { name: 'Toggle lock' }) expect(button).toBeTruthy() }) test('filters multiple series when locking', async () => { const multiSeriesData: EchartWidgetData = [ [ { name: 'Electronics', value: 440 }, { name: 'Clothing', value: 280 }, ], [ { name: 'Electronics', value: 520 }, { name: 'Clothing', value: 350 }, ], ] const selectedItems = ['Electronics'] render( , ) const button = screen.getByRole('button') fireEvent.click(button) await useWidgetStore .getState() .executeToolPipeline(widgetId, multiSeriesData) const widget = useWidgetStore.getState().getWidget(widgetId) expect(widget?.data).toEqual([ [{ name: 'Electronics', value: 440 }], [{ name: 'Electronics', value: 520 }], ]) }) })