import { afterEach, describe, expect, it, vi } from 'vitest' import { discoverProviderModels } from '../../packages/server/src/services/hermes/provider-model-discovery' afterEach(() => vi.unstubAllGlobals()) describe('live provider model discovery', () => { it('uses Anthropic authentication and collects every page before returning the catalog', async () => { const fetch = vi.fn() .mockResolvedValueOnce({ ok: true, json: async () => ({ data: [{ id: 'MiniMax-M3' }], has_more: true, last_id: 'MiniMax-M3' }) }) .mockResolvedValueOnce({ ok: true, json: async () => ({ data: [{ id: 'MiniMax-M2.7' }], has_more: false }) }) vi.stubGlobal('fetch', fetch) await expect(discoverProviderModels('https://proxy.invalid/anthropic/v1/', 'test-key', true)).resolves.toEqual(['MiniMax-M2.7', 'MiniMax-M3']) expect(fetch).toHaveBeenNthCalledWith(1, 'https://proxy.invalid/anthropic/v1/models', expect.objectContaining({ headers: { 'x-api-key': 'test-key', 'anthropic-version': '2023-06-01' }, })) expect(fetch.mock.calls[1][0]).toContain('after_id=MiniMax-M3') }) it('uses Bearer authentication for OpenAI-compatible endpoints and normalizes model IDs', async () => { const fetch = vi.fn().mockResolvedValue({ ok: true, json: async () => ({ data: [{ id: 'b' }, { id: '' }, { id: 'a' }, { id: 'b' }] }) }) vi.stubGlobal('fetch', fetch) await expect(discoverProviderModels('https://proxy.invalid', 'test-key')).resolves.toEqual(['a', 'b']) expect(fetch).toHaveBeenCalledWith('https://proxy.invalid/v1/models', expect.objectContaining({ headers: { Authorization: 'Bearer test-key' } })) }) it('rejects a failed later page instead of returning a partial list', async () => { vi.stubGlobal('fetch', vi.fn() .mockResolvedValueOnce({ ok: true, json: async () => ({ data: [{ id: 'first' }], has_more: true, last_id: 'first' }) }) .mockResolvedValueOnce({ ok: false, status: 503 })) await expect(discoverProviderModels('https://proxy.invalid/v1', 'test-key', true)).rejects.toThrow('HTTP 503') }) it('rejects a repeated cursor instead of looping', async () => { const fetch = vi.fn().mockResolvedValue({ ok: true, json: async () => ({ data: [{ id: 'first' }], has_more: true, last_id: 'first' }) }) vi.stubGlobal('fetch', fetch) await expect(discoverProviderModels('https://proxy.invalid/v1', 'test-key', true)).rejects.toThrow('invalid model pagination') expect(fetch).toHaveBeenCalledTimes(2) }) })