File size: 2,585 Bytes
1e732dd
 
 
 
 
 
 
696f787
1e732dd
696f787
1e732dd
 
 
 
 
 
 
 
 
 
 
 
 
 
9659593
1e732dd
 
 
 
 
 
 
 
 
 
 
 
 
 
9659593
1e732dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""
Tests for the production FastAPI app (src/main.py) — endpoint smoke tests.

These tests use FastAPI's TestClient with mocked backing services
so they run without Docker infrastructure.
"""

from unittest.mock import patch

import pytest
from fastapi.testclient import TestClient


@pytest.fixture
def client():
    """Create a test client with mocked services."""
    # We need to prevent the lifespan from actually connecting to services
    with patch("src.main.lifespan") as mock_lifespan:
        # Use a no-op lifespan
        from contextlib import asynccontextmanager

        @asynccontextmanager
        async def _noop_lifespan(app):
            import time

            app.state.start_time = time.time()
            app.state.version = "2.0.0-test"
            app.state.opensearch_client = None
            app.state.embedding_service = None
            app.state.cache = None
            app.state.ollama_client = None
            app.state.tracer = None
            app.state.rag_service = None
            app.state.ragbot_service = None
            yield

        mock_lifespan.side_effect = _noop_lifespan

        from src.main import create_app

        app = create_app()
        app.router.lifespan_context = _noop_lifespan
        with TestClient(app) as tc:
            yield tc


def test_root(client: TestClient):
    resp = client.get("/")
    assert resp.status_code == 200
    data = resp.json()
    assert data["name"] == "MediGuard AI"
    assert "endpoints" in data


def test_health(client: TestClient):
    resp = client.get("/health")
    assert resp.status_code == 200
    data = resp.json()
    assert data["status"] == "healthy"
    assert "version" in data


def test_ask_no_service(client: TestClient):
    """Without RAG service, /ask should return 503."""
    resp = client.post("/ask", json={"question": "What is diabetes?"})
    assert resp.status_code == 503


def test_search_no_service(client: TestClient):
    """Without OpenSearch, /search should return 503."""
    resp = client.post("/search", json={"query": "diabetes", "top_k": 5})
    assert resp.status_code == 503


def test_analyze_no_service(client: TestClient):
    """Without RagBot, /analyze/structured should return 503."""
    resp = client.post(
        "/analyze/structured",
        json={"biomarkers": {"Glucose": 185.0}},
    )
    assert resp.status_code == 503


def test_validation_error(client: TestClient):
    """Invalid request should return 422."""
    resp = client.post("/ask", json={"question": "ab"})  # too short
    assert resp.status_code == 422