1ad25e30f8
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
188 lines
5.3 KiB
TypeScript
188 lines
5.3 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { fireEvent, render, screen, within } from '@testing-library/react';
|
|
import { expect, test, vi } from 'vitest';
|
|
|
|
import { UnifiedConfirmDialog } from './UnifiedConfirmDialog';
|
|
|
|
test('renders a simple confirm dialog and closes through the primary action', () => {
|
|
const onClose = vi.fn();
|
|
|
|
render(
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="泥点提示"
|
|
description="当前表单不会丢失。"
|
|
onClose={onClose}
|
|
confirmLabel="知道了"
|
|
>
|
|
泥点不足,请补足后继续。
|
|
</UnifiedConfirmDialog>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '泥点提示' });
|
|
expect(within(dialog).getByText('当前表单不会丢失。')).toBeTruthy();
|
|
expect(within(dialog).getByText('泥点不足,请补足后继续。')).toBeTruthy();
|
|
|
|
fireEvent.click(within(dialog).getByRole('button', { name: '知道了' }));
|
|
|
|
expect(onClose).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
test('supports cancel and danger confirm actions', () => {
|
|
const onClose = vi.fn();
|
|
const onConfirm = vi.fn();
|
|
|
|
render(
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="删除作品"
|
|
description="确认删除《潮雾列岛》吗?"
|
|
onClose={onClose}
|
|
onConfirm={onConfirm}
|
|
showCancel
|
|
confirmLabel="确认删除"
|
|
confirmTone="danger"
|
|
>
|
|
删除后不可恢复。
|
|
</UnifiedConfirmDialog>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '删除作品' });
|
|
|
|
fireEvent.click(within(dialog).getByRole('button', { name: '取消' }));
|
|
expect(onClose).toHaveBeenCalledTimes(1);
|
|
|
|
fireEvent.click(within(dialog).getByRole('button', { name: '确认删除' }));
|
|
expect(onConfirm).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
test('busy state disables close paths and shows the busy confirm label', () => {
|
|
const onClose = vi.fn();
|
|
const onConfirm = vi.fn();
|
|
|
|
render(
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="删除作品"
|
|
onClose={onClose}
|
|
onConfirm={onConfirm}
|
|
showCancel
|
|
confirmLabel="确认删除"
|
|
busyConfirmLabel="删除中"
|
|
busy
|
|
>
|
|
正在删除。
|
|
</UnifiedConfirmDialog>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '删除作品' });
|
|
const overlay = dialog.parentElement as HTMLElement;
|
|
|
|
expect(
|
|
(
|
|
within(dialog).getByRole('button', {
|
|
name: '删除中',
|
|
}) as HTMLButtonElement
|
|
).disabled,
|
|
).toBe(true);
|
|
expect(
|
|
(within(dialog).getByRole('button', { name: '取消' }) as HTMLButtonElement)
|
|
.disabled,
|
|
).toBe(true);
|
|
|
|
fireEvent.click(overlay);
|
|
fireEvent.keyDown(window, { key: 'Escape' });
|
|
fireEvent.click(within(dialog).getByRole('button', { name: '删除中' }));
|
|
|
|
expect(onClose).not.toHaveBeenCalled();
|
|
expect(onConfirm).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('can render inline inside an existing modal stack', () => {
|
|
const { container } = render(
|
|
<div data-testid="modal-stack">
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="确认消耗泥点"
|
|
onClose={() => {}}
|
|
portal={false}
|
|
showCancel
|
|
>
|
|
消耗 2 泥点
|
|
</UnifiedConfirmDialog>
|
|
</div>,
|
|
);
|
|
|
|
const stack = screen.getByTestId('modal-stack');
|
|
const dialog = within(stack).getByRole('dialog', { name: '确认消耗泥点' });
|
|
|
|
expect(dialog).toBeTruthy();
|
|
expect(
|
|
container.querySelector('[data-testid="modal-stack"] [role="dialog"]'),
|
|
).toBe(dialog);
|
|
});
|
|
|
|
test('can hide the header close button for compact confirmations', () => {
|
|
render(
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="确认消耗泥点"
|
|
onClose={() => {}}
|
|
showCloseButton={false}
|
|
showCancel
|
|
>
|
|
消耗 2 泥点
|
|
</UnifiedConfirmDialog>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '确认消耗泥点' });
|
|
|
|
expect(within(dialog).queryByRole('button', { name: '关闭' })).toBeNull();
|
|
expect(within(dialog).getByRole('button', { name: '取消' })).toBeTruthy();
|
|
expect(within(dialog).getByRole('button', { name: '确定' })).toBeTruthy();
|
|
});
|
|
|
|
test('allows callers to adapt the confirm button layout without custom footer markup', () => {
|
|
render(
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="发布失败"
|
|
onClose={() => {}}
|
|
confirmLabel="知道了"
|
|
confirmClassName="w-full justify-center"
|
|
footerClassName="border-t-0 px-5 pb-5 pt-0"
|
|
>
|
|
发布校验未通过。
|
|
</UnifiedConfirmDialog>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '发布失败' });
|
|
const confirmButton = within(dialog).getByRole('button', { name: '知道了' });
|
|
|
|
expect(confirmButton.className).toContain('w-full');
|
|
expect(confirmButton.className).toContain('justify-center');
|
|
});
|
|
|
|
test('supports pixel variant for in-editor confirmations', () => {
|
|
render(
|
|
<UnifiedConfirmDialog
|
|
open
|
|
title="确认退出"
|
|
onClose={() => {}}
|
|
variant="pixel"
|
|
showCancel
|
|
confirmLabel="仍然退出"
|
|
cancelLabel="继续编辑"
|
|
>
|
|
当前生成画面还未保存。
|
|
</UnifiedConfirmDialog>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '确认退出' });
|
|
|
|
expect(dialog.className).toContain('pixel-modal-shell');
|
|
expect(within(dialog).getByRole('button', { name: '仍然退出' })).toBeTruthy();
|
|
expect(within(dialog).getByRole('button', { name: '继续编辑' })).toBeTruthy();
|
|
});
|