Spaces:
Running
Running
| """ | |
| Tests for the OCR API endpoint. | |
| """ | |
| import sys | |
| import os | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from unittest.mock import patch, AsyncMock | |
| # Add project root to sys.path | |
| sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) | |
| from main import app | |
| client = TestClient(app) | |
| def mock_ocr_router(): | |
| with patch("app.api.ocr.ocr_router") as mock: | |
| mock.extract = AsyncMock() | |
| yield mock | |
| def test_ocr_endpoint_no_file(): | |
| """Missing file should return 422 (Unprocessable Entity).""" | |
| response = client.post("/api/ai/ocr", headers={"X-API-Key": "test-api-key"}) | |
| def test_ocr_endpoint_invalid_file_type(): | |
| """Non-image file should return 400.""" | |
| files = {"file": ("test.txt", b"hello world", "text/plain")} | |
| data = {"document_type": "id_card"} | |
| response = client.post("/api/ai/ocr", files=files, data=data, headers={"X-API-Key": "test-api-key"}) | |
| assert response.status_code == 400 | |
| assert "not an image" in response.json()["detail"] | |
| def test_ocr_endpoint_missing_document_type(): | |
| """Missing document_type should return 422.""" | |
| dummy_image = ( | |
| b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01" | |
| b"\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\x00\x01" | |
| b"\x00\x00\x05\x00\x01\r\n-\xb4\x00\x00\x00\x00IEND\xaeB`\x82" | |
| ) | |
| files = {"file": ("test.png", dummy_image, "image/png")} | |
| response = client.post("/api/ai/ocr", files=files, headers={"X-API-Key": "test-api-key"}) | |
| assert response.status_code == 422 | |
| def test_ocr_endpoint_invalid_document_type(): | |
| """Invalid document_type value should return 422.""" | |
| dummy_image = ( | |
| b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01" | |
| b"\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\x00\x01" | |
| b"\x00\x00\x05\x00\x01\r\n-\xb4\x00\x00\x00\x00IEND\xaeB`\x82" | |
| ) | |
| files = {"file": ("test.png", dummy_image, "image/png")} | |
| data = {"document_type": "invalid_type"} | |
| response = client.post("/api/ai/ocr", files=files, data=data, headers={"X-API-Key": "test-api-key"}) | |
| assert response.status_code == 422 | |
| def test_ocr_endpoint_success(mock_ocr_router): | |
| """Valid image + document_type should return 200 with extracted data.""" | |
| mock_ocr_router.extract.return_value = {"_provider": "GeminiOCRProvider", "text": "صحيفة دعوى"} | |
| dummy_image = ( | |
| b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01" | |
| b"\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\x00\x01" | |
| b"\x00\x00\x05\x00\x01\r\n-\xb4\x00\x00\x00\x00IEND\xaeB`\x82" | |
| ) | |
| files = {"file": ("test.png", dummy_image, "image/png")} | |
| data = {"document_type": "id_card"} | |
| response = client.post("/api/ai/ocr", files=files, data=data, headers={"X-API-Key": "test-api-key"}) | |
| assert response.status_code == 200 | |
| result = response.json() | |
| assert result["text"] == "صحيفة دعوى" | |
| assert result["_provider"] == "GeminiOCRProvider" | |
| mock_ocr_router.extract.assert_called_once() | |