[codex] add vendor code entry presets follow-up (#363)

* address coding plan review comments

* add more vendor code entry presets
This commit is contained in:
Cita
2026-04-01 13:57:24 +08:00
committed by GitHub
parent 3ebe851002
commit aac1307470
8 changed files with 543 additions and 28 deletions
+2 -1
View File
@@ -28,6 +28,7 @@ import {
type SiteForm,
} from './helpers/sitesEditor.js';
import {
detectSiteInitializationPreset,
getSiteInitializationPreset,
listSiteInitializationPresets,
} from '../../shared/siteInitializationPresets.js';
@@ -388,7 +389,7 @@ export default function Sites() {
const openEdit = (site: SiteRow) => {
setEditor({ mode: 'edit', editingSiteId: site.id });
setForm(siteFormFromSite(site));
setSelectedInitializationPresetId(null);
setSelectedInitializationPresetId(detectSiteInitializationPreset(site.url, site.platform)?.id || null);
scrollToEditorTop();
// Load disabled models and discovered models independently so a best-effort
// availability fetch cannot wipe the existing disabled-model state.
@@ -113,4 +113,67 @@ describe('Accounts CodingPlan initialization', () => {
root?.unmount();
}
});
it('preloads vendor-specific recommendations for new code presets such as DeepSeek', async () => {
apiMock.getSites.mockResolvedValue([
{ id: 11, name: 'DeepSeek Official', url: 'https://api.deepseek.com/v1', platform: 'openai', status: 'active' },
]);
apiMock.addAccount.mockResolvedValue({
id: 19,
siteId: 11,
tokenType: 'apikey',
queued: false,
});
let root!: ReactTestRenderer;
try {
await act(async () => {
root = create(
<MemoryRouter initialEntries={['/accounts?segment=apikey&create=1&siteId=11&initPreset=deepseek-openai']}>
<ToastProvider>
<Accounts />
</ToastProvider>
</MemoryRouter>,
);
});
await flushMicrotasks();
const rendered = JSON.stringify(root.toJSON());
expect(rendered).toContain('DeepSeek / OpenAI');
expect(rendered).toContain('deepseek-chat');
expect(rendered).toContain('deepseek-reasoner');
const tokenInput = root.root.find((node) => (
node.type === 'textarea'
&& node.props.placeholder === '粘贴 API Key'
));
const addButton = root.root.find((node) => (
node.type === 'button'
&& typeof node.props.onClick === 'function'
&& collectText(node).includes('添加连接')
));
await act(async () => {
tokenInput.props.onChange({ target: { value: 'sk-deepseek-demo' } });
});
await act(async () => {
await addButton.props.onClick();
});
await flushMicrotasks();
expect(apiMock.addAccount).toHaveBeenCalledWith(expect.objectContaining({
siteId: 11,
accessToken: 'sk-deepseek-demo',
credentialMode: 'apikey',
skipModelFetch: true,
}));
expect(apiMock.addAccountAvailableModels).toHaveBeenCalledWith(
19,
['deepseek-chat', 'deepseek-reasoner'],
);
} finally {
root?.unmount();
}
});
});
@@ -219,6 +219,15 @@ describe('Sites create redirect', () => {
expect.objectContaining({ label: '阿里云 CodingPlan / Claude' }),
expect.objectContaining({ label: '智谱 Coding Plan / OpenAI' }),
expect.objectContaining({ label: '智谱 Coding Plan / Claude' }),
expect.objectContaining({ label: 'DeepSeek / OpenAI' }),
expect.objectContaining({ label: 'DeepSeek / Claude' }),
expect.objectContaining({ label: 'Moonshot(Kimi) / OpenAI' }),
expect.objectContaining({ label: 'Moonshot(Kimi) / Claude' }),
expect.objectContaining({ label: 'MiniMax / OpenAI' }),
expect.objectContaining({ label: 'MiniMax / Claude' }),
expect.objectContaining({ label: 'ModelScope / OpenAI' }),
expect.objectContaining({ label: 'ModelScope / Claude' }),
expect.objectContaining({ label: '豆包 Coding Plan / OpenAI' }),
]),
);
} finally {
@@ -554,4 +563,54 @@ describe('Sites create redirect', () => {
root.unmount();
});
it('re-selects the matching vendor preset when editing an existing vendor-specific site', async () => {
apiMock.getSites.mockResolvedValue([
{
id: 36,
name: 'DeepSeek Official',
url: 'https://api.deepseek.com/v1',
platform: 'openai',
status: 'active',
},
]);
let root!: ReactTestRenderer;
try {
await act(async () => {
root = create(
<ToastProvider>
<MemoryRouter initialEntries={['/sites']}>
<Routes>
<Route path="/sites" element={<Sites />} />
</Routes>
</MemoryRouter>
</ToastProvider>,
);
});
await flushMicrotasks();
const editButton = root.root.find((node) => (
node.type === 'button'
&& typeof node.props.onClick === 'function'
&& collectText(node).includes('编辑')
));
await act(async () => {
editButton.props.onClick();
});
await flushMicrotasks();
const platformSelect = root.root.findAllByType(ModernSelect).at(-1);
const presetAlert = root.root.find((node) => (
typeof node.props.className === 'string'
&& node.props.className.includes('alert alert-info')
));
expect(platformSelect?.props.value).toBe('preset:deepseek-openai');
expect(collectText(presetAlert)).toContain('已应用官方预设');
expect(collectText(presetAlert)).toContain('DeepSeek / OpenAI');
} finally {
root?.unmount();
}
});
});