/* @vitest-environment jsdom */ import { Waves } from 'lucide-react'; import { fireEvent, render, screen } from '@testing-library/react'; import { expect, test, vi } from 'vitest'; import { PlatformStatusDialog } from './PlatformStatusDialog'; test('renders result state with description and primary action', () => { const onClose = vi.fn(); const onAction = vi.fn(); render( , ); const dialog = screen.getByRole('dialog', { name: '支付成功' }); const overlay = dialog.parentElement as HTMLElement; const badge = dialog.querySelector('.platform-icon-badge'); const action = screen.getByRole('button', { name: '知道了' }); const visibleDescription = dialog.querySelector( '.mt-3.text-sm.font-semibold.leading-6.text-\\[var\\(--platform-text-soft\\)\\]', ); expect(dialog).toBeTruthy(); expect(overlay.className).toContain('platform-theme--light'); expect(overlay.className).toContain('platform-profile-modal-overlay'); expect(visibleDescription?.textContent).toBe('账户状态已刷新'); expect(badge?.className).toContain('text-[var(--platform-success-text)]'); expect(action.className).toContain('platform-primary-button'); fireEvent.click(action); expect(onAction).toHaveBeenCalledTimes(1); }); test('supports blocking confirming state without close action', () => { const onClose = vi.fn(); render( , ); const dialog = screen.getByRole('dialog', { name: '正在确认支付' }); const overlay = dialog.parentElement as HTMLElement; const spinner = dialog.querySelector('.platform-icon-badge svg'); expect(overlay.className).toContain('z-[95]'); expect(spinner?.getAttribute('class')).toContain('animate-spin'); expect( screen.queryByRole('button', { name: '关闭' }) || screen.queryByRole('button', { name: '知道了' }), ).toBeNull(); fireEvent.click(overlay); fireEvent.keyDown(window, { key: 'Escape' }); expect(onClose).not.toHaveBeenCalled(); }); test('supports custom badge icon label and action button styling', () => { render( } iconLabel="发布失败提示" iconClassName="bg-[var(--platform-button-danger-fill)] text-[var(--platform-button-danger-text)]" action={{ label: '知道了', onClick: vi.fn(), surface: 'platform', className: 'border-slate-950 bg-slate-950 text-white', }} />, ); const badge = screen.getByLabelText('发布失败提示'); const action = screen.getByRole('button', { name: '知道了' }); expect(badge.className).toContain('bg-[var(--platform-button-danger-fill)]'); expect(badge.className).toContain( 'text-[var(--platform-button-danger-text)]', ); expect(action.className).toContain('border-slate-950'); expect(action.className).toContain('bg-slate-950'); }); test('keeps default theme classes when callers customize the overlay', () => { render( , ); const dialog = screen.getByRole('dialog', { name: '发布失败' }); const overlay = dialog.parentElement as HTMLElement; expect(overlay.className).toContain('platform-theme--light'); expect(overlay.className).toContain('platform-profile-modal-overlay'); expect(overlay.className).toContain('bg-slate-950/58'); expect(overlay.className).toContain('custom-overlay'); }); test('supports header notice layout with body content and close button', () => { const onClose = vi.fn(); render( 本次需要 6 泥点,当前 5 泥点。 , ); const dialog = screen.getByRole('dialog', { name: '泥点不足' }); expect( dialog.querySelector('.mt-4.text-xl.font-black.text-\\[var\\(--platform-text-strong\\)\\]'), ).toBeNull(); expect(screen.getByText('本次需要 6 泥点,当前 5 泥点。')).toBeTruthy(); expect( screen.getByText( '当前表单不会丢失,关闭后可继续编辑或补足泥点再继续。', ), ).toBeTruthy(); fireEvent.click(screen.getByRole('button', { name: '关闭' })); expect(onClose).toHaveBeenCalledTimes(1); });