Download src/server/__tests__/persistence-upgrade.test.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 10.2 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/server/__tests__/persistence-upgrade.test.ts
- Command line
-
hf download hf://chenbhao/codev/src/server/__tests__/persistence-upgrade.test.ts
-
curl -L -o persistence-upgrade.test.ts https://huggingface.co/chenbhao/codev/resolve/main/src/server/__tests__/persistence-upgrade.test.ts
10.2 kB
| 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 { ProviderService } from '../services/providerService.js' | |
| import { | |
| CURRENT_PROVIDER_INDEX_SCHEMA_VERSION, | |
| ensurePersistentStorageUpgraded, | |
| resetPersistentStorageMigrationsForTests, | |
| } from '../services/persistentStorageMigrations.js' | |
| let tempDir: string | |
| async function listFiles(dir: string) { | |
| try { | |
| return await fs.readdir(dir) | |
| } catch { | |
| return [] | |
| } | |
| } | |
| describe('persistent storage upgrade migrations', () => { | |
| beforeEach(async () => { | |
| tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'cc-haha-persistence-')) | |
| process.env.CLAUDE_CONFIG_DIR = tempDir | |
| resetPersistentStorageMigrationsForTests() | |
| }) | |
| afterEach(async () => { | |
| resetPersistentStorageMigrationsForTests() | |
| delete process.env.CLAUDE_CONFIG_DIR | |
| await fs.rm(tempDir, { recursive: true, force: true }) | |
| }) | |
| test('migrates legacy providers index and writes a backup before changing it', async () => { | |
| const ccHahaDir = path.join(tempDir, 'cc-haha') | |
| await fs.mkdir(ccHahaDir, { recursive: true }) | |
| await fs.writeFile( | |
| path.join(ccHahaDir, 'providers.json'), | |
| JSON.stringify({ | |
| activeProviderId: 'provider-1', | |
| rootFutureField: { keep: true }, | |
| providers: [{ | |
| id: 'provider-1', | |
| presetId: 'custom', | |
| name: 'Legacy Provider', | |
| apiKey: 'token', | |
| baseUrl: 'https://example.test', | |
| models: { main: 'model-main', haiku: '', sonnet: '', opus: '' }, | |
| extraFutureField: 'keep-me', | |
| }], | |
| }, null, 2), | |
| 'utf-8', | |
| ) | |
| const report = await ensurePersistentStorageUpgraded() | |
| expect(report.failures).toEqual([]) | |
| expect(report.migratedEntries).toContain('cc-haha/providers.json') | |
| const migrated = JSON.parse(await fs.readFile(path.join(ccHahaDir, 'providers.json'), 'utf-8')) as { | |
| schemaVersion?: number | |
| activeId?: string | null | |
| activeProviderId?: string | |
| rootFutureField?: unknown | |
| providers?: Array<Record<string, unknown>> | |
| } | |
| expect(migrated.schemaVersion).toBe(CURRENT_PROVIDER_INDEX_SCHEMA_VERSION) | |
| expect(migrated.activeId).toBe('provider-1') | |
| expect(migrated.activeProviderId).toBeUndefined() | |
| expect(migrated.rootFutureField).toEqual({ keep: true }) | |
| expect(migrated.providers?.[0]?.extraFutureField).toBe('keep-me') | |
| const backups = (await listFiles(ccHahaDir)).filter((file) => file.startsWith('providers.json.bak-before-migration-')) | |
| expect(backups.length).toBe(1) | |
| const service = new ProviderService() | |
| const { providers, activeId } = await service.listProviders() | |
| expect(providers).toHaveLength(1) | |
| expect(activeId).toBe('provider-1') | |
| await service.updateProvider('provider-1', { name: 'Renamed Provider' }) | |
| const rewritten = JSON.parse(await fs.readFile(path.join(ccHahaDir, 'providers.json'), 'utf-8')) as { | |
| rootFutureField?: unknown | |
| providers?: Array<Record<string, unknown>> | |
| } | |
| expect(rewritten.rootFutureField).toEqual({ keep: true }) | |
| expect(rewritten.providers?.[0]?.extraFutureField).toBe('keep-me') | |
| }) | |
| test('imports legacy root providers config into cc-haha storage without deleting the source', async () => { | |
| await fs.writeFile( | |
| path.join(tempDir, 'providers.json'), | |
| JSON.stringify({ | |
| version: 1, | |
| activeModel: 'legacy-sonnet', | |
| providers: [{ | |
| id: 'legacy-provider', | |
| name: 'Legacy Root Provider', | |
| baseUrl: 'https://legacy.example.test', | |
| apiKey: 'legacy-token', | |
| models: [ | |
| { id: 'legacy-haiku', name: 'Legacy Haiku' }, | |
| { id: 'legacy-sonnet', name: 'Legacy Sonnet' }, | |
| ], | |
| isActive: true, | |
| createdAt: 1, | |
| updatedAt: 2, | |
| notes: 'keep note', | |
| }], | |
| }, null, 2), | |
| 'utf-8', | |
| ) | |
| const report = await ensurePersistentStorageUpgraded() | |
| expect(report.failures).toEqual([]) | |
| expect(report.migratedEntries).toContain('providers.json -> cc-haha/providers.json') | |
| expect(report.migratedEntries).toContain('providers.json -> cc-haha/settings.json') | |
| expect(JSON.parse(await fs.readFile(path.join(tempDir, 'providers.json'), 'utf-8'))).toMatchObject({ | |
| version: 1, | |
| activeModel: 'legacy-sonnet', | |
| }) | |
| const migrated = JSON.parse(await fs.readFile(path.join(tempDir, 'cc-haha', 'providers.json'), 'utf-8')) as { | |
| activeId?: string | null | |
| providers?: Array<{ | |
| id?: string | |
| presetId?: string | |
| apiFormat?: string | |
| models?: Record<string, string> | |
| notes?: string | |
| }> | |
| } | |
| expect(migrated.activeId).toBe('legacy-provider') | |
| expect(migrated.providers?.[0]).toMatchObject({ | |
| id: 'legacy-provider', | |
| presetId: 'custom', | |
| apiFormat: 'anthropic', | |
| notes: 'keep note', | |
| models: { | |
| main: 'legacy-sonnet', | |
| haiku: 'legacy-sonnet', | |
| sonnet: 'legacy-sonnet', | |
| opus: 'legacy-sonnet', | |
| }, | |
| }) | |
| const managedSettings = JSON.parse(await fs.readFile(path.join(tempDir, 'cc-haha', 'settings.json'), 'utf-8')) as { | |
| env?: Record<string, string> | |
| } | |
| expect(managedSettings.env).toMatchObject({ | |
| ANTHROPIC_BASE_URL: 'https://legacy.example.test', | |
| ANTHROPIC_AUTH_TOKEN: 'legacy-token', | |
| ANTHROPIC_MODEL: 'legacy-sonnet', | |
| }) | |
| const service = new ProviderService() | |
| const { providers, activeId } = await service.listProviders() | |
| expect(activeId).toBe('legacy-provider') | |
| expect(providers[0]?.models.main).toBe('legacy-sonnet') | |
| }) | |
| test('does not overwrite current cc-haha provider storage with a legacy root config', async () => { | |
| const ccHahaDir = path.join(tempDir, 'cc-haha') | |
| await fs.mkdir(ccHahaDir, { recursive: true }) | |
| await fs.writeFile( | |
| path.join(tempDir, 'providers.json'), | |
| JSON.stringify({ | |
| version: 1, | |
| activeModel: 'legacy-model', | |
| providers: [{ | |
| id: 'legacy-provider', | |
| name: 'Legacy Root Provider', | |
| baseUrl: 'https://legacy.example.test', | |
| apiKey: 'legacy-token', | |
| models: [{ id: 'legacy-model' }], | |
| isActive: true, | |
| }], | |
| }, null, 2), | |
| 'utf-8', | |
| ) | |
| await fs.writeFile( | |
| path.join(ccHahaDir, 'providers.json'), | |
| JSON.stringify({ | |
| schemaVersion: CURRENT_PROVIDER_INDEX_SCHEMA_VERSION, | |
| activeId: null, | |
| providers: [], | |
| }, null, 2), | |
| 'utf-8', | |
| ) | |
| const report = await ensurePersistentStorageUpgraded() | |
| expect(report.failures).toEqual([]) | |
| expect(report.migratedEntries).not.toContain('providers.json -> cc-haha/providers.json') | |
| const current = JSON.parse(await fs.readFile(path.join(ccHahaDir, 'providers.json'), 'utf-8')) as { | |
| activeId?: string | null | |
| providers?: unknown[] | |
| } | |
| expect(current.activeId).toBeNull() | |
| expect(current.providers).toEqual([]) | |
| }) | |
| test('does not write repo-owned schema metadata into shared user settings', async () => { | |
| await fs.writeFile( | |
| path.join(tempDir, 'settings.json'), | |
| JSON.stringify({ | |
| defaultMode: 'acceptEdits', | |
| userOwnedFutureField: { nested: true }, | |
| }, null, 2), | |
| 'utf-8', | |
| ) | |
| const report = await ensurePersistentStorageUpgraded() | |
| expect(report.failures).toEqual([]) | |
| const settings = JSON.parse(await fs.readFile(path.join(tempDir, 'settings.json'), 'utf-8')) as Record<string, unknown> | |
| expect(settings.schemaVersion).toBeUndefined() | |
| expect(settings.userOwnedFutureField).toEqual({ nested: true }) | |
| }) | |
| test('quarantines malformed managed settings instead of blocking startup', async () => { | |
| const ccHahaDir = path.join(tempDir, 'cc-haha') | |
| await fs.mkdir(ccHahaDir, { recursive: true }) | |
| await fs.writeFile(path.join(ccHahaDir, 'settings.json'), '{"env":', 'utf-8') | |
| const report = await ensurePersistentStorageUpgraded() | |
| expect(report.failures).toEqual([]) | |
| expect(report.migratedEntries).toContain('cc-haha/settings.json') | |
| expect(JSON.parse(await fs.readFile(path.join(ccHahaDir, 'settings.json'), 'utf-8'))).toEqual({}) | |
| const quarantined = (await listFiles(ccHahaDir)).filter((file) => file.startsWith('settings.json.invalid-')) | |
| expect(quarantined.length).toBe(1) | |
| }) | |
| test('upgrades existing DeepSeek managed env to follow global thinking settings', async () => { | |
| const ccHahaDir = path.join(tempDir, 'cc-haha') | |
| await fs.mkdir(ccHahaDir, { recursive: true }) | |
| await fs.writeFile( | |
| path.join(ccHahaDir, 'settings.json'), | |
| JSON.stringify({ | |
| env: { | |
| ANTHROPIC_BASE_URL: 'https://api.deepseek.com/anthropic', | |
| ANTHROPIC_AUTH_TOKEN: 'test-token', | |
| ANTHROPIC_MODEL: 'deepseek-v4-pro', | |
| ANTHROPIC_DEFAULT_HAIKU_MODEL: 'deepseek-v4-flash', | |
| ANTHROPIC_DEFAULT_SONNET_MODEL: 'deepseek-v4-pro', | |
| ANTHROPIC_DEFAULT_OPUS_MODEL: 'deepseek-v4-pro', | |
| CC_HAHA_SEND_DISABLED_THINKING: '1', | |
| USER_CUSTOM_ENV: 'keep-me', | |
| }, | |
| }, null, 2), | |
| 'utf-8', | |
| ) | |
| const report = await ensurePersistentStorageUpgraded() | |
| expect(report.failures).toEqual([]) | |
| expect(report.migratedEntries).toContain('cc-haha/settings.json') | |
| const migrated = JSON.parse(await fs.readFile(path.join(ccHahaDir, 'settings.json'), 'utf-8')) as { | |
| env?: Record<string, string> | |
| } | |
| expect(migrated.env?.CC_HAHA_SEND_DISABLED_THINKING).toBeUndefined() | |
| expect(migrated.env?.ANTHROPIC_DEFAULT_HAIKU_MODEL_SUPPORTED_CAPABILITIES).toBe( | |
| 'thinking,effort,adaptive_thinking,max_effort', | |
| ) | |
| expect(migrated.env?.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES).toBe( | |
| 'thinking,effort,adaptive_thinking,max_effort', | |
| ) | |
| expect(migrated.env?.ANTHROPIC_DEFAULT_OPUS_MODEL_SUPPORTED_CAPABILITIES).toBe( | |
| 'thinking,effort,adaptive_thinking,max_effort', | |
| ) | |
| expect(migrated.env?.USER_CUSTOM_ENV).toBe('keep-me') | |
| const backups = (await listFiles(ccHahaDir)).filter((file) => file.startsWith('settings.json.bak-before-migration-')) | |
| expect(backups.length).toBe(1) | |
| }) | |
| }) | |