from __future__ import annotations from PIL import Image, ImageDraw from api.services.docling import extract from api.services.docling.regions import detect_response_regions_from_image def test_detects_grouped_answer_lines() -> None: image = Image.new("RGB", (900, 1200), "white") draw = ImageDraw.Draw(image) for y in (420, 470, 520): draw.line((160, y, 760, y), fill="black", width=3) candidates = detect_response_regions_from_image(image, page_index=2) line_regions = [c.to_mapper_dict() for c in candidates if c.region_type == "answer_lines"] assert line_regions best = line_regions[0] assert best["kind"] == "response" assert best["source"] == "ai" assert best["confirmed"] is False assert best["page_index"] == 2 assert best["line_count"] == 3 assert best["bbox"]["coord_origin"] == "TOPLEFT" assert best["bbox"]["w"] > 550 assert best["bbox"]["h"] > 80 def test_detects_answer_box() -> None: image = Image.new("RGB", (900, 1200), "white") draw = ImageDraw.Draw(image) draw.rectangle((140, 300, 780, 520), outline="black", width=3) candidates = detect_response_regions_from_image(image, page_index=0) boxes = [c.to_mapper_dict() for c in candidates if c.region_type == "answer_box"] assert boxes assert boxes[0]["bbox"]["w"] > 600 assert boxes[0]["bbox"]["h"] > 200 def test_detect_response_region_taxonomy_for_lines_and_boxes(): img = Image.new("RGB", (800, 1000), "white") draw = ImageDraw.Draw(img) for y in (220, 260, 300): draw.line((120, y, 680, y), fill="black", width=2) draw.rectangle((140, 520, 660, 640), outline="black", width=3) regions = detect_response_regions_from_image(img, min_confidence=0.1) types = {r.region_type for r in regions} assert "answer_lines" in types assert "answer_box" in types def test_attach_detected_response_regions_normalizes_taxonomy_and_uses_pdf_y(monkeypatch, tmp_path): pdf = tmp_path / "paper.pdf" pdf.write_bytes(b"%PDF test placeholder") parts = { "01.1": {"q": "01", "page": 1, "bbox": {"l": 50, "r": 80, "t": 700, "b": 680}, "regions": []}, "01.2": {"q": "01", "page": 1, "bbox": {"l": 50, "r": 80, "t": 500, "b": 480}, "regions": []}, } def fake_detect(path, min_confidence=0.32): return [{ "page_index": 0, "region_type": "answer-box", "confidence": 0.77, "bbox": {"x": 100, "y": 335, "w": 500, "h": 40}, "detection_method": "test", "meta": {"page_height_px": 1000, "page_height_pdf": 800}, }] monkeypatch.setattr(extract.region_mod, "detect_response_regions_from_pdf", fake_detect) attached, candidates = extract.attach_detected_response_regions(parts, str(pdf)) assert attached == 1 assert len(candidates) == 1 assert parts["01.1"]["regions"] == [] assert parts["01.2"]["regions"][0]["type"] == "answer_box" assert parts["01.2"]["regions"][0]["source"] == "opencv"