import { afterEach, expect, test } from 'bun:test' import { getProviderValidationError } from './providerValidation.ts' const originalEnv = { CLAUDE_CODE_USE_OPENAI: process.env.CLAUDE_CODE_USE_OPENAI, OPENAI_API_KEY: process.env.OPENAI_API_KEY, OPENAI_BASE_URL: process.env.OPENAI_BASE_URL, CLAUDE_CODE_USE_GEMINI: process.env.CLAUDE_CODE_USE_GEMINI, GEMINI_API_KEY: process.env.GEMINI_API_KEY, GOOGLE_API_KEY: process.env.GOOGLE_API_KEY, GEMINI_ACCESS_TOKEN: process.env.GEMINI_ACCESS_TOKEN, GEMINI_AUTH_MODE: process.env.GEMINI_AUTH_MODE, GOOGLE_APPLICATION_CREDENTIALS: process.env.GOOGLE_APPLICATION_CREDENTIALS, } function restoreEnv(key: string, value: string | undefined): void { if (value === undefined) { delete process.env[key] } else { process.env[key] = value } } afterEach(() => { restoreEnv('CLAUDE_CODE_USE_OPENAI', originalEnv.CLAUDE_CODE_USE_OPENAI) restoreEnv('OPENAI_API_KEY', originalEnv.OPENAI_API_KEY) restoreEnv('OPENAI_BASE_URL', originalEnv.OPENAI_BASE_URL) restoreEnv('CLAUDE_CODE_USE_GEMINI', originalEnv.CLAUDE_CODE_USE_GEMINI) restoreEnv('GEMINI_API_KEY', originalEnv.GEMINI_API_KEY) restoreEnv('GOOGLE_API_KEY', originalEnv.GOOGLE_API_KEY) restoreEnv('GEMINI_ACCESS_TOKEN', originalEnv.GEMINI_ACCESS_TOKEN) restoreEnv('GEMINI_AUTH_MODE', originalEnv.GEMINI_AUTH_MODE) restoreEnv( 'GOOGLE_APPLICATION_CREDENTIALS', originalEnv.GOOGLE_APPLICATION_CREDENTIALS, ) }) test('accepts GEMINI_ACCESS_TOKEN as valid Gemini auth', async () => { process.env.CLAUDE_CODE_USE_GEMINI = '1' process.env.GEMINI_AUTH_MODE = 'access-token' delete process.env.GEMINI_API_KEY delete process.env.GOOGLE_API_KEY process.env.GEMINI_ACCESS_TOKEN = 'token-123' await expect(getProviderValidationError(process.env)).resolves.toBeNull() }) test('accepts ADC credentials for Gemini auth', async () => { process.env.CLAUDE_CODE_USE_GEMINI = '1' process.env.GEMINI_AUTH_MODE = 'adc' delete process.env.GEMINI_API_KEY delete process.env.GOOGLE_API_KEY delete process.env.GEMINI_ACCESS_TOKEN await expect( getProviderValidationError(process.env, { resolveGeminiCredential: async () => ({ kind: 'adc', credential: 'adc-token', projectId: 'adc-project', }), }), ).resolves.toBeNull() }) test('still errors when no Gemini credential source is available', async () => { process.env.CLAUDE_CODE_USE_GEMINI = '1' process.env.GEMINI_AUTH_MODE = 'access-token' delete process.env.GEMINI_API_KEY delete process.env.GOOGLE_API_KEY delete process.env.GEMINI_ACCESS_TOKEN delete process.env.GOOGLE_APPLICATION_CREDENTIALS await expect(getProviderValidationError(process.env)).resolves.toBe( 'GEMINI_API_KEY, GOOGLE_API_KEY, GEMINI_ACCESS_TOKEN, or Google ADC credentials are required when CLAUDE_CODE_USE_GEMINI=1.', ) }) test('openai missing key error includes recovery guidance and config locations', async () => { process.env.CLAUDE_CODE_USE_OPENAI = '1' process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' delete process.env.OPENAI_API_KEY const message = await getProviderValidationError(process.env) expect(message).toContain( 'OPENAI_API_KEY is required when CLAUDE_CODE_USE_OPENAI=1 and OPENAI_BASE_URL is not local.', ) expect(message).toContain( 'set CLAUDE_CODE_USE_OPENAI=0 in your shell environment', ) expect(message).toContain('Saved startup settings can come from') expect(message).toContain('.openclaude-profile.json') })