File size: 4,349 Bytes
4cea933
 
 
 
 
8c204aa
 
 
 
4cea933
 
b9f97a7
 
 
 
4cea933
8c204aa
 
 
 
 
 
b9f97a7
4cea933
 
 
 
b9f97a7
4cea933
 
 
 
155f199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c204aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604d53b
 
 
 
 
 
 
 
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import pytest
from fastapi.testclient import TestClient
import sys
import os

backend_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../backend'))
if backend_dir not in sys.path:
    sys.path.insert(0, backend_dir)

from main import app

@pytest.fixture
def client():
    with TestClient(app) as c:
        yield c

def test_health_endpoint(client):
    response = client.get("/health")
    assert response.status_code == 200
    data = response.json()
    assert "status" in data

def test_history_endpoint(client):
    response = client.get("/history")
    assert response.status_code == 200
    assert isinstance(response.json(), list)

def test_dataset_endpoint(client):
    response = client.get("/dataset")
    assert response.status_code == 200
    assert isinstance(response.json(), list)

def test_dataset_paginated_endpoint(client):
    response = client.get("/dataset?page=1&limit=25")
    assert response.status_code == 200
    data = response.json()
    assert isinstance(data, dict)
    assert "total" in data
    assert "rows" in data
    assert isinstance(data["rows"], list)
    assert len(data["rows"]) <= 25

def test_dataset_summary_endpoint(client):
    response = client.get("/dataset/summary")
    assert response.status_code == 200
    data = response.json()
    assert isinstance(data, dict)
    assert "summary" in data
    assert data["summary"]["total_records"] == 60000
    assert "target_distribution" in data
    assert "correlation_matrix" in data

def test_dataset_download_endpoint(client):
    response = client.get("/dataset/download")
    assert response.status_code == 200
    assert "text/csv" in response.headers.get("content-type", "")

def test_predict_endpoint_valid_telemetry(client):
    payload = {
        "Heart_Rate": 78.0,
        "SpO2_Level": 98.5,
        "Systolic_BP": 120.0,
        "Diastolic_BP": 80.0,
        "Body_Temp": 37.0
    }
    response = client.post("/predict", json=payload)
    assert response.status_code == 200
    data = response.json()
    if "error" not in data:
        assert "prediction" in data
        assert "prediction_label" in data
        assert "probability" in data
        assert "disease_probs" in data
        assert "model_outputs" in data

def test_predict_endpoint_acute_vitals(client):
    # Acute tachycardia + hypoxemia
    payload = {
        "Heart_Rate": 165.0,
        "SpO2_Level": 85.0,
        "Systolic_BP": 170.0,
        "Diastolic_BP": 105.0,
        "Body_Temp": 38.5
    }
    response = client.post("/predict", json=payload)
    assert response.status_code == 200
    data = response.json()
    if "error" not in data:
        assert "prediction" in data
        assert "prediction_label" in data
        assert data["prediction"] in [True, False, 0, 1]

def test_explain_endpoint(client):
    payload = {
        "Heart_Rate": 82.0,
        "SpO2_Level": 97.0,
        "Systolic_BP": 125.0,
        "Diastolic_BP": 82.0,
        "Body_Temp": 37.1
    }
    response = client.post("/explain", json=payload)
    assert response.status_code == 200
    data = response.json()
    if "error" not in data:
        assert "shap_values" in data
        assert "feature_names" in data
        assert len(data["shap_values"]) == len(data["feature_names"])

@pytest.mark.parametrize("model_name", ["rf", "svm", "logreg", "small_nn", "knn"])
@pytest.mark.parametrize("quantize", [False, True])
def test_export_tinyml_all_models_parameterized(client, model_name, quantize):
    response = client.get(f"/export_tinyml?model_name={model_name}&quantize={str(quantize).lower()}")
    assert response.status_code == 200
    data = response.json()
    if "error" in data:
        assert "not found" in data["error"].lower() or "cannot be exported" in data["error"].lower()
    else:
        assert "code" in data
        assert "#ifndef HEARTFLOW_MODEL_H" in data["code"]

def test_export_tinyml_invalid_model(client):
    response = client.get("/export_tinyml?model_name=unknown_nonexistent_model")
    assert response.status_code == 200
    data = response.json()
    assert "error" in data

def test_metrics_endpoint(client):
    response = client.get("/metrics")
    assert response.status_code == 200
    data = response.json()
    assert "ensemble_accuracy" in data
    assert "ensemble_f1_macro" in data
    assert "models" in data