""" Integration tests for the FastAPI endpoints using TestClient. """ import io import pytest from fastapi.testclient import TestClient class TestHealthEndpoint: def test_returns_200(self, client): resp = client.get("/health") assert resp.status_code == 200 def test_status_is_healthy(self, client): data = client.get("/health").json() assert data["status"] == "healthy" def test_all_processors_listed(self, client): data = client.get("/health").json() processors = data["processors"] for name in ("image_enhancer", "line_extractor", "ocr_processor", "svg_generator"): assert name in processors class TestInfoEndpoint: def test_returns_200(self, client): assert client.get("/api/info").status_code == 200 def test_returns_processing_options(self, client): data = client.get("/api/info").json() assert "processing_options" in data def test_all_options_listed(self, client): opts = client.get("/api/info").json()["processing_options"] for key in ("enhance", "extract_lines", "run_ocr", "generate_svg", "run_ai"): assert key in opts class TestProcessEndpoint: def test_returns_200_with_valid_image(self, client, drawing_file): resp = client.post("/api/process", files={"file": drawing_file}) assert resp.status_code == 200 def test_response_has_required_fields(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() for field in ("filename", "original_size", "processing_steps", "processing_time_s"): assert field in data def test_enhance_step_runs_by_default(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() assert "image_enhancement" in data["processing_steps"] assert "enhanced_image" in data def test_line_extraction_step_runs_by_default(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() assert "line_extraction" in data["processing_steps"] assert "detected_lines" in data def test_ocr_step_runs_by_default(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() assert "ocr" in data["processing_steps"] assert "ocr_results" in data def test_svg_not_generated_by_default(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() assert "svg_generation" not in data["processing_steps"] def test_svg_generated_when_requested(self, client, drawing_file): resp = client.post( "/api/process", files={"file": drawing_file}, data={"generate_svg": "true"}, ) data = resp.json() assert "svg_generation" in data["processing_steps"] assert "svg_output" in data def test_enhance_only_skips_other_steps(self, client, drawing_file): resp = client.post( "/api/process", files={"file": drawing_file}, data={"enhance": "true", "extract_lines": "false", "run_ocr": "false"}, ) data = resp.json() assert "image_enhancement" in data["processing_steps"] assert "line_extraction" not in data["processing_steps"] assert "ocr" not in data["processing_steps"] def test_detected_lines_is_integer(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() assert isinstance(data.get("detected_lines"), int) def test_processing_time_is_float(self, client, drawing_file): data = client.post("/api/process", files={"file": drawing_file}).json() assert isinstance(data["processing_time_s"], float) assert data["processing_time_s"] > 0 def test_invalid_file_returns_400(self, client): fake_file = ("bad.png", io.BytesIO(b"not an image"), "image/png") resp = client.post("/api/process", files={"file": fake_file}) assert resp.status_code == 400 def test_original_size_matches_image(self, client, drawing_bytes): # Our synthetic image is 800×600 file = ("drawing.png", io.BytesIO(drawing_bytes), "image/png") data = client.post("/api/process", files={"file": file}).json() size = data["original_size"] assert size["width"] == 800 assert size["height"] == 600 class TestAnalyzeEndpoint: def test_returns_501_without_api_key(self, client, drawing_file, monkeypatch): monkeypatch.setenv("ANTHROPIC_API_KEY", "") resp = client.post("/api/analyze", files={"file": drawing_file}) assert resp.status_code == 501 def test_error_message_mentions_api_key(self, client, drawing_file, monkeypatch): monkeypatch.setenv("ANTHROPIC_API_KEY", "") data = client.post("/api/analyze", files={"file": drawing_file}).json() assert "ANTHROPIC_API_KEY" in data["detail"]