#!/usr/bin/env python3 """ Tests for Dashboard API endpoints. """ import sys from pathlib import Path import tempfile import sqlite3 import json from datetime import datetime # Add parent directory to path sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent.parent)) try: from fastapi.testclient import TestClient from fastapi import FastAPI from server.dashboard_api import router except ImportError as e: print(f"⚠️ Import error: {e}") print(" Install dependencies: cd mcp-server && pip install -r requirements.txt") sys.exit(1) # Create test app app = FastAPI() app.include_router(router) client = TestClient(app) # Test data directory TEST_DATA_DIR = Path(__file__).parent.parent.parent / "data" / "test_dashboard" TEST_DATA_DIR.mkdir(parents=True, exist_ok=True) def setup_test_databases(): """Create test databases.""" # Conversations DB conversations_db = TEST_DATA_DIR / "conversations.db" if conversations_db.exists(): conversations_db.unlink() conn = sqlite3.connect(str(conversations_db)) cursor = conn.cursor() cursor.execute(""" CREATE TABLE sessions ( session_id TEXT PRIMARY KEY, agent_type TEXT NOT NULL, created_at TEXT NOT NULL, last_activity TEXT NOT NULL, message_count INTEGER DEFAULT 0 ) """) cursor.execute(""" INSERT INTO sessions (session_id, agent_type, created_at, last_activity, message_count) VALUES ('test-session-1', 'family', '2026-01-01T00:00:00', '2026-01-01T01:00:00', 5), ('test-session-2', 'work', '2026-01-02T00:00:00', '2026-01-02T02:00:00', 10) """) conn.commit() conn.close() # Timers DB timers_db = TEST_DATA_DIR / "timers.db" if timers_db.exists(): timers_db.unlink() conn = sqlite3.connect(str(timers_db)) cursor = conn.cursor() cursor.execute(""" CREATE TABLE timers ( id TEXT PRIMARY KEY, name TEXT, duration_seconds INTEGER, target_time TEXT, created_at TEXT NOT NULL, status TEXT DEFAULT 'active', type TEXT DEFAULT 'timer', message TEXT ) """) cursor.execute(""" INSERT INTO timers (id, name, duration_seconds, created_at, status, type) VALUES ('timer-1', 'Test Timer', 300, '2026-01-01T00:00:00', 'active', 'timer') """) conn.commit() conn.close() # Memory DB memory_db = TEST_DATA_DIR / "memory.db" if memory_db.exists(): memory_db.unlink() conn = sqlite3.connect(str(memory_db)) cursor = conn.cursor() cursor.execute(""" CREATE TABLE memories ( id TEXT PRIMARY KEY, category TEXT NOT NULL, content TEXT NOT NULL, confidence REAL DEFAULT 1.0, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, source TEXT ) """) conn.commit() conn.close() # Tasks directory tasks_dir = TEST_DATA_DIR / "tasks" / "home" tasks_dir.mkdir(parents=True, exist_ok=True) (tasks_dir / "todo").mkdir(exist_ok=True) (tasks_dir / "in-progress").mkdir(exist_ok=True) # Create test task task_file = tasks_dir / "todo" / "test-task.md" task_file.write_text("""--- title: Test Task status: todo priority: medium created: 2026-01-01 --- Test task content """) return { "conversations": conversations_db, "timers": timers_db, "memory": memory_db, "tasks": tasks_dir } def test_status_endpoint(): """Test /api/dashboard/status endpoint.""" # Temporarily patch database paths import server.dashboard_api as dashboard_api original_conversations = dashboard_api.CONVERSATIONS_DB original_timers = dashboard_api.TIMERS_DB original_memory = dashboard_api.MEMORY_DB original_tasks = dashboard_api.TASKS_DIR try: test_dbs = setup_test_databases() dashboard_api.CONVERSATIONS_DB = test_dbs["conversations"] dashboard_api.TIMERS_DB = test_dbs["timers"] dashboard_api.MEMORY_DB = test_dbs["memory"] dashboard_api.TASKS_DIR = test_dbs["tasks"] response = client.get("/api/dashboard/status") assert response.status_code == 200 data = response.json() assert data["status"] == "operational" assert "databases" in data assert "counts" in data assert data["counts"]["conversations"] == 2 assert data["counts"]["active_timers"] == 1 assert data["counts"]["pending_tasks"] == 1 print("✅ Status endpoint test passed") return True finally: dashboard_api.CONVERSATIONS_DB = original_conversations dashboard_api.TIMERS_DB = original_timers dashboard_api.MEMORY_DB = original_memory dashboard_api.TASKS_DIR = original_tasks def test_list_conversations(): """Test /api/dashboard/conversations endpoint.""" import server.dashboard_api as dashboard_api original_conversations = dashboard_api.CONVERSATIONS_DB try: test_dbs = setup_test_databases() dashboard_api.CONVERSATIONS_DB = test_dbs["conversations"] response = client.get("/api/dashboard/conversations?limit=10&offset=0") assert response.status_code == 200 data = response.json() assert "conversations" in data assert "total" in data assert data["total"] == 2 assert len(data["conversations"]) == 2 print("✅ List conversations endpoint test passed") return True finally: dashboard_api.CONVERSATIONS_DB = original_conversations def test_get_conversation(): """Test /api/dashboard/conversations/{id} endpoint.""" import server.dashboard_api as dashboard_api original_conversations = dashboard_api.CONVERSATIONS_DB try: test_dbs = setup_test_databases() dashboard_api.CONVERSATIONS_DB = test_dbs["conversations"] # Add messages table conn = sqlite3.connect(str(test_dbs["conversations"])) cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT NOT NULL, role TEXT NOT NULL, content TEXT NOT NULL, timestamp TEXT NOT NULL, FOREIGN KEY (session_id) REFERENCES sessions(session_id) ) """) cursor.execute(""" INSERT INTO messages (session_id, role, content, timestamp) VALUES ('test-session-1', 'user', 'Hello', '2026-01-01T00:00:00'), ('test-session-1', 'assistant', 'Hi there!', '2026-01-01T00:00:01') """) conn.commit() conn.close() response = client.get("/api/dashboard/conversations/test-session-1") assert response.status_code == 200 data = response.json() assert data["session_id"] == "test-session-1" assert "messages" in data assert len(data["messages"]) == 2 print("✅ Get conversation endpoint test passed") return True finally: dashboard_api.CONVERSATIONS_DB = original_conversations def test_list_timers(): """Test /api/dashboard/timers endpoint.""" import server.dashboard_api as dashboard_api original_timers = dashboard_api.TIMERS_DB try: test_dbs = setup_test_databases() dashboard_api.TIMERS_DB = test_dbs["timers"] response = client.get("/api/dashboard/timers") assert response.status_code == 200 data = response.json() assert "timers" in data assert "reminders" in data assert len(data["timers"]) == 1 print("✅ List timers endpoint test passed") return True finally: dashboard_api.TIMERS_DB = original_timers def test_list_tasks(): """Test /api/dashboard/tasks endpoint.""" import server.dashboard_api as dashboard_api original_tasks = dashboard_api.TASKS_DIR try: test_dbs = setup_test_databases() dashboard_api.TASKS_DIR = test_dbs["tasks"] response = client.get("/api/dashboard/tasks") assert response.status_code == 200 data = response.json() assert "tasks" in data assert len(data["tasks"]) >= 1 print("✅ List tasks endpoint test passed") return True finally: dashboard_api.TASKS_DIR = original_tasks def test_list_logs(): """Test /api/dashboard/logs endpoint.""" import server.dashboard_api as dashboard_api original_logs = dashboard_api.LOGS_DIR try: logs_dir = TEST_DATA_DIR / "logs" logs_dir.mkdir(exist_ok=True) # Create test log file log_file = logs_dir / "llm_2026-01-01.log" log_file.write_text(json.dumps({ "timestamp": "2026-01-01T00:00:00", "level": "INFO", "agent_type": "family", "message": "Test log entry" }) + "\n") dashboard_api.LOGS_DIR = logs_dir response = client.get("/api/dashboard/logs?limit=10") assert response.status_code == 200 data = response.json() assert "logs" in data assert len(data["logs"]) >= 1 print("✅ List logs endpoint test passed") return True finally: dashboard_api.LOGS_DIR = original_logs if __name__ == "__main__": print("=" * 60) print("Dashboard API Test Suite") print("=" * 60) print() try: test_status_endpoint() test_list_conversations() test_get_conversation() test_list_timers() test_list_tasks() test_list_logs() print() print("=" * 60) print("✅ All Dashboard API tests passed!") print("=" * 60) except Exception as e: print(f"\n❌ Test failed: {e}") import traceback traceback.print_exc() sys.exit(1)