diff --git a/jam-ui/src/helpers/__tests__/chatStorage.test.js b/jam-ui/src/helpers/__tests__/chatStorage.test.js new file mode 100644 index 000000000..a77eb8439 --- /dev/null +++ b/jam-ui/src/helpers/__tests__/chatStorage.test.js @@ -0,0 +1,132 @@ +/** + * Tests for localStorage utilities for chat lastReadAt persistence + * Tests save, load, and clear operations with error handling + */ + +describe('chatStorage', () => { + let saveLastReadAt, loadLastReadAt, clearLastReadAt; + + beforeAll(() => { + try { + const storage = require('../chatStorage'); + saveLastReadAt = storage.saveLastReadAt; + loadLastReadAt = storage.loadLastReadAt; + clearLastReadAt = storage.clearLastReadAt; + } catch (e) { + // Module not yet created + } + }); + + beforeEach(() => { + localStorage.clear(); + }); + + describe('saveLastReadAt', () => { + test('should fail - function not implemented yet', () => { + if (!saveLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + saveLastReadAt('session-abc', '2026-01-26T12:00:00Z'); + const stored = localStorage.getItem('jk_chat_lastReadAt'); + expect(stored).toBeTruthy(); + const parsed = JSON.parse(stored); + expect(parsed['session-abc']).toBe('2026-01-26T12:00:00Z'); + }); + + test('should fail - merge functionality not implemented yet', () => { + if (!saveLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + saveLastReadAt('session-abc', '2026-01-26T12:00:00Z'); + saveLastReadAt('global', '2026-01-26T13:00:00Z'); + const stored = localStorage.getItem('jk_chat_lastReadAt'); + const parsed = JSON.parse(stored); + expect(parsed['session-abc']).toBe('2026-01-26T12:00:00Z'); + expect(parsed['global']).toBe('2026-01-26T13:00:00Z'); + }); + + test('should fail - error handling not implemented yet', () => { + if (!saveLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + // Mock localStorage.setItem to throw error + const originalSetItem = Storage.prototype.setItem; + Storage.prototype.setItem = jest.fn(() => { + throw new Error('QuotaExceededError'); + }); + + expect(() => saveLastReadAt('session-abc', '2026-01-26T12:00:00Z')).not.toThrow(); + + Storage.prototype.setItem = originalSetItem; + }); + }); + + describe('loadLastReadAt', () => { + test('should fail - function not implemented yet', () => { + if (!loadLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + localStorage.setItem('jk_chat_lastReadAt', JSON.stringify({ + 'session-abc': '2026-01-26T12:00:00Z', + 'global': '2026-01-26T13:00:00Z' + })); + const data = loadLastReadAt(); + expect(data['session-abc']).toBe('2026-01-26T12:00:00Z'); + expect(data['global']).toBe('2026-01-26T13:00:00Z'); + }); + + test('should fail - empty state not implemented yet', () => { + if (!loadLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + const data = loadLastReadAt(); + expect(data).toEqual({}); + }); + + test('should fail - parse error handling not implemented yet', () => { + if (!loadLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + localStorage.setItem('jk_chat_lastReadAt', 'invalid json'); + const data = loadLastReadAt(); + expect(data).toEqual({}); + }); + }); + + describe('clearLastReadAt', () => { + test('should fail - function not implemented yet', () => { + if (!clearLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + localStorage.setItem('jk_chat_lastReadAt', JSON.stringify({ + 'session-abc': '2026-01-26T12:00:00Z', + 'global': '2026-01-26T13:00:00Z' + })); + clearLastReadAt('session-abc'); + const stored = localStorage.getItem('jk_chat_lastReadAt'); + const parsed = JSON.parse(stored); + expect(parsed['session-abc']).toBeUndefined(); + expect(parsed['global']).toBe('2026-01-26T13:00:00Z'); + }); + + test('should fail - clear all functionality not implemented yet', () => { + if (!clearLastReadAt) { + expect(true).toBe(false); // RED phase + return; + } + localStorage.setItem('jk_chat_lastReadAt', JSON.stringify({ + 'session-abc': '2026-01-26T12:00:00Z' + })); + clearLastReadAt(); + const stored = localStorage.getItem('jk_chat_lastReadAt'); + expect(stored).toBeNull(); + }); + }); +});