/** * Tests for Heartbeat + Reflection (via intelligenceClient) * * These tests mock the Tauri backend calls for unit testing. */ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { intelligenceClient, type HeartbeatConfig, type HeartbeatResult, } from '../../desktop/src/lib/intelligence-client'; // === Mock localStorage === const localStorageMock = (() => { let store: Record = {}; return { getItem: (key: string) => store[key] ?? null, setItem: (key: string, value: string) => { store[key] = value; }, removeItem: (key: string) => { delete store[key]; }, clear: () => { store = {}; }, }; })(); vi.stubGlobal('localStorage', localStorageMock); // === Mock Tauri invoke === vi.mock('@tauri-apps/api/core', () => ({ invoke: vi.fn(async (cmd: string, _args?: unknown) => { // Mock responses for heartbeat commands if (cmd === 'heartbeat_init') { return true; } if (cmd === 'heartbeat_start') { return true; } if (cmd === 'heartbeat_stop') { return true; } if (cmd === 'heartbeat_tick') { return { status: 'ok', alerts: [], checked_items: 3, timestamp: new Date().toISOString(), } as HeartbeatResult; } if (cmd === 'heartbeat_get_status') { return { running: false, last_tick: null, next_tick: null, config: _args?.config || null, }; } // Reflection commands if (cmd === 'reflection_reflect') { return { patterns: [], improvements: [], identity_proposals: [], new_memories: 0, timestamp: new Date().toISOString(), }; } if (cmd === 'reflection_get_history') { return []; } if (cmd === 'reflection_get_state') { return { conversations_since_reflection: 0, last_reflection_time: null, last_reflection_agent_id: null, }; } return null; }), })); // ============================================= // Heartbeat Tests (via intelligenceClient) // ============================================= describe('Heartbeat (via intelligenceClient)', () => { const defaultConfig: HeartbeatConfig = { enabled: true, interval_minutes: 30, quiet_hours_start: null, quiet_hours_end: null, notify_channel: 'ui', proactivity_level: 'standard', max_alerts_per_tick: 5, }; beforeEach(() => { localStorageMock.clear(); vi.clearAllMocks(); }); describe('init', () => { it('initializes heartbeat with config', async () => { await expect( intelligenceClient.heartbeat.init('test-agent', defaultConfig) ).resolves.toBe(true); }); }); describe('tick', () => { it('returns heartbeat result', async () => { const result = await intelligenceClient.heartbeat.tick('test-agent'); expect(result).toHaveProperty('status'); expect(result).toHaveProperty('alerts'); expect(result).toHaveProperty('checked_items'); expect(result).toHaveProperty('timestamp'); }); it('returns ok status when no issues', async () => { const result = await intelligenceClient.heartbeat.tick('test-agent'); expect(result.status).toBe('ok'); }); }); describe('start/stop', () => { it('starts heartbeat', async () => { await expect( intelligenceClient.heartbeat.start('test-agent') ).resolves.toBeUndefined(); }); it('stops heartbeat', async () => { await expect( intelligenceClient.heartbeat.stop('test-agent') ).resolves.toBeUndefined(); }); }); }); // ============================================= // Reflection Tests (via intelligenceClient) // ============================================= describe('Reflection (via intelligenceClient)', () => { beforeEach(() => { localStorageMock.clear(); vi.clearAllMocks(); }); describe('reflect', () => { it('returns reflection result', async () => { const result = await intelligenceClient.reflection.reflect('test-agent', []); expect(result).toHaveProperty('patterns'); expect(result).toHaveProperty('improvements'); expect(result).toHaveProperty('identity_proposals'); expect(result).toHaveProperty('new_memories'); expect(result).toHaveProperty('timestamp'); }); }); describe('getHistory', () => { it('returns reflection history', async () => { const history = await intelligenceClient.reflection.getHistory(); expect(Array.isArray(history)).toBe(true); }); }); describe('getState', () => { it('returns reflection state', async () => { const state = await intelligenceClient.reflection.getState(); expect(state).toHaveProperty('conversations_since_reflection'); expect(state).toHaveProperty('last_reflection_time'); }); }); });