feat: 前端适配后端新接口
适配后端统一模型 ID、协议字段、UUID 自动生成和结构化错误响应: - 类型定义:Provider 新增 protocol 字段,Model 新增 unifiedId,CreateModelInput 移除 id - API 客户端:提取结构化错误响应中的错误码 - 供应商管理:添加协议选择下拉框和表格列 - 模型管理:移除 ID 输入,显示统一模型 ID(只读) - Hooks:错误码映射为友好中文消息 - 测试:所有组件测试通过,mock 数据适配新字段 - 文档:更新 README 说明协议字段和统一模型 ID
This commit is contained in:
@@ -9,6 +9,7 @@ const mockProvider: Provider = {
|
||||
name: 'OpenAI',
|
||||
apiKey: 'sk-old-key',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
protocol: 'openai',
|
||||
enabled: true,
|
||||
createdAt: '2024-01-01T00:00:00Z',
|
||||
updatedAt: '2024-01-01T00:00:00Z',
|
||||
@@ -40,6 +41,7 @@ describe('ProviderForm', () => {
|
||||
expect(within(dialog).getByText('名称')).toBeInTheDocument();
|
||||
expect(within(dialog).getByText('API Key')).toBeInTheDocument();
|
||||
expect(within(dialog).getByText('Base URL')).toBeInTheDocument();
|
||||
expect(within(dialog).getByText('协议')).toBeInTheDocument();
|
||||
expect(within(dialog).getByText('启用')).toBeInTheDocument();
|
||||
expect(within(dialog).getByPlaceholderText('例如: openai')).toBeInTheDocument();
|
||||
expect(within(dialog).getByPlaceholderText('例如: OpenAI')).toBeInTheDocument();
|
||||
@@ -154,4 +156,41 @@ describe('ProviderForm', () => {
|
||||
expect(screen.getByText('请输入有效的 URL')).toBeInTheDocument();
|
||||
});
|
||||
}, 15000);
|
||||
|
||||
it('renders protocol select field with default value', () => {
|
||||
render(<ProviderForm {...defaultProps} />);
|
||||
|
||||
const dialog = getDialog();
|
||||
expect(within(dialog).getByText('协议')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('includes protocol field in form submission', async () => {
|
||||
const onSave = vi.fn();
|
||||
render(<ProviderForm {...defaultProps} onSave={onSave} />);
|
||||
|
||||
const dialog = getDialog();
|
||||
|
||||
// Get form instance and set values directly
|
||||
const idInput = within(dialog).getByPlaceholderText('例如: openai') as HTMLInputElement;
|
||||
const nameInput = within(dialog).getByPlaceholderText('例如: OpenAI') as HTMLInputElement;
|
||||
const apiKeyInput = within(dialog).getByPlaceholderText('sk-...') as HTMLInputElement;
|
||||
const baseUrlInput = within(dialog).getByPlaceholderText('例如: https://api.openai.com/v1') as HTMLInputElement;
|
||||
|
||||
// Simulate user input by directly setting values
|
||||
fireEvent.change(idInput, { target: { value: 'test-provider' } });
|
||||
fireEvent.change(nameInput, { target: { value: 'Test Provider' } });
|
||||
fireEvent.change(apiKeyInput, { target: { value: 'sk-test-key' } });
|
||||
fireEvent.change(baseUrlInput, { target: { value: 'https://api.test.com/v1' } });
|
||||
|
||||
const okButton = within(dialog).getByRole('button', { name: /保/ });
|
||||
fireEvent.click(okButton);
|
||||
|
||||
// Wait for the onSave to be called
|
||||
await vi.waitFor(() => {
|
||||
expect(onSave).toHaveBeenCalled();
|
||||
// Verify that the saved data includes a protocol field
|
||||
const savedData = onSave.mock.calls[0][0];
|
||||
expect(savedData).toHaveProperty('protocol');
|
||||
}, { timeout: 5000 });
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user