import { describe, expect, it } from 'vitest'; import { CHAT_VIEW_PREFERENCES_STORAGE_KEY, deleteChatViewPreferences, loadChatViewPreferences, saveChatViewPreferences, } from '@/stores/chat-view-preferences'; function memoryStorage(): Storage { const values = new Map(); return { get length() { return values.size; }, clear: () => values.clear(), getItem: (key) => values.get(key) ?? null, key: (index) => [...values.keys()][index] ?? null, removeItem: (key) => { values.delete(key); }, setItem: (key, value) => { values.set(key, value); }, }; } describe('chat view preferences', () => { it('defaults to the current visible thinking and timestamp behavior', () => { expect(loadChatViewPreferences('session-1', memoryStorage())).toEqual({ showThinking: true, showTimestamps: true, includeExecution: false, }); }); it('persists independent per-session values and ignores malformed storage', () => { const storage = memoryStorage(); saveChatViewPreferences('session-1', { showThinking: false }, storage); saveChatViewPreferences('session-2', { showTimestamps: false }, storage); expect(loadChatViewPreferences('session-1', storage)).toEqual({ showThinking: false, showTimestamps: true, includeExecution: false, }); expect(loadChatViewPreferences('session-2', storage)).toEqual({ showThinking: true, showTimestamps: false, includeExecution: false, }); storage.setItem(CHAT_VIEW_PREFERENCES_STORAGE_KEY, '{not-json'); expect(loadChatViewPreferences('session-1', storage)).toEqual({ showThinking: true, showTimestamps: true, includeExecution: false, }); }); it('deletes only the removed session entry', () => { const storage = memoryStorage(); saveChatViewPreferences('session-1', { showThinking: false }, storage); saveChatViewPreferences('session-2', { showTimestamps: false }, storage); deleteChatViewPreferences('session-1', storage); expect(loadChatViewPreferences('session-1', storage).showThinking).toBe(true); expect(loadChatViewPreferences('session-2', storage).showTimestamps).toBe(false); }); it('treats unavailable storage as best-effort and never throws', () => { const unavailableStorage = { get length() { throw new Error('storage denied'); }, clear: () => { throw new Error('storage denied'); }, getItem: () => { throw new Error('storage denied'); }, key: () => { throw new Error('storage denied'); }, removeItem: () => { throw new Error('storage denied'); }, setItem: () => { throw new Error('storage denied'); }, } as Storage; expect(loadChatViewPreferences('session-1', unavailableStorage)).toEqual({ showThinking: true, showTimestamps: true, includeExecution: false, }); expect(saveChatViewPreferences( 'session-1', { showThinking: false }, unavailableStorage, )).toEqual({ showThinking: false, showTimestamps: true, includeExecution: false, }); expect(() => deleteChatViewPreferences('session-1', unavailableStorage)).not.toThrow(); }); });