import { describe, test, expect, vi, beforeEach } from 'vitest' import { render, screen, fireEvent } from '@testing-library/react' import { WidgetWrapper } from './wrapper' import { useWidgetStore } from '../stores/widget-store' import type { WrapperState } from './types' describe('WidgetWrapper', () => { beforeEach(() => { useWidgetStore.getState().clearWidgets() // Pre-set the widget in the store with required base fields useWidgetStore.getState().setWidget('test-wrapper', { type: 'wrapper', title: 'Test Title', isLoading: false, visible: true, collapsed: false, disabled: false, }) }) const defaultProps = { id: 'test-wrapper', title: 'Test Title', children:
Test Content
, } test('renders correctly with default props', () => { render() expect(screen.getByText('Test Content')).toBeTruthy() }) test('initializes widget state in store', () => { render() const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget).toBeTruthy() expect(widget.id).toBe('test-wrapper') expect(widget.title).toBe('Test Title') expect(widget.isLoading).toBe(false) // collapsed and disabled are set via props, undefined when not passed expect(widget.collapsed).toBeUndefined() expect(widget.disabled).toBeUndefined() expect(widget.visible).toBe(true) }) test('updates widget state when props change', () => { // Render with Title 1 const { rerender } = render( , ) let widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.title).toBe('Title 1') // Rerender with Title 2 rerender() widget = useWidgetStore.getState().widgets['test-wrapper'] as WrapperState expect(widget.title).toBe('Title 2') }) test('initializes with collapsed state', () => { render() const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.collapsed).toBe(true) }) test('initializes with disabled state', () => { render() const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.disabled).toBe(true) }) test('initializes with isLoading state', () => { useWidgetStore .getState() .setWidget('test-wrapper', { isLoading: true }) render() const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.isLoading).toBe(true) }) test('handles collapse toggle correctly', () => { const onChangeCollapsed = vi.fn() useWidgetStore .getState() .setWidget('test-wrapper', { collapsed: false }) render( , ) // Find the accordion and click to collapse const accordion = screen.getByRole('button') fireEvent.click(accordion) expect(onChangeCollapsed).toHaveBeenCalledTimes(1) const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.collapsed).toBe(true) }) test('handles expand correctly', () => { const onChangeCollapsed = vi.fn() render( , ) const accordion = screen.getByRole('button') fireEvent.click(accordion) expect(onChangeCollapsed).toHaveBeenCalledTimes(1) const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.collapsed).toBe(false) }) test('returns null when widget is not in store', () => { // Clear the store to simulate widget not being set const { container } = render() // Force the widget to be removed useWidgetStore.getState().removeWidget('test-wrapper') // Re-render to trigger the null check render(
Content
, ) // The component should render initially expect(container).toBeTruthy() }) test('passes sx prop to WrapperUI', () => { const sx = { backgroundColor: 'red' } render() // Component should render (sx is passed through) expect(screen.getByText('Test Content')).toBeTruthy() }) test('passes actions to WrapperUI', () => { const actions = [] render() expect(screen.getByText('Action 1')).toBeTruthy() }) test('passes options to WrapperUI', () => { const options = [ { label: 'Option 1', onClick: vi.fn(), }, ] render() // Options button should be rendered const optionsButton = screen.getByLabelText('Options') expect(optionsButton).toBeTruthy() }) test('passes labels to WrapperUI', () => { const labels = { options: { title: 'Custom Options', }, } render() // Component should render with labels expect(screen.getByText('Test Content')).toBeTruthy() }) test('updates widget when all props change', () => { useWidgetStore.getState().setWidget('test-wrapper', { title: 'Initial Title', collapsed: false, disabled: false, isLoading: false, }) const { rerender } = render() useWidgetStore.getState().setWidget('test-wrapper', { title: 'Updated Title', collapsed: true, disabled: true, isLoading: true, }) rerender() const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.title).toBe('Updated Title') expect(widget.collapsed).toBe(true) expect(widget.disabled).toBe(true) expect(widget.isLoading).toBe(true) }) test('handles missing optional props', () => { render(
Content
, ) const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.isLoading).toBe(false) // collapsed and disabled are set via props, undefined when not passed expect(widget.collapsed).toBeUndefined() expect(widget.disabled).toBeUndefined() }) test('renders WrapperUI with accordion', () => { render() // Should render WrapperUI with accordion const accordion = screen.getByRole('button') expect(accordion).toBeTruthy() expect(screen.getByText('Test Content')).toBeTruthy() }) test('reads title from store when widget exists', () => { // Pre-populate store with widget useWidgetStore.getState().setWidget('test-wrapper', { type: 'wrapper', title: 'Store Title', isLoading: false, visible: true, }) render(
Content
, ) // Should display title from store const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.title).toBe('Store Title') }) test('renders actions even when widget is collapsed', () => { const actions = [] useWidgetStore .getState() .setWidget('test-wrapper', { collapsed: true }) render() // Actions are visible in the AccordionSummary even when collapsed expect(screen.getByText('Action 1')).toBeTruthy() }) test('shows actions when widget is expanded', () => { const actions = [] useWidgetStore .getState() .setWidget('test-wrapper', { collapsed: false }) render() // Actions should be visible when expanded expect(screen.getByText('Action 1')).toBeTruthy() }) test('actions remain visible when collapsing/expanding', () => { const actions = [] useWidgetStore .getState() .setWidget('test-wrapper', { collapsed: false }) const { rerender } = render( , ) // Actions visible when expanded expect(screen.getByText('Action 1')).toBeTruthy() // Collapse the widget useWidgetStore .getState() .setWidget('test-wrapper', { collapsed: true }) rerender() // Actions remain visible when collapsed (in AccordionSummary) expect(screen.getByText('Action 1')).toBeTruthy() }) test('isLoading state is independent from other states', () => { useWidgetStore .getState() .setWidget('test-wrapper', { isLoading: true }) render() const widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState // isLoading in store expect(widget.isLoading).toBe(true) }) test('updates isLoading when state changes', () => { useWidgetStore .getState() .setWidget('test-wrapper', { isLoading: false }) const { rerender } = render() let widget = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widget.isLoading).toBe(false) useWidgetStore .getState() .setWidget('test-wrapper', { isLoading: true }) rerender() widget = useWidgetStore.getState().widgets['test-wrapper'] as WrapperState expect(widget.isLoading).toBe(true) }) test('widget state persists across re-renders', () => { const { rerender } = render( , ) const widgetBefore = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widgetBefore.title).toBe('Persistent Title') // Re-render without changing props rerender() const widgetAfter = useWidgetStore.getState().widgets[ 'test-wrapper' ] as WrapperState expect(widgetAfter.title).toBe('Persistent Title') expect(widgetAfter).toBeTruthy() }) })