from src.backend.config import settings import pytest from unittest.mock import AsyncMock, MagicMock, patch def test_settings_loads_api_key(): assert settings.api_key == "test-key-12345" def test_settings_loads_db_path(): assert "test.db" in settings.db_path def test_settings_loads_worker_url(): assert settings.worker_url == "http://localhost:3001" def test_settings_loads_claude_model(): assert settings.claude_model == "claude-sonnet-4-6" def test_settings_loads_rate_limits(): assert settings.rate_limit_per_minute == 100 assert settings.rate_limit_per_hour == 1000 @pytest.mark.asyncio async def test_init_db_creates_tables(): from src.backend.db.database import init_db, get_db await init_db() db = await get_db() try: cursor = await db.execute( "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name" ) tables = [row[0] for row in await cursor.fetchall()] assert "topics" in tables assert "requests" in tables finally: await db.close() @pytest.mark.asyncio async def test_foreign_keys_enabled(): from src.backend.db.database import init_db, get_db await init_db() db = await get_db() try: cursor = await db.execute("PRAGMA foreign_keys") row = await cursor.fetchone() assert row[0] == 1 finally: await db.close() def test_topic_create_model_validates(): from src.backend.models.api import TopicCreate topic = TopicCreate( name="coding", system_prompt="You are an expert coder.", summary="Coding questions", model="claude-sonnet-4-6", ) assert topic.name == "coding" assert topic.model == "claude-sonnet-4-6" def test_topic_create_model_optional_fields(): from src.backend.models.api import TopicCreate topic = TopicCreate(name="coding", system_prompt="You are an expert coder.") assert topic.summary == "" assert topic.model is None def test_request_create_model_validates(): from src.backend.models.api import RequestCreate req = RequestCreate( prompt="How to do X?", topic_id="550e8400-e29b-41d4-a716-446655440000", ) assert req.session_id is None assert req.model is None assert req.summarize is False def test_model_validation_rejects_invalid(): from src.backend.models.api import TopicCreate from pydantic import ValidationError with pytest.raises(ValidationError): TopicCreate(name="test", system_prompt="test", model="gpt-4") def test_envelope_ok(): from src.backend.models.api import ok result = ok({"key": "value"}) assert result == {"success": True, "data": {"key": "value"}, "error": None} def test_envelope_fail(): from src.backend.models.api import fail result = fail("NOT_FOUND", "Resource not found") assert result["success"] is False assert result["error"]["code"] == "NOT_FOUND" @pytest.mark.asyncio async def test_worker_client_process(): from src.backend.services.worker_client import WorkerClient mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { "success": True, "result": "The answer is 42.", "session_id": "sess-123", } with patch("src.backend.services.worker_client.httpx.AsyncClient") as MockClient: mock_client_instance = AsyncMock() mock_client_instance.post.return_value = mock_response mock_client_instance.__aenter__ = AsyncMock(return_value=mock_client_instance) mock_client_instance.__aexit__ = AsyncMock(return_value=False) MockClient.return_value = mock_client_instance client = WorkerClient() result = await client.process( prompt="What is the answer?", system_prompt="You know everything.", model="claude-sonnet-4-6", ) assert result["success"] is True assert result["result"] == "The answer is 42." @pytest.mark.asyncio async def test_worker_client_summarize(): from src.backend.services.worker_client import WorkerClient mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { "success": True, "summary": "[2026-05-25] Discussed the meaning of life.", } with patch("src.backend.services.worker_client.httpx.AsyncClient") as MockClient: mock_client_instance = AsyncMock() mock_client_instance.post.return_value = mock_response mock_client_instance.__aenter__ = AsyncMock(return_value=mock_client_instance) mock_client_instance.__aexit__ = AsyncMock(return_value=False) MockClient.return_value = mock_client_instance client = WorkerClient() result = await client.summarize( exchanges=[{"prompt": "What?", "result": "42."}], mode="incremental", ) assert result["success"] is True assert "Discussed" in result["summary"] @pytest.mark.asyncio async def test_worker_client_health(): from src.backend.services.worker_client import WorkerClient mock_response = AsyncMock() mock_response.status_code = 200 with patch("src.backend.services.worker_client.httpx.AsyncClient") as MockClient: mock_client_instance = AsyncMock() mock_client_instance.get.return_value = mock_response mock_client_instance.__aenter__ = AsyncMock(return_value=mock_client_instance) mock_client_instance.__aexit__ = AsyncMock(return_value=False) MockClient.return_value = mock_client_instance client = WorkerClient() is_healthy = await client.health() assert is_healthy is True