cc-haha/src/utils/managedEnv.test.ts
2026-07-14 21:22:20 +08:00

108 lines
3.7 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
import * as fs from 'fs/promises'
import * as os from 'os'
import * as path from 'path'
import { applySafeConfigEnvironmentVariables } from './managedEnv.js'
let tmpDir: string
const originalEnv = {
CLAUDE_CONFIG_DIR: process.env.CLAUDE_CONFIG_DIR,
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: process.env.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST,
CC_HAHA_LOCAL_ACCESS_TOKEN: process.env.CC_HAHA_LOCAL_ACCESS_TOKEN,
ANTHROPIC_BASE_URL: process.env.ANTHROPIC_BASE_URL,
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
ANTHROPIC_AUTH_TOKEN: process.env.ANTHROPIC_AUTH_TOKEN,
ANTHROPIC_MODEL: process.env.ANTHROPIC_MODEL,
}
function restoreEnv(key: keyof typeof originalEnv): void {
const value = originalEnv[key]
if (value === undefined) {
delete process.env[key]
} else {
process.env[key] = value
}
}
async function writeJson(filePath: string, value: unknown): Promise<void> {
await fs.mkdir(path.dirname(filePath), { recursive: true })
await fs.writeFile(filePath, JSON.stringify(value, null, 2), 'utf-8')
}
describe('managedEnv', () => {
beforeEach(async () => {
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'managed-env-'))
process.env.CLAUDE_CONFIG_DIR = tmpDir
delete process.env.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST
delete process.env.CC_HAHA_LOCAL_ACCESS_TOKEN
delete process.env.ANTHROPIC_BASE_URL
delete process.env.ANTHROPIC_API_KEY
delete process.env.ANTHROPIC_AUTH_TOKEN
delete process.env.ANTHROPIC_MODEL
})
afterEach(async () => {
await import('../server/proxy/standaloneProviderProxy.js')
.then((mod) => mod.stopStandaloneProviderProxyForTests?.())
.catch(() => {})
await fs.rm(tmpDir, { recursive: true, force: true })
restoreEnv('CLAUDE_CONFIG_DIR')
restoreEnv('CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST')
restoreEnv('CC_HAHA_LOCAL_ACCESS_TOKEN')
restoreEnv('ANTHROPIC_BASE_URL')
restoreEnv('ANTHROPIC_API_KEY')
restoreEnv('ANTHROPIC_AUTH_TOKEN')
restoreEnv('ANTHROPIC_MODEL')
})
test('starts a standalone provider proxy for CLI-only OpenAI-compatible providers', async () => {
await writeJson(path.join(tmpDir, 'cc-haha', 'providers.json'), {
activeId: 'agnes-provider',
providers: [
{
id: 'agnes-provider',
presetId: 'custom',
name: 'Agnes',
apiKey: 'sk-agnes',
authStrategy: 'api_key',
baseUrl: 'https://apihub.agnes-ai.com',
apiFormat: 'openai_chat',
models: {
main: 'agnes-2.0-flash',
haiku: 'agnes-2.0-flash',
sonnet: 'agnes-2.0-flash',
opus: 'agnes-2.0-flash',
},
},
],
})
applySafeConfigEnvironmentVariables()
const baseUrl = new URL(process.env.ANTHROPIC_BASE_URL!)
expect(baseUrl.hostname).toBe('127.0.0.1')
expect(baseUrl.port).not.toBe('3456')
expect(baseUrl.pathname).toBe('/proxy')
const health = await fetch(new URL('/health', baseUrl.origin))
expect(health.status).toBe(200)
})
test('does not let settings replace host-owned provider routing credentials', async () => {
await writeJson(path.join(tmpDir, 'cc-haha', 'settings.json'), {
env: {
CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST: '0',
CC_HAHA_LOCAL_ACCESS_TOKEN: 'stale-settings-token',
},
})
process.env.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST = '1'
process.env.CC_HAHA_LOCAL_ACCESS_TOKEN = 'desktop-local-secret'
applySafeConfigEnvironmentVariables()
expect(process.env.CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST).toBe('1')
expect(process.env.CC_HAHA_LOCAL_ACCESS_TOKEN).toBe('desktop-local-secret')
})
})