import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { fireEvent, render, screen } from '@testing-library/react'
import { Provider } from '../provider/widget-provider'
import { clearAllWidgetStores } from '../stores'
import { Wrapper } from './widget-wrapper'
import { Actions } from './widget-actions'
import { Content } from './widget-content'
beforeEach(() => clearAllWidgetStores())
afterEach(() => clearAllWidgetStores())
function withProvider(id: string, ui: React.ReactNode, isFetching = false) {
return (
{ui}
)
}
describe('', () => {
it('renders the title', () => {
render(
withProvider(
'wrap-1',
body,
),
)
expect(screen.getByText('Sales')).toBeTruthy()
})
it('renders Content children when expanded', () => {
render(
withProvider(
'wrap-2',
body
,
),
)
expect(screen.getByTestId('body')).toBeTruthy()
})
it('keeps Content mounted but visually hidden when collapsed', () => {
// Accordion uses MUI , which animates the parent via height/visibility.
// Children stay mounted (the Collapse keeps `keepMounted` semantics by default).
render(
withProvider(
'wrap-3',
,
),
)
const actionBtn = screen.getByTestId('action-btn')
const bodyContent = screen.getByTestId('body-content')
// The action lives inside the AccordionSummary, the body inside AccordionDetails.
expect(actionBtn.closest('.MuiAccordionSummary-root')).not.toBeNull()
expect(bodyContent.closest('.MuiAccordionDetails-root')).not.toBeNull()
})
it('shows a LinearProgress at the top when the store reports isFetching', () => {
render(
withProvider(
'wrap-7',
body,
true,
),
)
expect(screen.getByRole('progressbar')).toBeTruthy()
})
it('hides the LinearProgress when isFetching is false', () => {
render(
withProvider(
'wrap-8',
body,
false,
),
)
expect(screen.queryByRole('progressbar')).toBeNull()
})
it('renders by default (elevation variant) with body intact', () => {
render(
withProvider(
'wrap-variant-default',
body
,
),
)
expect(screen.getByText('t')).toBeTruthy()
expect(screen.getByTestId('body')).toBeTruthy()
})
it('renders the outlined variant with body intact', () => {
render(
withProvider(
'wrap-variant-outlined',
,
),
)
expect(screen.getByTestId('body')).toBeTruthy()
})
it('disables only the summary, leaving the details panel interactive', () => {
let clicks = 0
render(
withProvider(
'wrap-10',
,
),
)
// The details panel keeps its events even while the wrapper is disabled.
fireEvent.click(screen.getByTestId('body-btn'))
expect(clicks).toBe(1)
})
it('does not toggle when the disabled summary is clicked', () => {
let lastCollapsed: boolean | undefined
render(
withProvider(
'wrap-11',
(lastCollapsed = c)}
>
body,
),
)
fireEvent.click(screen.getByText('t'))
expect(lastCollapsed).toBeUndefined()
})
it('keeps summary actions clickable while the wrapper is disabled', () => {
let actionClicks = 0
let lastCollapsed: boolean | undefined
render(
withProvider(
'wrap-12',
(lastCollapsed = c)}
>
body,
),
)
fireEvent.click(screen.getByTestId('action-btn'))
// The action fires, and clicking it must not toggle the disabled wrapper.
expect(actionClicks).toBe(1)
expect(lastCollapsed).toBeUndefined()
})
})