feat(TestDataGenerator): 更新规则编辑提示和警告显示逻辑
- 修改规则编辑时的 toast 提示,确保显示正确的规则名称。 - 更新 ResultPanel 组件,优化警告数量的显示逻辑,确保超过 5 条警告时正确显示剩余警告数量。 - 新增 TestDataGeneratorPage 和 ResultPanel 组件的单元测试,验证功能的正确性。
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
|
vi.mock('../hooks/useGenerator', () => ({
|
||||||
|
useGenerator: () => ({
|
||||||
|
isGenerating: false,
|
||||||
|
progress: null,
|
||||||
|
result: null,
|
||||||
|
error: null,
|
||||||
|
generate: vi.fn(),
|
||||||
|
cancel: vi.fn(),
|
||||||
|
clearResult: vi.fn(),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@/utils/ruleStorage', () => ({
|
||||||
|
MAX_RULES: 20,
|
||||||
|
getAll: vi.fn(() => []),
|
||||||
|
save: vi.fn(),
|
||||||
|
deleteRule: vi.fn(),
|
||||||
|
duplicate: vi.fn(),
|
||||||
|
recordUse: vi.fn(),
|
||||||
|
search: vi.fn(() => []),
|
||||||
|
exportRules: vi.fn(() => '[]'),
|
||||||
|
importRules: vi.fn(() => ({ success: 0, failed: 0, errors: [] })),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('sonner', () => ({
|
||||||
|
toast: {
|
||||||
|
success: vi.fn(),
|
||||||
|
error: vi.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
import TestDataGeneratorPage from '../index';
|
||||||
|
import * as ruleStorage from '@/utils/ruleStorage';
|
||||||
|
import { toast } from 'sonner';
|
||||||
|
import type { DataRule, FieldConfig } from '@/types/testDataGenerator';
|
||||||
|
|
||||||
|
const mockedRuleStorage = vi.mocked(ruleStorage);
|
||||||
|
const mockedToast = vi.mocked(toast);
|
||||||
|
|
||||||
|
const mockFields: FieldConfig[] = [
|
||||||
|
{
|
||||||
|
id: 'field-1',
|
||||||
|
name: 'name',
|
||||||
|
generatorId: 'string',
|
||||||
|
params: {},
|
||||||
|
required: true,
|
||||||
|
nullRate: 0,
|
||||||
|
unique: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const mockRule: DataRule = {
|
||||||
|
id: 'rule-1',
|
||||||
|
name: '用户数据规则',
|
||||||
|
description: '测试规则',
|
||||||
|
fields: mockFields,
|
||||||
|
createdAt: Date.now(),
|
||||||
|
updatedAt: Date.now(),
|
||||||
|
useCount: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('TestDataGeneratorPage', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
mockedRuleStorage.getAll.mockReturnValue([mockRule]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('编辑规则时应显示包含规则名的 toast', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
render(<TestDataGeneratorPage />);
|
||||||
|
|
||||||
|
await user.click(screen.getByText('规则管理'));
|
||||||
|
await user.click(screen.getByTitle('编辑'));
|
||||||
|
|
||||||
|
expect(mockedToast.success).toHaveBeenCalledWith('正在编辑规则「用户数据规则」');
|
||||||
|
expect(mockedToast.success).not.toHaveBeenCalledWith(expect.stringContaining('{{name}}'));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -84,7 +84,9 @@ export default function ResultPanel({ result }: ResultPanelProps) {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
{result.warnings.length > 5 && (
|
{result.warnings.length > 5 && (
|
||||||
<li className="text-xs text-yellow-500/80">... {'还有 {{count}} 条警告'}</li>
|
<li className="text-xs text-yellow-500/80">
|
||||||
|
{`... 还有 ${result.warnings.length - 5} 条警告`}
|
||||||
|
</li>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import ResultPanel from '../ResultPanel';
|
||||||
|
import type { GenerateResult } from '@/types/testDataGenerator';
|
||||||
|
|
||||||
|
function createResult(overrides: Partial<GenerateResult> = {}): GenerateResult {
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
warnings: [],
|
||||||
|
stats: {
|
||||||
|
total: 100,
|
||||||
|
success: 100,
|
||||||
|
failed: 0,
|
||||||
|
duration: 1200,
|
||||||
|
},
|
||||||
|
...overrides,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('ResultPanel', () => {
|
||||||
|
it('警告超过 5 条时应显示剩余警告数量', () => {
|
||||||
|
const warnings = Array.from({ length: 8 }, (_, index) => `警告 ${index + 1}`);
|
||||||
|
|
||||||
|
render(<ResultPanel result={createResult({ warnings })} />);
|
||||||
|
|
||||||
|
expect(screen.getByText('警告 1')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('警告 5')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('警告 6')).not.toBeInTheDocument();
|
||||||
|
expect(screen.getByText('... 还有 3 条警告')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText(/\{\{count\}\}/)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('警告不超过 5 条时不应显示剩余提示', () => {
|
||||||
|
const warnings = ['警告 1', '警告 2', '警告 3'];
|
||||||
|
|
||||||
|
render(<ResultPanel result={createResult({ warnings })} />);
|
||||||
|
|
||||||
|
expect(screen.getByText('警告 1')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('警告 3')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText(/还有 \d+ 条警告/)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -178,6 +178,18 @@ describe('RuleManager', () => {
|
|||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should call onEdit when edit button clicked', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
const onEdit = vi.fn();
|
||||||
|
mockedRuleStorage.getAll.mockReturnValue([mockRule]);
|
||||||
|
|
||||||
|
render(<RuleManager {...defaultProps} onEdit={onEdit} />);
|
||||||
|
|
||||||
|
await user.click(screen.getByTitle('编辑'));
|
||||||
|
|
||||||
|
expect(onEdit).toHaveBeenCalledWith(mockRule);
|
||||||
|
});
|
||||||
|
|
||||||
it('should show saved rule count', () => {
|
it('should show saved rule count', () => {
|
||||||
mockedRuleStorage.getAll.mockReturnValue([mockRule]);
|
mockedRuleStorage.getAll.mockReturnValue([mockRule]);
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export default function TestDataGeneratorPage() {
|
|||||||
setEditingRule(rule);
|
setEditingRule(rule);
|
||||||
setActiveTab('fields');
|
setActiveTab('fields');
|
||||||
clearResult();
|
clearResult();
|
||||||
toast.success('正在编辑规则「{{name}}」');
|
toast.success(`正在编辑规则「${rule.name}」`);
|
||||||
},
|
},
|
||||||
[clearResult],
|
[clearResult],
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user