mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 02:11:28 +00:00
fix(image-analysis): reject unknown backend mappings
This commit is contained in:
@@ -40,6 +40,13 @@ const IMAGE_ANALYSIS_PROVIDER_ALIASES = Object.freeze(
|
||||
)
|
||||
);
|
||||
|
||||
function isConfiguredImageAnalysisBackend(
|
||||
backend: string | null,
|
||||
providerModels: Record<string, string>
|
||||
): backend is string {
|
||||
return Boolean(backend && Object.prototype.hasOwnProperty.call(providerModels, backend));
|
||||
}
|
||||
|
||||
function parseArgs(args: string[]): ImageAnalysisCommandOptions {
|
||||
const options: ImageAnalysisCommandOptions = {
|
||||
enable: hasAnyFlag(args, ['--enable']),
|
||||
@@ -296,7 +303,7 @@ export async function handleConfigImageAnalysisCommand(args: string[]): Promise<
|
||||
options.setFallback,
|
||||
Object.keys(imageConfig.provider_models)
|
||||
);
|
||||
if (!normalizedBackend) {
|
||||
if (!isConfiguredImageAnalysisBackend(normalizedBackend, imageConfig.provider_models)) {
|
||||
console.error(fail(`Invalid fallback backend: ${options.setFallback}`));
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -314,7 +321,7 @@ export async function handleConfigImageAnalysisCommand(args: string[]): Promise<
|
||||
console.error(fail('Profile name cannot be empty'));
|
||||
process.exit(1);
|
||||
}
|
||||
if (!normalizedBackend) {
|
||||
if (!isConfiguredImageAnalysisBackend(normalizedBackend, imageConfig.provider_models)) {
|
||||
console.error(fail(`Invalid backend: ${options.setProfileBackend.backend}`));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Unit tests for ccs config image-analysis subcommand.
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach, spyOn, mock } from 'bun:test';
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
@@ -33,6 +33,13 @@ function createConfigYaml(content: string): void {
|
||||
fs.writeFileSync(path.join(testDir, 'config.yaml'), content, 'utf8');
|
||||
}
|
||||
|
||||
async function loadHandleConfigImageAnalysisCommand() {
|
||||
const mod = await import(
|
||||
`../../../src/commands/config-image-analysis-command?test=${Date.now()}-${Math.random()}`
|
||||
);
|
||||
return mod.handleConfigImageAnalysisCommand;
|
||||
}
|
||||
|
||||
describe('config image-analysis command', () => {
|
||||
describe('config file parsing', () => {
|
||||
it('should parse enabled status from config.yaml', () => {
|
||||
@@ -152,6 +159,56 @@ image_analysis:
|
||||
expect(validProviders.includes(provider)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects invalid fallback backends that are not configured', async () => {
|
||||
const handleConfigImageAnalysisCommand = await loadHandleConfigImageAnalysisCommand();
|
||||
const originalProcessExit = process.exit;
|
||||
|
||||
process.exit = ((code?: number) => {
|
||||
throw new Error(`process.exit(${code ?? 0})`);
|
||||
}) as typeof process.exit;
|
||||
|
||||
try {
|
||||
await expect(
|
||||
handleConfigImageAnalysisCommand(['--set-fallback', 'unknown-provider'])
|
||||
).rejects.toThrow('process.exit(1)');
|
||||
} finally {
|
||||
process.exit = originalProcessExit;
|
||||
}
|
||||
|
||||
const configPath = path.join(testDir, 'config.yaml');
|
||||
if (fs.existsSync(configPath)) {
|
||||
const content = fs.readFileSync(configPath, 'utf8');
|
||||
expect(content).not.toContain('fallback_backend: unknown-provider');
|
||||
} else {
|
||||
expect(fs.existsSync(configPath)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects invalid profile backend mappings that are not configured', async () => {
|
||||
const handleConfigImageAnalysisCommand = await loadHandleConfigImageAnalysisCommand();
|
||||
const originalProcessExit = process.exit;
|
||||
|
||||
process.exit = ((code?: number) => {
|
||||
throw new Error(`process.exit(${code ?? 0})`);
|
||||
}) as typeof process.exit;
|
||||
|
||||
try {
|
||||
await expect(
|
||||
handleConfigImageAnalysisCommand(['--set-profile-backend', 'orq', 'unknown-provider'])
|
||||
).rejects.toThrow('process.exit(1)');
|
||||
} finally {
|
||||
process.exit = originalProcessExit;
|
||||
}
|
||||
|
||||
const configPath = path.join(testDir, 'config.yaml');
|
||||
if (fs.existsSync(configPath)) {
|
||||
const content = fs.readFileSync(configPath, 'utf8');
|
||||
expect(content).not.toContain('unknown-provider');
|
||||
} else {
|
||||
expect(fs.existsSync(configPath)).toBe(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('default configuration', () => {
|
||||
|
||||
Reference in New Issue
Block a user