Files
Genarrative/src/components/common/CopyFeedbackButton.test.tsx
T
kdletters 06bf03a28c 继续收口平台空态与动作按钮
作品架异步状态切换复用 PlatformAsyncStatePanel
复制反馈动作外观改为组合 PlatformActionButton
结果页与调试面板空态继续收口到 PlatformEmptyState
暗色私聊与工坊按钮改为复用 PlatformActionButton
更新 PlatformUiKit 收口文档与团队决策记录
2026-06-11 01:41:15 +08:00

142 lines
3.9 KiB
TypeScript

/* @vitest-environment jsdom */
import { render, screen, within } from '@testing-library/react';
import { expect, test } from 'vitest';
import { CopyFeedbackButton } from './CopyFeedbackButton';
test('renders idle copy label and icon by default', () => {
render(
<CopyFeedbackButton
state="idle"
idleLabel="分享"
className="platform-button"
/>,
);
const button = screen.getByRole('button', { name: '分享' });
expect(button.className).toContain('platform-button');
expect(within(button).getByText('分享')).toBeTruthy();
expect(button.querySelector('svg')).toBeTruthy();
});
test('switches copied and failed feedback labels', () => {
const { rerender } = render(
<CopyFeedbackButton
state="copied"
idleLabel="复制作品号"
copiedLabel="作品号已复制"
failedLabel="作品号复制失败"
/>,
);
expect(screen.getByRole('button', { name: '作品号已复制' })).toBeTruthy();
rerender(
<CopyFeedbackButton
state="failed"
idleLabel="复制作品号"
copiedLabel="作品号已复制"
failedLabel="作品号复制失败"
/>,
);
expect(screen.getByRole('button', { name: '作品号复制失败' })).toBeTruthy();
});
test('keeps custom accessible label for compact buttons', () => {
render(
<CopyFeedbackButton
state="copied"
idleLabel="作品号 PZ-001"
aria-label="复制作品号 PZ-001"
title="复制作品号"
showIcon={false}
/>,
);
const button = screen.getByRole('button', { name: '复制作品号 PZ-001' });
expect(button.textContent).toBe('已复制');
expect(button.getAttribute('title')).toBe('复制作品号');
});
test('supports icon-only buttons with feedback labels kept in accessibility', () => {
render(
<CopyFeedbackButton
state="copied"
idleLabel="分享作品"
copiedLabel="分享内容已复制"
showLabel={false}
className="icon-button"
/>,
);
const button = screen.getByRole('button', { name: '分享内容已复制' });
expect(button.textContent).toBe('');
expect(button.querySelector('svg')).toBeTruthy();
});
test('allows overriding accessible label without business-side state branches', () => {
render(
<CopyFeedbackButton
state="failed"
idleLabel="分享作品"
failedLabel="复制失败"
accessibleLabel="分享内容复制失败"
showLabel={false}
/>,
);
const button = screen.getByRole('button', {
name: '分享内容复制失败',
});
expect(button.getAttribute('title')).toBe('分享内容复制失败');
});
test('can opt into platform action button chrome', () => {
render(
<CopyFeedbackButton
state="idle"
idleLabel="复制报错"
actionSurface="platform"
actionShape="pill"
actionFullWidth
aria-label="复制错误详情"
title="复制错误详情"
/>,
);
const button = screen.getByRole('button', { name: '复制错误详情' });
expect(button.className).toContain('platform-button--primary');
expect(button.className).toContain('w-full');
expect(button.className).toContain('rounded-full');
expect(button.className).toContain('disabled:cursor-not-allowed');
expect(button.getAttribute('title')).toBe('复制错误详情');
expect(button.textContent).toContain('复制报错');
});
test('can opt into shared pill action chrome', () => {
render(
<CopyFeedbackButton
state="idle"
idleLabel="分享作品"
actionAppearance="pill"
actionPillSize="xxs"
className="tracking-[0.18em]"
/>,
);
const button = screen.getByRole('button', { name: '分享作品' });
expect(button.className).toContain('rounded-full');
expect(button.className).toContain('bg-white/72');
expect(button.className).toContain('text-[10px]');
expect(button.className).toContain('tracking-[0.18em]');
expect(button.className).not.toContain('platform-pill');
});