churnflow-api / tests /test_api.py
aleem1234's picture
Fix requirements.txt dependencies
38c1a14
Raw
History Blame Contribute Delete
3.19 kB
import os
import sys
from fastapi.testclient import TestClient
# Ensure project root is in path
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if project_root not in sys.path:
sys.path.append(project_root)
from src.api import app
def test_health_check() -> None:
"""Verifies that the /health API endpoint responds with success status."""
with TestClient(app) as client:
response = client.get("/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
assert "model_loaded" in data
def test_predict_endpoint() -> None:
"""Verifies that a valid customer prediction payload yields correct structure and values."""
payload = {
"recency": 10,
"frequency": 5,
"monetary": 250.0,
"basket_size": 8.0,
"avg_days_between": 20.0,
"recent_orders_ratio": 0.8,
"is_uk": 1
}
with TestClient(app) as client:
response = client.post("/predict", json=payload)
assert response.status_code == 200
data = response.json()
assert "churn_probability" in data
assert "risk_tier" in data
assert "recommendation" in data
assert isinstance(data["churn_probability"], float)
def test_predict_batch_endpoint() -> None:
"""Verifies that a valid list of customer profiles returns batched prediction arrays."""
payload = {
"customers": [
{
"recency": 10,
"frequency": 5,
"monetary": 250.0,
"basket_size": 8.0
},
{
"recency": 200,
"frequency": 1,
"monetary": 50.0,
"basket_size": 2.0
}
]
}
with TestClient(app) as client:
response = client.post("/predict_batch", json=payload)
assert response.status_code == 200
data = response.json()
assert "predictions" in data
assert len(data["predictions"]) == 2
for pred in data["predictions"]:
assert "churn_probability" in pred
assert "risk_tier" in pred
assert "recommendation" in pred
def test_monitor_drift_endpoint() -> None:
"""Verifies that the /monitor endpoint returns the statistical drift analysis report."""
with TestClient(app) as client:
response = client.get("/monitor")
assert response.status_code == 200
data = response.json()
assert "drift_detected" in data
assert "drift_status" in data
assert "message" in data
def test_shadow_stats_endpoint() -> None:
"""Verifies that the /shadow_stats endpoint returns Champion vs Challenger metrics."""
with TestClient(app) as client:
response = client.get("/shadow_stats")
assert response.status_code == 200
data = response.json()
assert "total_predictions" in data
assert "champion_mean" in data
assert "challenger_mean" in data
assert "mean_absolute_deviation" in data
assert "agreement_rate" in data
assert "recent_logs" in data