id-ocr-engine / tests /test_api.py
Kevin-KES
Deploy current main to HF Space
50c6ee2
Raw
History Blame Contribute Delete
4.97 kB
import io
import pytest
from main import create_app
from config import Config
class TestConfig(Config):
API_KEY = "test-key-123"
DEBUG = True
@pytest.fixture
def app():
app = create_app(TestConfig)
app.config["TESTING"] = True
return app
@pytest.fixture
def client(app):
return app.test_client()
class TestHealthCheck:
def test_health_no_auth_required(self, client):
resp = client.get("/health")
assert resp.status_code in (200, 503)
data = resp.get_json()
assert "status" in data
assert "uptime_seconds" in data
def test_health_returns_checks(self, client):
resp = client.get("/health")
data = resp.get_json()
assert "checks" in data
assert "upload_directory" in data["checks"]
class TestAuth:
def test_no_api_key_returns_401(self, client):
resp = client.post("/api/ocr")
assert resp.status_code == 401
def test_wrong_api_key_returns_401(self, client):
resp = client.post("/api/ocr", headers={"X-API-Key": "wrong-key"})
assert resp.status_code == 401
def test_correct_api_key_passes_auth(self, client):
# Will get 400 (no doc_type) but not 401
resp = client.post("/api/ocr", headers={"X-API-Key": "test-key-123"})
assert resp.status_code == 400
class TestOCREndpoint:
def test_missing_doc_type_returns_400(self, client):
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
)
assert resp.status_code == 400
assert "doc_type is required" in resp.get_json()["error"]
def test_invalid_doc_type_returns_400(self, client):
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
data={"doc_type": "invalid_type"},
)
assert resp.status_code == 400
assert "Invalid doc_type" in resp.get_json()["error"]
def test_no_file_returns_400(self, client):
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
data={"doc_type": "sa_id_card"},
)
assert resp.status_code == 400
assert "No front image" in resp.get_json()["error"]
def test_invalid_file_type_returns_400(self, client):
data = {
"front": (io.BytesIO(b"not an image"), "test.txt"),
"doc_type": "sa_id_card",
}
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
data=data,
content_type="multipart/form-data",
)
assert resp.status_code == 400
assert "Invalid file type" in resp.get_json()["error"]
def test_back_rejected_for_non_id_card(self, client):
data = {
"front": (io.BytesIO(b"\x89PNG\r\n"), "front.png"),
"back": (io.BytesIO(b"\x89PNG\r\n"), "back.png"),
"doc_type": "sa_id_book",
}
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
data=data,
content_type="multipart/form-data",
)
assert resp.status_code == 400
assert "only accepted for doc_type=sa_id_card" in resp.get_json()["error"]
def test_legacy_file_key_accepted(self, client):
"""Legacy 'file' key should work as front image."""
data = {
"file": (io.BytesIO(b"not an image"), "test.txt"),
"doc_type": "sa_id_card",
}
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
data=data,
content_type="multipart/form-data",
)
# 400 for invalid file type (not 400 for missing file)
assert resp.status_code == 400
assert "Invalid file type" in resp.get_json()["error"]
def test_request_id_in_response(self, client):
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123", "X-Request-ID": "test-req-123"},
data={"doc_type": "sa_id_card"},
)
assert resp.headers.get("X-Request-ID") == "test-req-123"
def test_request_id_generated_if_missing(self, client):
resp = client.post(
"/api/ocr",
headers={"X-API-Key": "test-key-123"},
data={"doc_type": "sa_id_card"},
)
assert resp.headers.get("X-Request-ID") is not None
class TestWarmEndpoint:
def test_warm_no_auth_required(self, client):
resp = client.get("/warm")
assert resp.status_code == 200
data = resp.get_json()
assert "status" in data
assert "engines" in data
class TestNotFound:
def test_unknown_route_returns_404(self, client):
resp = client.get("/api/unknown", headers={"X-API-Key": "test-key-123"})
assert resp.status_code == 404
data = resp.get_json()
assert "error" in data