import assert from 'node:assert/strict' import { DEFAULT_MEMORY_PREFERENCES, mergeMemoryPreferences, normalizeMemoryPreferences } from '../src/shared/memory' import { buildPersonalizationPrompt, DEFAULT_PERSONA, normalizePersonalization } from '../src/shared/personalization' import { storageUsagePresentation } from '../src/renderer/src/components/GeneralSettingsPanel' import { LOADING_TIPS_EVENT, LOADING_TIPS_STORAGE_KEY, loadingTipsEnabled, setLoadingTipsEnabled, subscribeLoadingTips } from '../src/renderer/src/personalization-prefs' assert.deepEqual(normalizeMemoryPreferences(undefined), DEFAULT_MEMORY_PREFERENCES) assert.deepEqual( mergeMemoryPreferences(undefined, { conversationMemory: false }), { conversationMemory: false, localMemorySkills: false }, 'changing conversation memory must not change local memory skills' ) assert.deepEqual( mergeMemoryPreferences(undefined, { localMemorySkills: true }), { conversationMemory: true, localMemorySkills: true }, 'changing local memory skills must not change conversation memory' ) assert.deepEqual( mergeMemoryPreferences({ conversationMemory: false }, undefined), { conversationMemory: false, localMemorySkills: false }, 'a partial stored view must inherit the declared default for its omitted key' ) const gib = 1024 ** 3 const exactStorage = storageUsagePresentation({ dataBytes: gib, dataUsagePartial: false, diskTotal: 100 * gib, diskFree: 50 * gib }) assert.equal(exactStorage.usageText, '已用 1.00 GB / 共 100.0 GB') assert.equal(exactStorage.cacheLabel, '系统缓存') assert.equal(exactStorage.otherLabel, '磁盘已用') assert.equal(exactStorage.cachePercentLowerBound, 1) assert.equal(exactStorage.otherPercentUpperBound, 49) assert.equal(exactStorage.freePercent, 50) assert.equal(exactStorage.partial, false) const partialStorage = storageUsagePresentation({ dataBytes: gib, dataUsagePartial: true, diskTotal: 100 * gib, diskFree: 50 * gib }) assert.equal(partialStorage.usageText, '统计未完成 · 至少已扫描 1.00 GB') assert.equal(partialStorage.cacheLabel, '系统缓存(至少)') assert.equal(partialStorage.otherLabel, '其他磁盘数据(至多)') assert.equal(partialStorage.partial, true) const overCountedStorage = storageUsagePresentation({ dataBytes: 80 * gib, dataUsagePartial: true, diskTotal: 100 * gib, diskFree: 70 * gib }) assert.equal(overCountedStorage.cachePercentLowerBound, 30, 'cache must not exceed the mounted disk used ratio') assert.equal(overCountedStorage.otherPercentUpperBound, 0) assert.equal(overCountedStorage.freePercent, 70) const defaultPrompt = buildPersonalizationPrompt(normalizePersonalization(undefined)) assert.ok(defaultPrompt.includes(`### 人设设定\n${DEFAULT_PERSONA}`)) assert.equal(buildPersonalizationPrompt(normalizePersonalization({ persona: '' })), '') const storage = new Map() const fakeLocalStorage = { get length(): number { return storage.size }, clear(): void { storage.clear() }, getItem(key: string): string | null { return storage.get(key) ?? null }, key(index: number): string | null { return [...storage.keys()][index] ?? null }, removeItem(key: string): void { storage.delete(key) }, setItem(key: string, value: string): void { storage.set(key, value) } } const fakeWindow = new EventTarget() Object.defineProperty(globalThis, 'localStorage', { value: fakeLocalStorage, configurable: true }) Object.defineProperty(globalThis, 'window', { value: fakeWindow, configurable: true }) assert.equal(loadingTipsEnabled(), true) let notifications = 0 const unsubscribe = subscribeLoadingTips(() => { notifications++ }) setLoadingTipsEnabled(false) assert.equal(storage.get(LOADING_TIPS_STORAGE_KEY), '0') assert.equal(notifications, 1, 'same-window custom event should update immediately') const unrelatedStorage = new Event('storage') Object.defineProperty(unrelatedStorage, 'key', { value: 'unrelated' }) fakeWindow.dispatchEvent(unrelatedStorage) assert.equal(notifications, 1, 'unrelated storage keys must be ignored') const matchingStorage = new Event('storage') Object.defineProperty(matchingStorage, 'key', { value: LOADING_TIPS_STORAGE_KEY }) fakeWindow.dispatchEvent(matchingStorage) assert.equal(notifications, 2, 'another window storage event should update the subscriber') unsubscribe() fakeWindow.dispatchEvent(new Event(LOADING_TIPS_EVENT)) fakeWindow.dispatchEvent(matchingStorage) assert.equal(notifications, 2, 'unsubscribe must clean up both local and storage listeners') console.log('remediation-pure-regression: all checks passed')