Spaces:
Sleeping
Sleeping
| """ | |
| Tests for the API endpoints. | |
| Uses FastAPI TestClient for synchronous testing. | |
| No LLM calls required — tests use mock data and direct endpoint testing. | |
| """ | |
| import sys | |
| import os | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from main import app | |
| from core.security import get_or_create_master_key | |
| def client(): | |
| """Create a test client.""" | |
| return TestClient(app) | |
| def api_key(): | |
| """Get a valid API key.""" | |
| return get_or_create_master_key() | |
| # ============================================================ | |
| # Health Check | |
| # ============================================================ | |
| class TestHealthCheck: | |
| def test_health_returns_200(self, client): | |
| response = client.get("/api/health") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["status"] == "healthy" | |
| assert data["app"] == "PolicyEye" | |
| def test_health_no_auth_required(self, client): | |
| """Health check should work without API key.""" | |
| response = client.get("/api/health") | |
| assert response.status_code == 200 | |
| # ============================================================ | |
| # Authentication Tests | |
| # ============================================================ | |
| class TestAuthentication: | |
| def test_list_policies_requires_auth(self, client): | |
| """Endpoints should reject requests without API key.""" | |
| response = client.get("/api/policies") | |
| assert response.status_code == 401 | |
| def test_list_policies_rejects_invalid_key(self, client): | |
| """Invalid API key should be rejected.""" | |
| response = client.get( | |
| "/api/policies", | |
| headers={"X-API-Key": "invalid_key_123"} | |
| ) | |
| assert response.status_code == 403 | |
| def test_list_policies_accepts_valid_key(self, client, api_key): | |
| """Valid API key should work.""" | |
| response = client.get( | |
| "/api/policies", | |
| headers={"X-API-Key": api_key} | |
| ) | |
| assert response.status_code == 200 | |
| def test_upload_requires_auth(self, client): | |
| response = client.post("/api/upload-policy") | |
| assert response.status_code == 401 | |
| def test_check_eligibility_requires_auth(self, client): | |
| response = client.post("/api/check-eligibility", json={}) | |
| assert response.status_code == 401 | |
| def test_history_requires_auth(self, client): | |
| response = client.get("/api/history") | |
| assert response.status_code == 401 | |
| # ============================================================ | |
| # Input Validation Tests | |
| # ============================================================ | |
| class TestInputValidation: | |
| def test_upload_rejects_non_pdf(self, client, api_key): | |
| """Non-PDF files should be rejected.""" | |
| response = client.post( | |
| "/api/upload-policy", | |
| headers={"X-API-Key": api_key}, | |
| files={"file": ("test.txt", b"not a pdf", "text/plain")}, | |
| ) | |
| assert response.status_code == 400 | |
| assert "PDF" in response.json()["detail"] | |
| def test_eligibility_rejects_invalid_body(self, client, api_key): | |
| """Invalid request body should return 422.""" | |
| response = client.post( | |
| "/api/check-eligibility", | |
| headers={"X-API-Key": api_key}, | |
| json={"invalid": "data"}, | |
| ) | |
| assert response.status_code == 422 | |
| def test_history_rejects_invalid_limit(self, client, api_key): | |
| """Limit out of range should be rejected.""" | |
| response = client.get( | |
| "/api/history?limit=999", | |
| headers={"X-API-Key": api_key}, | |
| ) | |
| assert response.status_code == 400 | |
| def test_policy_not_found(self, client, api_key): | |
| """Non-existent policy should return 404.""" | |
| response = client.get( | |
| "/api/policies/99999", | |
| headers={"X-API-Key": api_key}, | |
| ) | |
| assert response.status_code == 404 | |
| # ============================================================ | |
| # Policy Listing | |
| # ============================================================ | |
| class TestPolicyListing: | |
| def test_empty_policies_list(self, client, api_key): | |
| """Should return empty list when no policies uploaded.""" | |
| response = client.get( | |
| "/api/policies", | |
| headers={"X-API-Key": api_key}, | |
| ) | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert "policies" in data | |
| assert isinstance(data["policies"], list) | |
| assert "count" in data | |
| if __name__ == "__main__": | |
| pytest.main([__file__, "-v", "--tb=short"]) | |