YELY_AI_Module / tests /test_api.py
danielxdata's picture
Module IA YELY - CRNN fine-tune, API FastAPI, interface demo
b510add
Raw
History Blame Contribute Delete
3.32 kB
import io
import unittest
from unittest.mock import patch
import numpy as np
import cv2
from fastapi.testclient import TestClient
from app import main
def _fake_jpeg_bytes(color=(200, 200, 200), size=(300, 200)):
img = np.full((size[1], size[0], 3), color, dtype=np.uint8)
ok, buf = cv2.imencode(".jpg", img)
assert ok
return buf.tobytes()
class TestAnalyzeEndpoint(unittest.TestCase):
def setUp(self):
self.client = TestClient(main.app)
def test_consistent_reading_returns_success(self):
fake_fields = [
{"field": "prix", "text": "10000", "confidence": 0.95},
{"field": "volume", "text": "14.28", "confidence": 0.9},
{"field": "prix_litre", "text": "700", "confidence": 0.85},
]
fake_quality = {"image_quality": "valid", "quality_score": 0.95,
"blur_variance": 500.0, "brightness": 120.0}
with patch.object(main, "_get_model", return_value=(None, None)), \
patch.object(main, "recognize_screen", return_value=fake_fields), \
patch.object(main, "estimate_image_quality", return_value=fake_quality):
resp = self.client.post(
"/analyze",
files={"image": ("pompe.jpg", _fake_jpeg_bytes(), "image/jpeg")},
data={"fuel_price": "700", "driver_id": "chauffeur-42"},
)
self.assertEqual(resp.status_code, 200)
body = resp.json()
self.assertTrue(body["success"])
self.assertEqual(body["detected_amount"], 10000.0)
self.assertAlmostEqual(body["detected_liters"], 14.28, places=2)
self.assertEqual(body["fuel_price"], 700.0)
self.assertEqual(body["driver_id"], "chauffeur-42")
self.assertIn("photo_reference", body)
# Champs techniques (moteur OCR, variante...) volontairement absents
# de la réponse — seuls les champs du cahier des charges sont exposés.
self.assertNotIn("ocr_engine", body)
self.assertNotIn("best_variant", body)
def test_inconsistent_reading_blocks(self):
fake_fields = [
{"field": "prix", "text": "10000", "confidence": 0.95},
{"field": "volume", "text": "20.00", "confidence": 0.9},
]
fake_quality = {"image_quality": "valid", "quality_score": 0.95,
"blur_variance": 500.0, "brightness": 120.0}
with patch.object(main, "_get_model", return_value=(None, None)), \
patch.object(main, "recognize_screen", return_value=fake_fields), \
patch.object(main, "estimate_image_quality", return_value=fake_quality):
resp = self.client.post(
"/analyze",
files={"image": ("pompe.jpg", _fake_jpeg_bytes(), "image/jpeg")},
data={"fuel_price": "875"},
)
body = resp.json()
self.assertFalse(body["success"])
self.assertIn("Incohérence", body["message"])
def test_unsupported_content_type_rejected(self):
resp = self.client.post(
"/analyze",
files={"image": ("pompe.txt", b"not an image", "text/plain")},
data={"fuel_price": "700"},
)
self.assertEqual(resp.status_code, 400)
if __name__ == "__main__":
unittest.main()