FarmerHelp / backend /tests /test_middleware.py
Gankit12's picture
All Code
b64de39
Raw
History Blame Contribute Delete
3.73 kB
"""
Tests for middleware and system-level endpoints.
Covers:
- Root endpoint
- Health check
- Request ID injection
- Response timing header
- Error handling (404, 422 envelopes)
- API versioning (v1 prefix)
"""
import pytest
class TestRootEndpoint:
"""Tests for GET /"""
def test_root(self, client):
resp = client.get("/")
assert resp.status_code == 200
body = resp.json()
assert body["status"] == "running"
assert "version" in body
assert "docs" in body
assert "v1" in body["api_versions"]
class TestHealthCheck:
"""Tests for GET /health"""
def test_health_check(self, client):
resp = client.get("/health")
assert resp.status_code == 200
body = resp.json()
assert body["status"] in ("healthy", "degraded")
assert "service" in body
assert "version" in body
assert "timestamp" in body
assert "database" in body
assert body["database"] in ("connected", "disconnected")
def test_health_components(self, client):
resp = client.get("/health")
body = resp.json()
assert "components" in body
assert "database" in body["components"]
assert "api" in body["components"]
assert body["components"]["api"]["status"] == "operational"
class TestRequestIDMiddleware:
"""Verify the X-Request-ID header is present on all responses."""
def test_request_id_generated(self, client):
resp = client.get("/")
rid = resp.headers.get("x-request-id")
assert rid is not None
assert len(rid) >= 10
def test_request_id_varies(self, client):
r1 = client.get("/")
r2 = client.get("/")
assert r1.headers["x-request-id"] != r2.headers["x-request-id"]
def test_client_supplied_request_id(self, client):
resp = client.get("/", headers={"X-Request-ID": "my-custom-id"})
assert resp.headers.get("x-request-id") == "my-custom-id"
class TestResponseTimingHeader:
"""Verify the X-Response-Time-Ms header is present."""
def test_timing_header(self, client):
resp = client.get("/health")
time_ms = resp.headers.get("x-response-time-ms")
assert time_ms is not None
assert float(time_ms) >= 0
class TestErrorHandling:
"""Verify error envelope structure."""
def test_404_has_detail(self, client):
resp = client.get("/api/disease/99999")
assert resp.status_code == 404
body = resp.json()
assert "detail" in body
def test_404_has_error_envelope(self, client):
resp = client.get("/api/disease/99999")
body = resp.json()
assert body["success"] is False
assert "error" in body
assert body["error"]["status_code"] == 404
def test_unknown_route_404(self, client):
resp = client.get("/api/nonexistent/endpoint")
assert resp.status_code == 404
def test_validation_error_422(self, client):
resp = client.get("/api/weather/forecast?pincode=abc")
assert resp.status_code == 422
body = resp.json()
assert "detail" in body
class TestAPIVersioning:
"""Verify both legacy and v1 prefixed routes are reachable."""
def test_legacy_disease_list(self, client):
resp = client.get("/api/disease/list")
assert resp.status_code == 200
def test_v1_disease_list(self, client):
resp = client.get("/api/v1/disease/list")
assert resp.status_code == 200
def test_v1_and_legacy_same_data(self, client):
r_legacy = client.get("/api/disease/list")
r_v1 = client.get("/api/v1/disease/list")
assert r_legacy.json()["total"] == r_v1.json()["total"]