Spaces:
Running
Running
File size: 5,307 Bytes
aefac4f 9659593 696f787 aefac4f 696f787 aefac4f 9659593 aefac4f 9659593 aefac4f 9659593 aefac4f 9659593 aefac4f 9659593 aefac4f 9659593 aefac4f | 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 135 136 137 138 139 140 141 142 | """
Tests for codebase fixes: confidence cap, validator, thresholds, schema validation
"""
import json
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from api.app.models.schemas import HealthResponse, StructuredAnalysisRequest
from api.app.services.extraction import predict_disease_simple as api_predict
from scripts.chat import predict_disease_simple as cli_predict
from src.biomarker_validator import BiomarkerValidator
# ============================================================================
# Confidence cap tests
# ============================================================================
class TestConfidenceCap:
"""Verify confidence never exceeds 1.0"""
def test_api_confidence_capped_at_one(self):
# Glucose>126 (+0.4), Glucose>180 (+0.2), HbA1c>=6.5 (+0.5) = 1.1 raw
result = api_predict({"Glucose": 200, "HbA1c": 7.0})
assert result["confidence"] <= 1.0
def test_cli_confidence_capped_at_one(self):
result = cli_predict({"Glucose": 200, "HbA1c": 7.0})
assert result["confidence"] <= 1.0
def test_confidence_is_exactly_one_for_high_diabetes(self):
result = api_predict({"Glucose": 200, "HbA1c": 7.0})
assert result["confidence"] == 1.0
def test_confidence_not_capped_when_below_one(self):
result = api_predict({"Glucose": 130})
assert result["confidence"] == 0.4
# ============================================================================
# Updated critical threshold tests
# ============================================================================
class TestCriticalThresholds:
"""Verify biomarker_references.json has clinically appropriate critical thresholds"""
def setup_method(self):
config_path = Path(__file__).parent.parent / "config" / "biomarker_references.json"
with open(config_path) as f:
self.refs = json.load(f)["biomarkers"]
def test_glucose_critical_high_is_emergency(self):
assert self.refs["Glucose"]["critical_high"] >= 300
def test_glucose_critical_low_is_emergency(self):
assert self.refs["Glucose"]["critical_low"] <= 54
def test_hba1c_critical_high_is_emergency(self):
assert self.refs["HbA1c"]["critical_high"] >= 10
def test_troponin_critical_high_above_normal(self):
normal_max = self.refs["Troponin"]["normal_range"]["max"]
assert self.refs["Troponin"]["critical_high"] > normal_max
def test_bmi_critical_high_is_morbid(self):
assert self.refs["BMI"]["critical_high"] >= 40
def test_systolic_bp_critical_high_is_crisis(self):
assert self.refs["Systolic Blood Pressure"]["critical_high"] >= 180
def test_diastolic_bp_critical_low_is_shock(self):
assert self.refs["Diastolic Blood Pressure"]["critical_low"] <= 40
# ============================================================================
# Validator threshold removal tests
# ============================================================================
class TestValidatorNoThreshold:
"""Verify validator flags all out-of-range values (no 15% threshold)"""
def setup_method(self):
self.validator = BiomarkerValidator()
def test_slightly_high_glucose_is_flagged(self):
"""Glucose=105 is above normal max=100 — should be HIGH, not NORMAL"""
flag = self.validator.validate_biomarker("Glucose", 105.0)
assert flag.status == "HIGH"
def test_slightly_low_hemoglobin_is_flagged(self):
"""Hemoglobin=13.0 for male (min=13.5) should be LOW"""
flag = self.validator.validate_biomarker("Hemoglobin", 13.0, gender="male")
assert flag.status == "LOW"
def test_normal_glucose_stays_normal(self):
flag = self.validator.validate_biomarker("Glucose", 90.0)
assert flag.status == "NORMAL"
def test_critical_high_glucose_flagged(self):
flag = self.validator.validate_biomarker("Glucose", 500.0)
assert flag.status == "CRITICAL_HIGH"
def test_high_glucose_200_not_critical(self):
"""Glucose=200 is above normal but below critical_high=400"""
flag = self.validator.validate_biomarker("Glucose", 200.0)
assert flag.status == "HIGH"
# ============================================================================
# Pydantic schema validation tests
# ============================================================================
class TestSchemaValidation:
"""Verify Pydantic models enforce constraints correctly"""
def test_structured_request_rejects_empty_biomarkers(self):
import pytest
with pytest.raises(Exception):
StructuredAnalysisRequest(biomarkers={})
def test_structured_request_accepts_valid_biomarkers(self):
req = StructuredAnalysisRequest(biomarkers={"Glucose": 100.0})
assert req.biomarkers == {"Glucose": 100.0}
def test_health_response_uses_llm_status_field(self):
resp = HealthResponse(
status="healthy",
timestamp="2025-01-01T00:00:00",
llm_status="connected",
vector_store_loaded=True,
available_models=["test"],
uptime_seconds=100.0,
version="1.0.0",
)
assert resp.llm_status == "connected"
|