收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
141
src/components/common/PlatformUploadTile.test.tsx
Normal file
141
src/components/common/PlatformUploadTile.test.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import { PlatformUploadTile } from './PlatformUploadTile';
|
||||
|
||||
test('renders platform upload tile with default button semantics', () => {
|
||||
render(<PlatformUploadTile label="上传凭证" hint="(最多四张)" />);
|
||||
|
||||
const button = screen.getByRole('button', {
|
||||
name: '上传凭证 (最多四张)',
|
||||
});
|
||||
|
||||
expect(button.getAttribute('type')).toBe('button');
|
||||
expect(button.className).toContain('border-dashed');
|
||||
expect(button.className).toContain('bg-[var(--platform-input-fill)]');
|
||||
expect(screen.getByText('上传凭证')).toBeTruthy();
|
||||
expect(screen.getByText('(最多四张)')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('keeps disabled upload tile inert', () => {
|
||||
const onClick = vi.fn();
|
||||
|
||||
render(<PlatformUploadTile label="上传凭证" disabled onClick={onClick} />);
|
||||
|
||||
const button = screen.getByRole('button', { name: '上传凭证' });
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(button).toHaveProperty('disabled', true);
|
||||
expect(button.className).toContain('cursor-not-allowed');
|
||||
expect(onClick).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('supports label semantics for file inputs', () => {
|
||||
render(
|
||||
<>
|
||||
<PlatformUploadTile
|
||||
asChild="label"
|
||||
htmlFor="reference-upload"
|
||||
label="上传参考图"
|
||||
className="h-20 w-20"
|
||||
/>
|
||||
<input id="reference-upload" type="file" />
|
||||
</>,
|
||||
);
|
||||
|
||||
const input = screen.getByLabelText('上传参考图');
|
||||
const label = screen.getByText('上传参考图').closest('label');
|
||||
|
||||
expect(input.getAttribute('type')).toBe('file');
|
||||
expect(label?.getAttribute('for')).toBe('reference-upload');
|
||||
expect(label?.className).toContain('h-20');
|
||||
});
|
||||
|
||||
test('supports editor dark panel upload labels', () => {
|
||||
render(
|
||||
<>
|
||||
<PlatformUploadTile
|
||||
asChild="label"
|
||||
htmlFor="cover-upload"
|
||||
label="上传封面"
|
||||
hint="支持 png、jpg、webp。"
|
||||
icon={null}
|
||||
size="panel"
|
||||
surface="editorDark"
|
||||
/>
|
||||
<input id="cover-upload" type="file" />
|
||||
</>,
|
||||
);
|
||||
|
||||
const input = screen.getByLabelText(/上传封面/u);
|
||||
const label = screen.getByText('上传封面').closest('label');
|
||||
|
||||
expect(input.getAttribute('type')).toBe('file');
|
||||
expect(label?.className).toContain('min-h-[7rem]');
|
||||
expect(label?.className).toContain('items-start');
|
||||
expect(label?.className).toContain('border-white/12');
|
||||
expect(label?.className).toContain('bg-black/20');
|
||||
expect(screen.getByText('支持 png、jpg、webp。').className).toContain(
|
||||
'leading-5',
|
||||
);
|
||||
});
|
||||
|
||||
test('prevents disabled label uploads from opening the nested input', () => {
|
||||
const onClick = vi.fn();
|
||||
|
||||
render(
|
||||
<PlatformUploadTile
|
||||
asChild="label"
|
||||
label="上传参考图"
|
||||
disabled
|
||||
onClick={onClick}
|
||||
/>,
|
||||
);
|
||||
|
||||
const label = screen.getByText('上传参考图').closest('label');
|
||||
const clickEvent = new MouseEvent('click', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
|
||||
label?.dispatchEvent(clickEvent);
|
||||
|
||||
expect(clickEvent.defaultPrevented).toBe(true);
|
||||
expect(label?.getAttribute('aria-disabled')).toBe('true');
|
||||
expect(onClick).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('supports custom icon content', () => {
|
||||
render(
|
||||
<PlatformUploadTile
|
||||
label="上传音频"
|
||||
icon={<span aria-hidden="true">+</span>}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole('button', { name: '上传音频' }).textContent,
|
||||
).toContain('+');
|
||||
});
|
||||
|
||||
test('supports compact icon-only dashed actions', () => {
|
||||
render(
|
||||
<PlatformUploadTile
|
||||
label="新增功德词条"
|
||||
showLabel={false}
|
||||
size="compact"
|
||||
icon={<span aria-hidden="true">+</span>}
|
||||
className="rounded-[0.95rem]"
|
||||
/>,
|
||||
);
|
||||
|
||||
const button = screen.getByRole('button', { name: '新增功德词条' });
|
||||
const hiddenLabel = button.querySelector('.sr-only');
|
||||
|
||||
expect(button.className).toContain('h-12');
|
||||
expect(button.className).toContain('w-full');
|
||||
expect(button.className).toContain('rounded-[0.95rem]');
|
||||
expect(hiddenLabel?.textContent).toBe('新增功德词条');
|
||||
});
|
||||
Reference in New Issue
Block a user