Treat boolean and numeric auth.json provider entries as unusable credentials while preserving non-empty string, array, and object entries. Extend pi-config tests for empty arrays and primitive malformed entries. --- Build: pass Tests: pass — 2210 passed (166 files) --- Build: pass | Tests: pass — 2210 passed (654 files)
193 lines
4.5 KiB
TypeScript
193 lines
4.5 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
import { resolvePiProviderCredentials } from './pi-config.js';
|
|
|
|
let tmpDir: string;
|
|
let authFile: string;
|
|
|
|
beforeEach(() => {
|
|
const base = path.resolve(process.cwd(), 'tmp');
|
|
fs.mkdirSync(base, { recursive: true });
|
|
tmpDir = fs.mkdtempSync(path.join(base, 'pi-config-test-'));
|
|
authFile = path.join(tmpDir, 'auth.json');
|
|
});
|
|
|
|
afterEach(() => {
|
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
});
|
|
|
|
describe('resolvePiProviderCredentials', () => {
|
|
it('accepts openai-codex OAuth auth from auth.json', () => {
|
|
fs.writeFileSync(
|
|
authFile,
|
|
JSON.stringify({ 'openai-codex': { type: 'oauth', accessToken: 'x' } }),
|
|
'utf-8',
|
|
);
|
|
|
|
const result = resolvePiProviderCredentials({
|
|
provider: 'openai-codex',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
hasCredential: true,
|
|
source: 'auth_file',
|
|
keyVar: null,
|
|
});
|
|
});
|
|
|
|
it('accepts API-key providers from auth.json too', () => {
|
|
fs.writeFileSync(
|
|
authFile,
|
|
JSON.stringify({ openrouter: { type: 'api_key', key: 'sk-or-test' } }),
|
|
'utf-8',
|
|
);
|
|
|
|
const result = resolvePiProviderCredentials({
|
|
provider: 'openrouter',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
hasCredential: true,
|
|
source: 'auth_file',
|
|
keyVar: 'OPENROUTER_API_KEY',
|
|
});
|
|
});
|
|
|
|
it('falls back to env vars when auth.json is absent', () => {
|
|
const result = resolvePiProviderCredentials({
|
|
provider: 'openai',
|
|
envContent: 'OPENAI_API_KEY=sk-test\n',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
hasCredential: true,
|
|
source: 'env',
|
|
keyVar: 'OPENAI_API_KEY',
|
|
});
|
|
});
|
|
|
|
it('ignores unusable auth.json provider entries', () => {
|
|
fs.writeFileSync(
|
|
authFile,
|
|
JSON.stringify({
|
|
'openai-codex': {},
|
|
openrouter: null,
|
|
zai: '',
|
|
anthropic: [],
|
|
openai: true,
|
|
gemini: 42,
|
|
}),
|
|
'utf-8',
|
|
);
|
|
|
|
const codex = resolvePiProviderCredentials({
|
|
provider: 'openai-codex',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
const openrouter = resolvePiProviderCredentials({
|
|
provider: 'openrouter',
|
|
envContent: 'OPENROUTER_API_KEY=sk-or-test\n',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
const zai = resolvePiProviderCredentials({
|
|
provider: 'zai',
|
|
envContent: '',
|
|
processEnv: { ZAI_API_KEY: 'zai-test' },
|
|
authFile,
|
|
});
|
|
const anthropic = resolvePiProviderCredentials({
|
|
provider: 'anthropic',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
const openai = resolvePiProviderCredentials({
|
|
provider: 'openai',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
const gemini = resolvePiProviderCredentials({
|
|
provider: 'gemini',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
|
|
expect(codex).toEqual({
|
|
hasCredential: false,
|
|
source: 'none',
|
|
keyVar: null,
|
|
});
|
|
expect(openrouter).toEqual({
|
|
hasCredential: true,
|
|
source: 'env',
|
|
keyVar: 'OPENROUTER_API_KEY',
|
|
});
|
|
expect(zai).toEqual({
|
|
hasCredential: true,
|
|
source: 'env',
|
|
keyVar: 'ZAI_API_KEY',
|
|
});
|
|
expect(anthropic).toEqual({
|
|
hasCredential: false,
|
|
source: 'none',
|
|
keyVar: 'ANTHROPIC_API_KEY',
|
|
});
|
|
expect(openai).toEqual({
|
|
hasCredential: false,
|
|
source: 'none',
|
|
keyVar: 'OPENAI_API_KEY',
|
|
});
|
|
expect(gemini).toEqual({
|
|
hasCredential: false,
|
|
source: 'none',
|
|
keyVar: 'GEMINI_API_KEY',
|
|
});
|
|
});
|
|
|
|
it('checks OLLAMA_HOST for ollama providers', () => {
|
|
const result = resolvePiProviderCredentials({
|
|
provider: 'ollama',
|
|
envContent: 'OLLAMA_HOST=http://127.0.0.1:11434\n',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
hasCredential: true,
|
|
source: 'ollama_host',
|
|
keyVar: null,
|
|
});
|
|
});
|
|
|
|
it('treats malformed auth.json as missing and does not throw', () => {
|
|
fs.writeFileSync(authFile, '{not-json', 'utf-8');
|
|
|
|
const result = resolvePiProviderCredentials({
|
|
provider: 'openai-codex',
|
|
envContent: '',
|
|
processEnv: {},
|
|
authFile,
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
hasCredential: false,
|
|
source: 'none',
|
|
keyVar: null,
|
|
});
|
|
});
|
|
});
|