Files
ccs/tests/unit/config/migration-manager.test.ts
T

136 lines
3.8 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { loadMigrationCheckData, migrate } from '../../../src/config/migration-manager';
import { saveUnifiedConfig } from '../../../src/config/unified-config-loader';
import { createEmptyUnifiedConfig } from '../../../src/config/unified-config-types';
describe('migration-manager legacy kimi compatibility', () => {
let tempHome: string;
let ccsDir: string;
let originalCcsHome: string | undefined;
beforeEach(() => {
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-migration-manager-test-'));
originalCcsHome = process.env.CCS_HOME;
process.env.CCS_HOME = tempHome;
ccsDir = path.join(tempHome, '.ccs');
fs.mkdirSync(ccsDir, { recursive: true });
});
afterEach(() => {
if (originalCcsHome !== undefined) {
process.env.CCS_HOME = originalCcsHome;
} else {
delete process.env.CCS_HOME;
}
if (fs.existsSync(tempHome)) {
fs.rmSync(tempHome, { recursive: true, force: true });
}
});
it('prefers explicit canonical km profile over legacy kimi when both exist', async () => {
const kmSettingsPath = path.join(ccsDir, 'km.settings.json');
const kimiSettingsPath = path.join(ccsDir, 'kimi.settings.json');
fs.writeFileSync(kmSettingsPath, JSON.stringify({ env: { ANTHROPIC_AUTH_TOKEN: 'sk-km' } }));
fs.writeFileSync(
kimiSettingsPath,
JSON.stringify({ env: { ANTHROPIC_AUTH_TOKEN: 'sk-kimi' } })
);
// Intentionally place legacy alias first to verify deterministic behavior.
fs.writeFileSync(
path.join(ccsDir, 'config.json'),
JSON.stringify(
{
profiles: {
kimi: kimiSettingsPath,
km: kmSettingsPath,
},
},
null,
2
)
);
const result = await migrate(true);
expect(result.success).toBe(true);
expect(
result.migratedFiles.some((entry) =>
entry.includes(`config.json.profiles.km → config.yaml.profiles.km (settings: ${kmSettingsPath})`)
)
).toBe(true);
expect(
result.migratedFiles.some((entry) =>
entry.includes(`(settings: ${kimiSettingsPath})`)
)
).toBe(false);
expect(
result.warnings.some((warning) =>
warning.includes(
'Skipped kimi: canonical profile "km" exists in config.json with different settings'
)
)
).toBe(true);
});
it('renames case-variant legacy Kimi profile key to km', async () => {
const kimiSettingsPath = path.join(ccsDir, 'kimi.settings.json');
fs.writeFileSync(
kimiSettingsPath,
JSON.stringify({ env: { ANTHROPIC_AUTH_TOKEN: 'sk-kimi-case-variant' } })
);
fs.writeFileSync(
path.join(ccsDir, 'config.json'),
JSON.stringify(
{
profiles: {
Kimi: kimiSettingsPath,
},
},
null,
2
)
);
const result = await migrate(true);
expect(result.success).toBe(true);
expect(
result.migratedFiles.some((entry) =>
entry.includes('config.json.profiles.Kimi → config.yaml.profiles.km')
)
).toBe(true);
});
it('treats legacy kimi profile as migrated when unified config already has km', () => {
const unifiedConfig = createEmptyUnifiedConfig();
unifiedConfig.profiles.km = {
type: 'api',
settings: '~/.ccs/km.settings.json',
};
saveUnifiedConfig(unifiedConfig);
fs.writeFileSync(
path.join(ccsDir, 'config.json'),
JSON.stringify(
{
profiles: {
kimi: '~/.ccs/kimi.settings.json',
},
},
null,
2
)
);
const checkData = loadMigrationCheckData();
expect(checkData.needsMigration).toBe(false);
});
});