import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { render } from '@testing-library/react' import { Provider } from './widget-provider' import { clearAllWidgetStores, getWidgetStore, hasWidgetStore, useWidgetId, } from '../stores' beforeEach(() => clearAllWidgetStores()) afterEach(() => clearAllWidgetStores()) function ChildSpy({ onMount }: { onMount: (id: string) => void }) { const id = useWidgetId() onMount(id) return null } describe('', () => { it('creates a store and exposes the id via context', () => { const ids: string[] = [] render( ids.push(i)} /> , ) expect(ids).toEqual(['p1']) expect(hasWidgetStore('p1')).toBe(true) const s = getWidgetStore('p1').getState() expect(s.rawData).toEqual({ x: 1 }) // Provider is renderer-agnostic — option pipeline state lives in // ``, not on the store. expect( (s as unknown as { rawOptions?: unknown }).rawOptions, ).toBeUndefined() }) it('removes the store on unmount when keepAlive is false (default)', () => { const { unmount } = render( , ) unmount() expect(hasWidgetStore('p2')).toBe(false) }) it('preserves the store on unmount when keepAlive is true', () => { const { unmount } = render( , ) unmount() expect(hasWidgetStore('p3')).toBe(true) }) it('reuses an existing keepAlive store on remount and preserves transformStates', () => { const { unmount } = render( , ) getWidgetStore('p4').setState({ transformStates: { foo: { enabled: false } }, }) unmount() render( , ) expect(getWidgetStore('p4').getState().transformStates.foo).toEqual({ enabled: false, }) }) it('syncs data / isLoading / error / formatter prop changes onto the store', () => { const fmt = (n: number): string => `$${n}` const { rerender } = render( , ) expect(getWidgetStore('p5').getState().rawData).toBe(1) rerender( , ) const s = getWidgetStore('p5').getState() expect(s.rawData).toBe(2) expect(s.isLoading).toBe(true) expect(s.error).toEqual({ message: 'oops' }) expect(s.formatter).toBe(fmt) }) it('descendants see the store on first render (sync registration in lazy init)', () => { function Spy() { const id = useWidgetId() // If the store wasn't registered synchronously this would throw. const data = getWidgetStore(id).getState().rawData return {JSON.stringify(data)} } const { getByTestId } = render( , ) expect(getByTestId('data').textContent).toBe('{"initial":true}') }) })