134c6a167c
CC1: customCommandEnabled→enableCustomCommands, downloadArchive→ useDownloadArchive, clipboardWatch→watchClipboard, sidebarCollapsed→ isSidebarCollapsed, hardwareAcceleration→useHardwareAcceleration, videoDir/audioDir→videoFolder/audioFolder (+ chooseDir/clearDir store actions → chooseFolder/clearFolder). Rename map in settingsMigration.ts (pure, unit-tested incl. pre-rename backup fixture), applied as an idempotent on-disk shim at store open and on backup import so old settings.json and old backups both keep working. CC11: update host/owner/repo + release API moved to src/main/config.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
70 lines
2.6 KiB
TypeScript
70 lines
2.6 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { migrateSettingsKeys, RENAMED_SETTINGS_KEYS } from '../src/main/settingsMigration'
|
|
import { DEFAULT_SETTINGS } from '@shared/ipc'
|
|
|
|
describe('migrateSettingsKeys (CC1)', () => {
|
|
it('moves every legacy key to its new name', () => {
|
|
const legacy = {
|
|
customCommandEnabled: true,
|
|
downloadArchive: true,
|
|
clipboardWatch: false,
|
|
sidebarCollapsed: true,
|
|
hardwareAcceleration: true,
|
|
videoDir: 'D:\\Media\\Video',
|
|
audioDir: 'D:\\Media\\Audio'
|
|
}
|
|
const out = migrateSettingsKeys(legacy)
|
|
expect(out).toEqual({
|
|
enableCustomCommands: true,
|
|
useDownloadArchive: true,
|
|
watchClipboard: false,
|
|
isSidebarCollapsed: true,
|
|
useHardwareAcceleration: true,
|
|
videoFolder: 'D:\\Media\\Video',
|
|
audioFolder: 'D:\\Media\\Audio'
|
|
})
|
|
})
|
|
|
|
it('a value already present under the new name wins', () => {
|
|
const out = migrateSettingsKeys({ videoDir: 'old', videoFolder: 'new' })
|
|
expect(out).toEqual({ videoFolder: 'new' })
|
|
})
|
|
|
|
it('passes non-renamed keys through untouched and does not mutate the input', () => {
|
|
const input = { theme: 'dark', maxConcurrent: 3, videoDir: 'X' }
|
|
const out = migrateSettingsKeys(input)
|
|
expect(out.theme).toBe('dark')
|
|
expect(out.maxConcurrent).toBe(3)
|
|
expect(input.videoDir).toBe('X') // input untouched
|
|
expect('videoDir' in out).toBe(false)
|
|
})
|
|
|
|
it('restores a full pre-rename backup fixture into the current Settings shape', () => {
|
|
// A settings object exactly as an older AeroFetch would have exported it:
|
|
// current defaults, but with every renamed key under its OLD name.
|
|
const legacyBackup: Record<string, unknown> = { ...DEFAULT_SETTINGS }
|
|
for (const [oldKey, newKey] of RENAMED_SETTINGS_KEYS) {
|
|
legacyBackup[oldKey] = legacyBackup[newKey]
|
|
delete legacyBackup[newKey]
|
|
}
|
|
legacyBackup.customCommandEnabled = true
|
|
legacyBackup.videoDir = 'E:\\Downloads'
|
|
|
|
const out = migrateSettingsKeys(legacyBackup)
|
|
// Every current key present, no legacy key left behind.
|
|
for (const [oldKey, newKey] of RENAMED_SETTINGS_KEYS) {
|
|
expect(oldKey in out).toBe(false)
|
|
expect(newKey in out).toBe(true)
|
|
}
|
|
expect(out.enableCustomCommands).toBe(true)
|
|
expect(out.videoFolder).toBe('E:\\Downloads')
|
|
expect(Object.keys(out).sort()).toEqual(Object.keys(DEFAULT_SETTINGS).sort())
|
|
})
|
|
|
|
it('every new name follows the boolean/folder naming convention', () => {
|
|
for (const [, newKey] of RENAMED_SETTINGS_KEYS) {
|
|
expect(newKey).toMatch(/^(is|has|should|use|enable|watch)[A-Z]|Folder$/)
|
|
}
|
|
})
|
|
})
|