import { describe, it, expect, vi } from 'vitest'; import { buildResolvedRegistry } from '../provider-config-registry.js'; import { PROVIDERS } from '../provider-registry.js'; import type { CoderProvidersFile } from '../provider-config.js'; describe('buildResolvedRegistry', () => { it('applies a built-in override (goose label)', () => { const config: CoderProvidersFile = { providers: { goose: { label: 'Goosey' } } }; const reg = buildResolvedRegistry(PROVIDERS, config); const goose = reg.get('goose'); expect(goose).toBeDefined(); expect(goose!.label).toBe('Goosey'); expect(goose!.configLabel).toBe('Goosey'); expect(goose!.enabled).toBe(true); expect(goose!.isBuiltin).toBe(true); expect(goose!.isCustomAcp).toBe(false); }); it('adds a custom ACP entry (extends:acp + label + command)', () => { const config: CoderProvidersFile = { providers: { 'amp-acp': { extends: 'acp', label: 'Amp', description: 'ACP wrapper', command: ['amp-acp', '--acp'], env: { AMP: '1' } }, }, }; const reg = buildResolvedRegistry(PROVIDERS, config); const amp = reg.get('amp-acp'); expect(amp).toBeDefined(); expect(amp!.isCustomAcp).toBe(true); expect(amp!.isBuiltin).toBe(false); expect(amp!.transport).toBe('acp'); expect(amp!.modelSource).toBe('probe'); expect(amp!.launchCommand).toEqual(['amp-acp', '--acp']); expect(amp!.env).toEqual({ AMP: '1' }); expect(amp!.enabled).toBe(true); }); it('keeps a disabled built-in in the registry flagged disabled (goose)', () => { const config: CoderProvidersFile = { providers: { goose: { enabled: false } } }; const reg = buildResolvedRegistry(PROVIDERS, config); expect(reg.has('goose')).toBe(true); expect(reg.get('goose')!.enabled).toBe(false); }); it('skips a custom id without extends (no throw)', () => { const config: CoderProvidersFile = { providers: { weird: { label: 'Weird', command: ['weird'] } } }; const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}); const reg = buildResolvedRegistry(PROVIDERS, config); expect(reg.has('weird')).toBe(false); // built-ins untouched expect(reg.size).toBe(PROVIDERS.length); expect(warn).toHaveBeenCalled(); warn.mockRestore(); }); it('ignores enabled:false on boocode and warns', () => { const config: CoderProvidersFile = { providers: { boocode: { enabled: false } } }; const warn = vi.spyOn(console, 'warn').mockImplementation(() => {}); const reg = buildResolvedRegistry(PROVIDERS, config); expect(reg.get('boocode')!.enabled).toBe(true); expect(warn).toHaveBeenCalled(); warn.mockRestore(); }); it('carries config models + additionalModels onto built-in and custom defs', () => { const reg = buildResolvedRegistry(PROVIDERS, { providers: { claude: { models: [{ id: 'claude-opus-4-8', label: 'Opus 4.8' }] }, 'amp-acp': { extends: 'acp', label: 'Amp', command: ['amp-acp'], additionalModels: [{ id: 'amp-1', label: 'Amp 1' }], }, }, }); expect(reg.get('claude')!.configModels).toEqual([{ id: 'claude-opus-4-8', label: 'Opus 4.8' }]); expect(reg.get('amp-acp')!.configAdditionalModels).toEqual([{ id: 'amp-1', label: 'Amp 1' }]); }); it('REGRESSION: empty config returns exactly the built-ins, all enabled', () => { const reg = buildResolvedRegistry(PROVIDERS, { providers: {} }); expect(reg.size).toBe(PROVIDERS.length); expect([...reg.keys()]).toEqual(PROVIDERS.map((p) => p.name)); for (const def of PROVIDERS) { const r = reg.get(def.name)!; expect(r.enabled).toBe(true); expect(r.isBuiltin).toBe(true); expect(r.isCustomAcp).toBe(false); expect(r.launchCommand).toBeNull(); expect(r.label).toBe(def.label); } }); });