import { beforeEach, describe, expect, it, vi } from 'vitest' const openAIState = vi.hoisted(() => ({ create: vi.fn(async () => ({ choices: [{ message: { content: 'pong' } }], })), })) const fetchMock = vi.hoisted(() => vi.fn(async () => new Response('not-found', { status: 404 })), ) vi.mock('openai', () => ({ default: class OpenAI { chat = { completions: { create: openAIState.create, }, } }, })) import { testProviderConnection } from '@/lib/user-api/provider-test' describe('provider test connection compatible probes', () => { beforeEach(() => { vi.clearAllMocks() vi.stubGlobal('fetch', fetchMock) }) it('asks user to configure llm when free probes are unsupported', async () => { const result = await testProviderConnection({ apiType: 'openai-compatible', baseUrl: 'https://compat.example.com/v1', apiKey: 'compat-key', }) expect(result.success).toBe(false) expect(result.steps[0]?.name).toBe('models') expect(result.steps[0]?.status).toBe('skip') expect(result.steps[1]?.name).toBe('credits') expect(result.steps[1]?.status).toBe('skip') expect(result.steps[2]).toEqual({ name: 'textGen', status: 'fail', message: 'No free probe endpoint detected. Please configure an LLM model first, then retry / 未发现可用的免费探测接口,请先配置 LLM 模型后再测试', }) }) it('falls back to configured llm test when free probes are unsupported', async () => { const result = await testProviderConnection({ apiType: 'openai-compatible', baseUrl: 'https://compat.example.com/v1', apiKey: 'compat-key', llmModel: 'gpt-4.1-mini', }) expect(result.success).toBe(true) expect(result.steps[0]?.status).toBe('skip') expect(result.steps[1]?.status).toBe('skip') expect(result.steps[2]).toEqual({ name: 'textGen', status: 'pass', model: 'gpt-4.1-mini', message: 'Response: pong', }) expect(openAIState.create).toHaveBeenCalledWith({ model: 'gpt-4.1-mini', messages: [{ role: 'user', content: 'hi' }], max_tokens: 20, temperature: 0, }) }) it('marks success when any free probe endpoint passes', async () => { fetchMock.mockImplementation(async (input: RequestInfo | URL) => { const url = String(input) if (url.endsWith('/v1/models')) { return new Response(JSON.stringify({ data: [{ id: 'm1' }, { id: 'm2' }] }), { status: 200 }) } return new Response('not-found', { status: 404 }) }) const result = await testProviderConnection({ apiType: 'gemini-compatible', baseUrl: 'https://compat.example.com', apiKey: 'compat-key', }) expect(result.success).toBe(true) expect(result.steps[0]).toMatchObject({ name: 'models', status: 'pass', message: 'Found 2 models', }) expect(result.steps[1]?.name).toBe('credits') expect(result.steps[1]?.status).toBe('skip') expect(result.steps.length).toBe(2) }) })