import { afterEach, describe, expect, it, vi } from 'vitest' describe('ConfigService suggestion tuning migration', () => { afterEach(() => { vi.doUnmock('electron-store') vi.resetModules() }) it('revision 3은 새 delay와 분당 상한만 바꾸고 기존 개인 설정을 보존한다', async () => { const savedBindings = { 'suggestion-accept': [ { device: 'keyboard' as const, code: 65, ctrl: true, alt: false, shift: false, meta: false } ] } const persisted = { suggestionTuningRevision: 3, suggestionTriggerDelayMs: 300, suggestionMaxRequestsPerMinute: 12, suggestionMinPrefixChars: 17, suggestionDailyBudget: 777, suggestionRequestTimeoutMs: 23000, keyBindings: savedBindings } class TestStore> { store: T constructor(options: { defaults: T }) { this.store = { ...options.defaults, ...persisted } as T } get(key: K): T[K] { return this.store[key] } set(key: K, value: T[K]): void { this.store[key] = value } delete(key: string): void { delete this.store[key as keyof T] } } vi.doMock('electron-store', () => ({ default: TestStore })) const { configGet, initConfigService, resetInMemoryConfig } = await import( '../../../src/main/services/ConfigService' ) await initConfigService() expect(configGet('suggestionTuningRevision')).toBe(5) expect(configGet('suggestionTriggerDelayMs')).toBe(600) expect(configGet('suggestionMaxRequestsPerMinute')).toBe(6) expect(configGet('suggestionMinPrefixChars')).toBe(17) expect(configGet('suggestionDailyBudget')).toBe(777) expect(configGet('suggestionRequestTimeoutMs')).toBe(23000) // 옛 기본값이 아닌 커스터마이즈(Ctrl+A)는 revision 5 마이그레이션도 건드리지 않는다. expect(configGet('keyBindings')['suggestion-accept']).toEqual(savedBindings['suggestion-accept']) resetInMemoryConfig() }) function makeTestStore>(persisted: Partial) { return class TestStore { store: T constructor(options: { defaults: T }) { this.store = { ...options.defaults, ...persisted } as T } get(key: K): T[K] { return this.store[key] } set(key: K, value: T[K]): void { this.store[key] = value } delete(key: string): void { delete this.store[key as keyof T] } } } it('revision 5: 정확히 옛 기본값(accept=Ctrl+Alt+→, dismiss=Ctrl+Alt+←)이면 새 기본값으로 옮기고 페이지 이동을 그 자리에 채운다', async () => { const OLD_ACCEPT = [{ device: 'keyboard' as const, code: 39, ctrl: true, alt: true, shift: false, meta: false }] const OLD_NEXT = [{ device: 'keyboard' as const, code: 40, ctrl: true, alt: true, shift: false, meta: false }] const OLD_PREV = [{ device: 'keyboard' as const, code: 38, ctrl: true, alt: true, shift: false, meta: false }] const OLD_DISMISS = [{ device: 'keyboard' as const, code: 37, ctrl: true, alt: true, shift: false, meta: false }] vi.doMock('electron-store', () => ({ default: makeTestStore({ suggestionTuningRevision: 4, keyBindings: { 'suggestion-accept': OLD_ACCEPT, 'suggestion-next': OLD_NEXT, 'suggestion-prev': OLD_PREV, 'suggestion-dismiss': OLD_DISMISS } }) })) const { configGet, initConfigService, resetInMemoryConfig } = await import( '../../../src/main/services/ConfigService' ) await initConfigService() const bindings = configGet('keyBindings') expect(bindings['suggestion-accept']).toEqual([ { device: 'keyboard', code: 0x0d, ctrl: true, alt: true, shift: false, meta: false } ]) expect(bindings['suggestion-dismiss']).toEqual([ { device: 'keyboard', code: 0x08, ctrl: true, alt: true, shift: false, meta: false } ]) // 옮기지 않는 액션은 그대로 남는다. expect(bindings['suggestion-next']).toEqual(OLD_NEXT) expect(bindings['suggestion-prev']).toEqual(OLD_PREV) expect(configGet('suggestionTuningRevision')).toBe(5) resetInMemoryConfig() }) it('revision 5: 옛 기본값이 아닌 커스터마이즈는 절대 건드리지 않는다', async () => { const CUSTOM_ACCEPT = [{ device: 'keyboard' as const, code: 0x41, ctrl: true, alt: false, shift: false, meta: false }] const CUSTOM_DISMISS = [{ device: 'keyboard' as const, code: 0x44, ctrl: true, alt: false, shift: false, meta: false }] vi.doMock('electron-store', () => ({ default: makeTestStore({ suggestionTuningRevision: 4, keyBindings: { 'suggestion-accept': CUSTOM_ACCEPT, 'suggestion-dismiss': CUSTOM_DISMISS } }) })) const { configGet, initConfigService, resetInMemoryConfig } = await import( '../../../src/main/services/ConfigService' ) await initConfigService() const bindings = configGet('keyBindings') expect(bindings['suggestion-accept']).toEqual(CUSTOM_ACCEPT) expect(bindings['suggestion-dismiss']).toEqual(CUSTOM_DISMISS) resetInMemoryConfig() }) })