import { useRef } from 'react' import type { PropsWithChildren } from 'react' import { act, render, renderHook } from '@testing-library/react' import { afterEach, describe, expect, it } from 'vitest' import { UnityThemeProvider, useUnityTheme } from './unity-theme-provider' afterEach(() => { delete document.documentElement.dataset.uyTheme }) describe('UnityThemeProvider', () => { it('sets data-uy-theme on the html element when mounted', () => { render(
child
, ) expect(document.documentElement.dataset.uyTheme).toBe('rebrand') }) it('defaults to legacy when no theme prop is provided', () => { render(
child
, ) expect(document.documentElement.dataset.uyTheme).toBe('legacy') }) it('removes data-uy-theme on unmount', () => { const { unmount } = render(
child
, ) expect(document.documentElement.dataset.uyTheme).toBe('rebrand') unmount() expect(document.documentElement.dataset.uyTheme).toBeUndefined() }) it('renders children unchanged', () => { const { getByText } = render( hello world , ) expect(getByText('hello world')).toBeTruthy() }) describe('target', () => { it('sets data-uy-theme on a custom element via CSS selector', () => { const container = document.createElement('div') container.id = 'theme-root' document.body.appendChild(container) render(
child
, ) expect(container.dataset.uyTheme).toBe('rebrand') expect(document.documentElement.dataset.uyTheme).toBeUndefined() document.body.removeChild(container) }) it('sets data-uy-theme on a custom element via ref', () => { const targetEl = document.createElement('section') document.body.appendChild(targetEl) function TestComponent() { const ref = useRef(targetEl) return (
child
) } render() expect(targetEl.dataset.uyTheme).toBe('rebrand') expect(document.documentElement.dataset.uyTheme).toBeUndefined() document.body.removeChild(targetEl) }) }) }) describe('useUnityTheme', () => { it('returns the theme value from the provider', () => { const { result } = renderHook(() => useUnityTheme(), { wrapper: ({ children }) => ( {children} ), }) expect(result.current.theme).toBe('rebrand') }) it('returns "legacy" when used outside a provider', () => { const { result } = renderHook(() => useUnityTheme()) expect(result.current.theme).toBe('legacy') }) it('does not throw when used outside a provider', () => { expect(() => renderHook(() => useUnityTheme())).not.toThrow() }) it('exposes setTheme to change the theme at runtime', () => { const wrapper = ({ children }: PropsWithChildren) => ( {children} ) const { result } = renderHook(() => useUnityTheme(), { wrapper }) expect(result.current.theme).toBe('legacy') expect(document.documentElement.dataset.uyTheme).toBe('legacy') act(() => { result.current.setTheme('rebrand') }) expect(result.current.theme).toBe('rebrand') expect(document.documentElement.dataset.uyTheme).toBe('rebrand') }) it('setTheme is a no-op outside a provider', () => { const { result } = renderHook(() => useUnityTheme()) expect(() => { act(() => { result.current.setTheme('rebrand') }) }).not.toThrow() expect(result.current.theme).toBe('legacy') }) })