Worker: endpoint /recipes/dxf-compare con test (#83)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""POST /recipes/dxf-compare del worker (#83): forma della risposta ed errori."""
|
||||
import pytest
|
||||
|
||||
# Come test_worker.py: serve l'albero vision (Python >=3.13), altrimenti skipped.
|
||||
pytest.importorskip(
|
||||
"visionsuite.task",
|
||||
reason="the vision tree requires Python >=3.13; see test_worker.py",
|
||||
)
|
||||
|
||||
import base64
|
||||
import io
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
from PIL import Image
|
||||
|
||||
from src.vision.tests.test_costruttori import PX_PER_MM, SAMPLE_DXF, a_scene
|
||||
from src.vision_worker.main import app
|
||||
|
||||
|
||||
def _png(array: np.ndarray) -> bytes:
|
||||
buffer = io.BytesIO()
|
||||
Image.fromarray(array).save(buffer, format="PNG")
|
||||
return buffer.getvalue()
|
||||
|
||||
|
||||
async def _post(image: bytes, dxf: bytes, **data):
|
||||
transport = ASGITransport(app=app)
|
||||
async with AsyncClient(transport=transport, base_url="http://worker") as client:
|
||||
return await client.post(
|
||||
"/recipes/dxf-compare",
|
||||
files={"image": ("riferimento.png", image, "image/png"),
|
||||
"dxf": ("disegno.dxf", dxf, "application/octet-stream")},
|
||||
data={"px_per_mm": str(PX_PER_MM), "band_mm": "2.0", **data},
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dxf_compare_200_con_le_chiavi_del_contratto():
|
||||
inizio = time.monotonic()
|
||||
response = await _post(_png(a_scene(0.0)), SAMPLE_DXF.read_bytes())
|
||||
durata = time.monotonic() - inizio
|
||||
|
||||
assert response.status_code == 200, response.text
|
||||
body = response.json()
|
||||
assert {"graph", "files", "outputs", "overlay", "outcome"} <= set(body)
|
||||
assert set(body["files"]) == {"disegno.dxf", "calibrazione.json"}
|
||||
assert base64.b64decode(body["files"]["disegno.dxf"]) == SAMPLE_DXF.read_bytes()
|
||||
assert set(body["outputs"]) == {
|
||||
"dxf.points_in_pct", "dxf.distance_avg", "dxf.distance_min", "dxf.distance_max"}
|
||||
assert body["outputs"]["dxf.points_in_pct"] > 95.0
|
||||
assert body["graph"]["schema_version"] == 2
|
||||
print(f"\nW2 sulla scena di prova: {durata:.2f}s") # riportato nel rapporto
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dxf_compare_immagine_senza_pezzo_e_422():
|
||||
bianca = np.full((600, 800), 255, np.uint8)
|
||||
response = await _post(_png(bianca), SAMPLE_DXF.read_bytes())
|
||||
assert response.status_code == 422
|
||||
assert "pezzo" in response.json()["detail"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dxf_compare_dxf_illeggibile_e_422():
|
||||
response = await _post(_png(a_scene(0.0)), b"non e' un dxf")
|
||||
assert response.status_code == 422
|
||||
assert "DXF" in response.json()["detail"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dxf_compare_immagine_non_decodificabile_e_422():
|
||||
response = await _post(b"non e' un'immagine", SAMPLE_DXF.read_bytes())
|
||||
assert response.status_code == 422
|
||||
assert "not decodable" in response.json()["detail"].lower()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_dxf_compare_parametro_fuori_range_e_422():
|
||||
response = await _post(_png(a_scene(0.0)), SAMPLE_DXF.read_bytes(), polarity="grigio")
|
||||
assert response.status_code == 422
|
||||
Reference in New Issue
Block a user