- 供应商/模型/统计表格增加列宽约束和 ellipsis 省略号 - 修复主题切换按钮在暗色侧边栏中不可见 - 表格添加 scroll 属性防止窄屏溢出 - 自定义表格空状态提示文案
125 lines
3.8 KiB
TypeScript
125 lines
3.8 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
import { StatsTable } from '@/pages/Stats/StatsTable';
|
|
import type { Provider, UsageStats } from '@/types';
|
|
|
|
const mockProviders: Provider[] = [
|
|
{
|
|
id: 'openai',
|
|
name: 'OpenAI',
|
|
apiKey: 'sk-test',
|
|
baseUrl: 'https://api.openai.com/v1',
|
|
enabled: true,
|
|
createdAt: '2024-01-01T00:00:00Z',
|
|
updatedAt: '2024-01-01T00:00:00Z',
|
|
},
|
|
{
|
|
id: 'anthropic',
|
|
name: 'Anthropic',
|
|
apiKey: 'sk-ant-test',
|
|
baseUrl: 'https://api.anthropic.com',
|
|
enabled: true,
|
|
createdAt: '2024-01-02T00:00:00Z',
|
|
updatedAt: '2024-01-02T00:00:00Z',
|
|
},
|
|
];
|
|
|
|
const mockStats: UsageStats[] = [
|
|
{
|
|
id: '1',
|
|
providerId: 'openai',
|
|
modelName: 'gpt-4o',
|
|
requestCount: 100,
|
|
date: '2024-01-15',
|
|
},
|
|
{
|
|
id: '2',
|
|
providerId: 'anthropic',
|
|
modelName: 'claude-3-opus',
|
|
requestCount: 50,
|
|
date: '2024-01-15',
|
|
},
|
|
];
|
|
|
|
const defaultProps = {
|
|
providers: mockProviders,
|
|
stats: mockStats,
|
|
loading: false,
|
|
providerId: undefined,
|
|
modelName: undefined,
|
|
dateRange: null,
|
|
onProviderIdChange: vi.fn(),
|
|
onModelNameChange: vi.fn(),
|
|
onDateRangeChange: vi.fn(),
|
|
};
|
|
|
|
describe('StatsTable', () => {
|
|
it('renders stats table with data', () => {
|
|
render(<StatsTable {...defaultProps} />);
|
|
|
|
expect(screen.getByText('gpt-4o')).toBeInTheDocument();
|
|
expect(screen.getByText('claude-3-opus')).toBeInTheDocument();
|
|
const dateCells = screen.getAllByText('2024-01-15');
|
|
expect(dateCells.length).toBe(2);
|
|
expect(screen.getByText('100')).toBeInTheDocument();
|
|
expect(screen.getByText('50')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows provider name from providers prop instead of providerId', () => {
|
|
render(<StatsTable {...defaultProps} />);
|
|
|
|
expect(screen.getByText('OpenAI')).toBeInTheDocument();
|
|
const allAnthropic = screen.getAllByText('Anthropic');
|
|
expect(allAnthropic.length).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it('renders filter controls with Select, Input, and DatePicker', () => {
|
|
render(<StatsTable {...defaultProps} />);
|
|
|
|
const selects = document.querySelectorAll('.ant-select');
|
|
expect(selects.length).toBeGreaterThanOrEqual(1);
|
|
|
|
const modelInput = screen.getByPlaceholderText('模型名称');
|
|
expect(modelInput).toBeInTheDocument();
|
|
|
|
expect(screen.getByText('所有供应商')).toBeInTheDocument();
|
|
|
|
const rangePicker = document.querySelector('.ant-picker-range');
|
|
expect(rangePicker).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders table headers correctly', () => {
|
|
render(<StatsTable {...defaultProps} />);
|
|
|
|
expect(screen.getAllByText('供应商').length).toBeGreaterThanOrEqual(1);
|
|
expect(screen.getAllByText('模型').length).toBeGreaterThanOrEqual(1);
|
|
expect(screen.getAllByText('日期').length).toBeGreaterThanOrEqual(1);
|
|
expect(screen.getAllByText('请求数').length).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it('falls back to providerId when provider not found in providers prop', () => {
|
|
const limitedProviders = [mockProviders[0]];
|
|
render(<StatsTable {...defaultProps} providers={limitedProviders} />);
|
|
|
|
expect(screen.getByText('OpenAI')).toBeInTheDocument();
|
|
expect(screen.getByText('anthropic')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders with empty stats data', () => {
|
|
render(<StatsTable {...defaultProps} stats={[]} />);
|
|
|
|
expect(screen.getAllByText('供应商').length).toBeGreaterThanOrEqual(1);
|
|
expect(screen.getAllByText('模型').length).toBeGreaterThanOrEqual(1);
|
|
});
|
|
|
|
it('shows loading state', () => {
|
|
render(<StatsTable {...defaultProps} loading={true} />);
|
|
expect(document.querySelector('.ant-spin')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows custom empty text when stats data is empty', () => {
|
|
render(<StatsTable {...defaultProps} stats={[]} />);
|
|
expect(screen.getByText('暂无统计数据')).toBeInTheDocument();
|
|
});
|
|
});
|