// @vitest-environment jsdom import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import { afterEach, describe, expect, it, vi } from 'vitest' import type { ModelTarget } from '@deepseek-ai/dsh-client-connection/client' import { createSnapshotStore } from '@deepseek-ai/dsh-client-runtime/client' import type { ModelDirectoryState } from '../src/client/directory.ts' import { ModelSelect } from '../src/client/ModelSelect.tsx' const reasoning = { efforts: [ { id: 'off', name: 'Off' }, { id: 'high', name: 'High' }, { id: 'max', name: 'Max', description: 'Largest budget' }, ], defaultEffort: 'high', } function state(overrides: Partial = {}): ModelDirectoryState { return { current: { provider: 'deepseek', model: 'deepseek-v4-flash' }, groups: [{ id: 'deepseek', name: 'DeepSeek', models: [{ id: 'deepseek-v4-flash', name: 'DeepSeek-V4-Flash', reasoning }], }], failures: [], status: 'ready', error: null, ...overrides, } } afterEach(cleanup) describe('ModelSelect reasoning effort', () => { it('renders adapter metadata and submits the effort as part of the session target', async () => { const directory = createSnapshotStore(state()) const select = vi.fn(async (target: ModelTarget) => { directory.update((snapshot) => { snapshot.current = target }) return true }) render() const trigger = screen.getByRole('button', { name: '选择模型,当前 DeepSeek-V4-Flash,推理等级 High', }) fireEvent.click(trigger) fireEvent.click(screen.getByRole('menuitem', { name: /Effort/ })) expect(screen.getAllByRole('menuitemradio').map(item => item.textContent)) .toEqual(['Off', 'High', 'MaxLargest budget']) fireEvent.click(screen.getByRole('menuitemradio', { name: /Max/ })) await waitFor(() => { expect(select).toHaveBeenCalledWith({ provider: 'deepseek', model: 'deepseek-v4-flash', reasoningEffort: 'max', }) expect(trigger.getAttribute('aria-label')).toBe('选择模型,当前 DeepSeek-V4-Flash,推理等级 Max') }) }) it('offers provider default only when the adapter does not configure a model default', () => { const directory = createSnapshotStore(state({ groups: [{ id: 'provider', name: 'Provider', models: [{ id: 'model', name: 'Model', reasoning: { efforts: [{ id: 'standard', name: 'Standard' }] }, }], }], current: { provider: 'provider', model: 'model' }, })) render() fireEvent.click(screen.getByRole('button', { name: '选择模型,当前 Model,推理等级 Provider default', })) fireEvent.click(screen.getByRole('menuitem', { name: /Effort/ })) expect(screen.getAllByRole('menuitemradio').map(item => item.textContent)) .toEqual(['Provider default', 'Standard']) }) })