ClarityAI / tests /test_api.py
gauthambinoy
Deploy ClarityAI backend to HuggingFace Spaces
0890729
Raw
History Blame Contribute Delete
4 kB
"""
Integration tests for key ClarityAI API endpoints.
These tests use a lightweight async HTTP client backed by the FastAPI app
directly (no real server needed). Heavy ML models are intentionally not
loaded during the test run — tests focus on routing, schema validation, and
error-handling behaviour.
"""
from __future__ import annotations
import pytest
# ---------------------------------------------------------------------------
# /api/v1/health
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_health_returns_200(client):
"""Health endpoint must return HTTP 200 with a 'healthy' status."""
resp = await client.get("/api/v1/health")
assert resp.status_code == 200
@pytest.mark.asyncio
async def test_health_response_schema(client):
"""Health response must include all required fields."""
resp = await client.get("/api/v1/health")
body = resp.json()
required_fields = {
"status", "model_version", "uptime_seconds",
"loaded_models", "ollama_available", "database", "timestamp",
}
assert required_fields.issubset(body.keys())
@pytest.mark.asyncio
async def test_health_status_value(client):
"""Health endpoint status field must be 'healthy'."""
resp = await client.get("/api/v1/health")
assert resp.json()["status"] == "healthy"
# ---------------------------------------------------------------------------
# /api/v1/history
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_history_returns_200(client):
"""History endpoint returns 200 even when the database is empty."""
resp = await client.get("/api/v1/history")
assert resp.status_code == 200
@pytest.mark.asyncio
async def test_history_response_schema(client):
"""History response must contain pagination fields."""
resp = await client.get("/api/v1/history")
body = resp.json()
assert "page" in body
assert "limit" in body
assert "total" in body
assert "results" in body
assert isinstance(body["results"], list)
@pytest.mark.asyncio
async def test_history_default_pagination(client):
"""History endpoint default page is 1."""
resp = await client.get("/api/v1/history")
assert resp.json()["page"] == 1
@pytest.mark.asyncio
async def test_history_invalid_page_raises_422(client):
"""Passing page=0 (below minimum) must return 422 Unprocessable Entity."""
resp = await client.get("/api/v1/history?page=0")
assert resp.status_code == 422
# ---------------------------------------------------------------------------
# /api/v1/detect — validation only (no ML model required)
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_detect_empty_text_returns_422(client):
"""Sending an empty text string must return 422."""
resp = await client.post("/api/v1/detect", json={"text": ""})
assert resp.status_code == 422
@pytest.mark.asyncio
async def test_detect_invalid_mode_returns_422(client):
"""Sending an invalid mode must return 422."""
resp = await client.post(
"/api/v1/detect",
json={"text": "Some valid text here.", "mode": "invalid_mode"},
)
assert resp.status_code == 422
@pytest.mark.asyncio
async def test_detect_missing_text_returns_422(client):
"""Sending a request with no text field must return 422."""
resp = await client.post("/api/v1/detect", json={"mode": "fast"})
assert resp.status_code == 422
# ---------------------------------------------------------------------------
# OpenAPI schema sanity
# ---------------------------------------------------------------------------
@pytest.mark.asyncio
async def test_openapi_schema_accessible(client):
"""OpenAPI JSON schema endpoint must be reachable."""
resp = await client.get("/api/v1/openapi.json")
assert resp.status_code == 200
assert "paths" in resp.json()