mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
118 lines
3.9 KiB
TypeScript
118 lines
3.9 KiB
TypeScript
import { afterEach, describe, expect, it } from 'bun:test';
|
|
import * as fs from 'fs';
|
|
import * as os from 'os';
|
|
import * as path from 'path';
|
|
|
|
import { ClaudeSettingsChecker } from '../../../../src/management/checks/config-check';
|
|
import { HealthCheck } from '../../../../src/management/checks/types';
|
|
import { runWithScopedCcsHome } from '../../../../src/utils/config-manager';
|
|
|
|
let originalClaudeConfigDir: string | undefined;
|
|
|
|
afterEach(() => {
|
|
if (originalClaudeConfigDir === undefined) {
|
|
delete process.env.CLAUDE_CONFIG_DIR;
|
|
} else {
|
|
process.env.CLAUDE_CONFIG_DIR = originalClaudeConfigDir;
|
|
}
|
|
});
|
|
|
|
describe('ClaudeSettingsChecker', () => {
|
|
it('warns when Claude settings point at the Codex CLIProxy translator', async () => {
|
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-config-check-'));
|
|
originalClaudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
|
|
delete process.env.CLAUDE_CONFIG_DIR;
|
|
|
|
try {
|
|
await runWithScopedCcsHome(tempRoot, async () => {
|
|
const settingsPath = path.join(tempRoot, '.claude', 'settings.json');
|
|
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
fs.writeFileSync(
|
|
settingsPath,
|
|
JSON.stringify(
|
|
{
|
|
env: {
|
|
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317/api/provider/codex',
|
|
},
|
|
},
|
|
null,
|
|
2
|
|
) + '\n'
|
|
);
|
|
|
|
const originalConsoleLog = console.log;
|
|
console.log = () => {};
|
|
try {
|
|
const results = new HealthCheck();
|
|
new ClaudeSettingsChecker().run(results);
|
|
|
|
expect(results.warnings).toHaveLength(1);
|
|
expect(results.warnings[0].message).toContain('Codex CLIProxy translator');
|
|
expect(results.warnings[0].fix).toContain('ccs persist default --yes');
|
|
} finally {
|
|
console.log = originalConsoleLog;
|
|
}
|
|
});
|
|
} finally {
|
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it('warns with safe path-level evidence for nested Codex translator settings', async () => {
|
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-config-check-'));
|
|
originalClaudeConfigDir = process.env.CLAUDE_CONFIG_DIR;
|
|
delete process.env.CLAUDE_CONFIG_DIR;
|
|
|
|
try {
|
|
await runWithScopedCcsHome(tempRoot, async () => {
|
|
const staleUrl = 'https://proxy.example.com/api/provider/codex/v1/messages';
|
|
const settingsPath = path.join(tempRoot, '.claude', 'settings.json');
|
|
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
fs.writeFileSync(
|
|
settingsPath,
|
|
JSON.stringify(
|
|
{
|
|
env: {
|
|
KEEP_ME: 'safe',
|
|
},
|
|
hooks: {
|
|
PostToolUse: [
|
|
{
|
|
config: {
|
|
endpoint: staleUrl,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
null,
|
|
2
|
|
) + '\n'
|
|
);
|
|
|
|
const originalConsoleLog = console.log;
|
|
const capturedLogs: string[] = [];
|
|
console.log = (...args: unknown[]) => {
|
|
capturedLogs.push(args.map((arg) => String(arg)).join(' '));
|
|
};
|
|
try {
|
|
const results = new HealthCheck();
|
|
new ClaudeSettingsChecker().run(results);
|
|
|
|
expect(results.warnings).toHaveLength(1);
|
|
expect(results.warnings[0].message).toContain(
|
|
'hooks.PostToolUse[0].config.endpoint'
|
|
);
|
|
expect(results.warnings[0].message).not.toContain(staleUrl);
|
|
expect(capturedLogs.join('\n')).toContain('hooks.PostToolUse[0].config.endpoint');
|
|
expect(capturedLogs.join('\n')).not.toContain(staleUrl);
|
|
} finally {
|
|
console.log = originalConsoleLog;
|
|
}
|
|
});
|
|
} finally {
|
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|