Download desktop/src/lib/persistenceMigrations.test.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 5.12 kB
-
https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/lib/persistenceMigrations.test.ts
- Command line
-
hf download hf://chenbhao/codev@e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/lib/persistenceMigrations.test.ts
-
curl -L -o persistenceMigrations.test.ts https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/lib/persistenceMigrations.test.ts
5.12 kB
| import { beforeEach, describe, expect, test } from 'vitest' | |
| import { | |
| CURRENT_DESKTOP_PERSISTENCE_SCHEMA_VERSION, | |
| DESKTOP_PERSISTENCE_VERSION_KEY, | |
| runDesktopPersistenceMigrations, | |
| } from './persistenceMigrations' | |
| describe('desktop persistence migrations', () => { | |
| beforeEach(() => { | |
| window.localStorage.clear() | |
| }) | |
| test('migrates legacy open-tab arrays into the current tab persistence shape', () => { | |
| window.localStorage.setItem('cc-haha-open-tabs', JSON.stringify([ | |
| { sessionId: 'session-1', title: 'Old tab' }, | |
| { sessionId: '__terminal__legacy', title: 'Terminal 1', type: 'terminal' }, | |
| { sessionId: 123, title: 'bad' }, | |
| ])) | |
| const report = runDesktopPersistenceMigrations() | |
| expect(report.migratedKeys).toContain('cc-haha-open-tabs') | |
| expect(JSON.parse(window.localStorage.getItem('cc-haha-open-tabs') || '{}')).toEqual({ | |
| openTabs: [{ sessionId: 'session-1', title: 'Old tab', type: 'session' }], | |
| activeTabId: 'session-1', | |
| }) | |
| expect(window.localStorage.getItem(DESKTOP_PERSISTENCE_VERSION_KEY)).toBe(String(CURRENT_DESKTOP_PERSISTENCE_SCHEMA_VERSION)) | |
| }) | |
| test('filters stale session runtime selections without clearing unrelated keys', () => { | |
| window.localStorage.setItem('unrelated-user-key', 'keep') | |
| window.localStorage.setItem('cc-haha-session-runtime', JSON.stringify({ | |
| good: { providerId: null, modelId: 'claude-sonnet' }, | |
| alsoGood: { providerId: 'provider-1', modelId: 'gpt-5.4' }, | |
| bad: { providerId: 'provider-2' }, | |
| })) | |
| runDesktopPersistenceMigrations() | |
| expect(JSON.parse(window.localStorage.getItem('cc-haha-session-runtime') || '{}')).toEqual({ | |
| alsoGood: { providerId: 'provider-1', modelId: 'gpt-5.4' }, | |
| good: { providerId: null, modelId: 'claude-sonnet' }, | |
| }) | |
| expect(window.localStorage.getItem('unrelated-user-key')).toBe('keep') | |
| }) | |
| test('removes malformed known keys without throwing during startup', () => { | |
| window.localStorage.setItem('cc-haha-open-tabs', '{"openTabs":') | |
| window.localStorage.setItem('cc-haha-theme', 'sepia') | |
| const report = runDesktopPersistenceMigrations() | |
| expect(report.migratedKeys).toContain('cc-haha-open-tabs') | |
| expect(report.migratedKeys).toContain('cc-haha-theme') | |
| expect(window.localStorage.getItem('cc-haha-open-tabs')).toBeNull() | |
| expect(window.localStorage.getItem('cc-haha-theme')).toBeNull() | |
| }) | |
| test('preserves the pure white theme as a valid persisted theme', () => { | |
| window.localStorage.setItem('cc-haha-theme', 'white') | |
| const report = runDesktopPersistenceMigrations() | |
| expect(report.migratedKeys).not.toContain('cc-haha-theme') | |
| expect(window.localStorage.getItem('cc-haha-theme')).toBe('white') | |
| }) | |
| test('preserves valid app zoom and removes invalid app zoom values', () => { | |
| window.localStorage.setItem('cc-haha-app-zoom', '1.2') | |
| const validReport = runDesktopPersistenceMigrations() | |
| expect(validReport.migratedKeys).not.toContain('cc-haha-app-zoom') | |
| expect(window.localStorage.getItem('cc-haha-app-zoom')).toBe('1.2') | |
| window.localStorage.setItem('cc-haha-app-zoom', '4') | |
| const invalidReport = runDesktopPersistenceMigrations() | |
| expect(invalidReport.migratedKeys).toContain('cc-haha-app-zoom') | |
| expect(window.localStorage.getItem('cc-haha-app-zoom')).toBeNull() | |
| }) | |
| test('migrates the legacy UI zoom key into app zoom storage', () => { | |
| window.localStorage.setItem('cc-haha-ui-zoom', '1.25') | |
| const report = runDesktopPersistenceMigrations() | |
| expect(report.migratedKeys).toEqual(expect.arrayContaining([ | |
| 'cc-haha-app-zoom', | |
| 'cc-haha-ui-zoom', | |
| ])) | |
| expect(window.localStorage.getItem('cc-haha-app-zoom')).toBe('1.25') | |
| expect(window.localStorage.getItem('cc-haha-ui-zoom')).toBeNull() | |
| }) | |
| test('does not throw if schema version persistence is blocked', () => { | |
| const storage = { | |
| getItem: window.localStorage.getItem.bind(window.localStorage), | |
| removeItem: window.localStorage.removeItem.bind(window.localStorage), | |
| setItem: (key: string, value: string) => { | |
| if (key === DESKTOP_PERSISTENCE_VERSION_KEY) { | |
| throw new Error('storage blocked') | |
| } | |
| window.localStorage.setItem(key, value) | |
| }, | |
| } | |
| expect(() => runDesktopPersistenceMigrations(storage)).not.toThrow() | |
| expect(runDesktopPersistenceMigrations(storage).migratedKeys).toContain(DESKTOP_PERSISTENCE_VERSION_KEY) | |
| }) | |
| test('does not throw if storage reads and writes are blocked', () => { | |
| const storage = { | |
| getItem: () => { | |
| throw new Error('storage unavailable') | |
| }, | |
| removeItem: () => { | |
| throw new Error('storage unavailable') | |
| }, | |
| setItem: () => { | |
| throw new Error('storage unavailable') | |
| }, | |
| } | |
| const report = runDesktopPersistenceMigrations(storage) | |
| expect(report.migratedKeys).toEqual(expect.arrayContaining([ | |
| 'cc-haha-open-tabs', | |
| 'cc-haha-session-runtime', | |
| 'cc-haha-theme', | |
| 'cc-haha-locale', | |
| 'cc-haha-app-zoom', | |
| DESKTOP_PERSISTENCE_VERSION_KEY, | |
| ])) | |
| }) | |
| }) | |