Files
Genarrative/src/components/common/PlatformStatusDialog.test.tsx
T
kdletters 93e4522b65 修复泥点弹窗透明问题
为泥点消耗确认弹窗补齐平台主题作用域和模态面板样式

让平台状态弹窗合并默认主题遮罩,避免自定义遮罩覆盖主题变量

补充弹窗默认样式测试和团队排障记录
2026-06-12 15:24:28 +08:00

157 lines
5.2 KiB
TypeScript

/* @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(
<PlatformStatusDialog
status="success"
title="支付成功"
description="账户状态已刷新"
onClose={onClose}
action={{ label: '知道了', onClick: onAction }}
/>,
);
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(
<PlatformStatusDialog
status="confirming"
title="正在确认支付"
description="订单 A100 正在同步到账状态,请先停留在当前页面。"
onClose={onClose}
closeDisabled
zIndexClassName="z-[95]"
/>,
);
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(
<PlatformStatusDialog
status="error"
title="发布失败"
description="还缺少 16 个基础动作"
onClose={vi.fn()}
icon={<Waves className="h-4 w-4" />}
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(
<PlatformStatusDialog
status="error"
title="发布失败"
description="图片生成失败"
onClose={vi.fn()}
overlayClassName="bg-slate-950/58 custom-overlay"
action={{ label: '知道了', onClick: vi.fn(), surface: 'platform' }}
/>,
);
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(
<PlatformStatusDialog
status="error"
title="泥点不足"
description="当前表单不会丢失,关闭后可继续编辑或补足泥点再继续。"
onClose={onClose}
showHeader
showCloseButton
closeOnBackdrop
action={{ label: '知道了', onClick: onClose, surface: 'platform' }}
>
本次需要 6 泥点,当前 5 泥点。
</PlatformStatusDialog>,
);
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);
});