9f2d624b4f
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
"""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
|