import { renderHook, act } from '@testing-library/react' import { useToast, clearAllToasts, reducer } from '../toast/use-toast' import type { ToasterToast } from '../toast/use-toast' beforeEach(() => { clearAllToasts() }) describe('useToast', () => { it('adds a toast', () => { const { result } = renderHook(() => useToast()) act(() => { result.current.toast({ title: 'Hello', description: 'World' }) }) expect(result.current.toasts).toHaveLength(1) expect(result.current.toasts[0].title).toBe('Hello') expect(result.current.toasts[0].description).toBe('World') }) it('adds toast with variant', () => { const { result } = renderHook(() => useToast()) act(() => { result.current.toast({ title: 'Error', variant: 'destructive' }) }) expect(result.current.toasts[0].variant).toBe('destructive') }) it('dismisses a specific toast', () => { jest.useFakeTimers() const { result } = renderHook(() => useToast()) let toastId: string act(() => { // Use duration: 0 to prevent auto-dismiss interference const t = result.current.toast({ title: 'Dismiss me', duration: 0 }) toastId = t.id }) expect(result.current.toasts).toHaveLength(1) act(() => { result.current.dismiss(toastId) }) // Advance past the dismiss animation delay act(() => { jest.advanceTimersByTime(500) }) expect(result.current.toasts).toHaveLength(0) jest.useRealTimers() }) it('clears all toasts', () => { const { result } = renderHook(() => useToast()) act(() => { result.current.toast({ title: 'One', duration: 0 }) result.current.toast({ title: 'Two', duration: 0 }) result.current.toast({ title: 'Three', duration: 0 }) }) expect(result.current.toasts.length).toBeGreaterThanOrEqual(1) act(() => { result.current.clear() }) expect(result.current.toasts).toHaveLength(0) }) }) describe('reducer', () => { const makeToast = (id: string, title: string): ToasterToast => ({ id, title, }) it('ADD_TOAST adds to front of list', () => { const state = { toasts: [makeToast('1', 'First')] } const result = reducer(state, { type: 'ADD_TOAST', toast: makeToast('2', 'Second'), }) expect(result.toasts[0].title).toBe('Second') expect(result.toasts).toHaveLength(2) }) it('UPDATE_TOAST updates matching toast', () => { const state = { toasts: [makeToast('1', 'Original')] } const result = reducer(state, { type: 'UPDATE_TOAST', toast: { id: '1', title: 'Updated' }, }) expect(result.toasts[0].title).toBe('Updated') }) it('REMOVE_TOAST with undefined removes all', () => { const state = { toasts: [makeToast('1', 'A'), makeToast('2', 'B')], } const result = reducer(state, { type: 'REMOVE_TOAST', toastId: undefined, }) expect(result.toasts).toHaveLength(0) }) it('REMOVE_TOAST with id removes specific toast', () => { const state = { toasts: [makeToast('1', 'A'), makeToast('2', 'B')], } const result = reducer(state, { type: 'REMOVE_TOAST', toastId: '1', }) expect(result.toasts).toHaveLength(1) expect(result.toasts[0].id).toBe('2') }) })