import { ChatMessage } from '../store/useAppStore'; import { findLastAssistantId, shouldShowTypingIndicator } from '../utils/chatSelectors'; import { buildServerConfig, isConfigChanged } from '../utils/serverConfig'; import { isDarkTheme } from '../utils/theme'; const msg = (id: string, role: ChatMessage['role'], content = 'x'): ChatMessage => ({ id, role, content, timestamp: 0, }); describe('findLastAssistantId', () => { it('returns the most recent assistant message', () => { expect(findLastAssistantId([msg('1', 'assistant'), msg('2', 'user'), msg('3', 'assistant')])).toBe('3'); }); it('returns null when there is no assistant message', () => { expect(findLastAssistantId([msg('1', 'user')])).toBeNull(); expect(findLastAssistantId([])).toBeNull(); }); }); describe('shouldShowTypingIndicator', () => { it('is true only while streaming an assistant message with no text yet', () => { expect(shouldShowTypingIndicator([msg('1', 'user'), msg('2', 'assistant', '')], true)).toBe(true); }); it('is false when not streaming, when text arrived, when the last message is the user, or when empty', () => { expect(shouldShowTypingIndicator([msg('2', 'assistant', '')], false)).toBe(false); expect(shouldShowTypingIndicator([msg('2', 'assistant', 'hi')], true)).toBe(false); expect(shouldShowTypingIndicator([msg('1', 'user', '')], true)).toBe(false); expect(shouldShowTypingIndicator([], true)).toBe(false); }); }); describe('buildServerConfig', () => { it('trims the host and API key and parses the port', () => { expect(buildServerConfig({ host: ' 10.0.0.1 ', port: '8080', apiKey: ' k ' })).toEqual({ host: '10.0.0.1', port: 8080, apiKey: 'k', }); }); it('uses the defaults for blank host, invalid port and blank key', () => { expect(buildServerConfig({ host: '', port: 'abc', apiKey: ' ' })).toEqual({ host: 'localhost', port: 1234, apiKey: undefined, }); }); }); describe('isConfigChanged', () => { const saved = { host: 'lan', port: 1234, apiKey: 'k' }; it('is false when the form matches the saved config', () => { expect(isConfigChanged({ host: 'lan', port: '1234', apiKey: 'k' }, saved)).toBe(false); expect(isConfigChanged({ host: 'lan', port: '1234', apiKey: '' }, { host: 'lan', port: 1234 })).toBe(false); }); it('is true when any single field differs', () => { expect(isConfigChanged({ host: 'other', port: '1234', apiKey: 'k' }, saved)).toBe(true); expect(isConfigChanged({ host: 'lan', port: '99', apiKey: 'k' }, saved)).toBe(true); expect(isConfigChanged({ host: 'lan', port: '1234', apiKey: '' }, saved)).toBe(true); }); }); describe('isDarkTheme', () => { it('honours an explicit preference and falls back to the system scheme', () => { expect(isDarkTheme('dark', 'light')).toBe(true); expect(isDarkTheme('light', 'dark')).toBe(false); expect(isDarkTheme('system', 'dark')).toBe(true); expect(isDarkTheme('system', 'light')).toBe(false); }); });