"""Text-layer extraction, evidence bbox matching, and crop rendering.""" import os import pytest fitz = pytest.importorskip("pymupdf") from backend import config from backend.text_layer import ( attach_text_layers, coverage_gaps, extract_text_layers, find_evidence_bbox, render_crop, ) EVIDENCE = "(5) 2X6 STUD PACK @ 16 IN O.C." def _make_pdf(path, pages): """pages: list of str ('' = effectively blank page).""" doc = fitz.open() for text in pages: page = doc.new_page(width=612, height=792) if text: page.insert_text((72, 72), text, fontsize=11) doc.save(str(path)) doc.close() return str(path) @pytest.fixture def text_pdf(tmp_path): return _make_pdf(tmp_path / "set.pdf", [EVIDENCE, ""]) def test_extract_text_layers(text_pdf): layers = extract_text_layers(text_pdf) assert set(layers) == {1, 2} assert layers[1]["has_text_layer"] is True assert "2X6 STUD PACK" in layers[1]["text"] assert layers[1]["words"], "expected word-level bboxes" assert all("bbox" in w and len(w["bbox"]) == 4 for w in layers[1]["words"]) def test_blank_page_below_min_chars(text_pdf): layers = extract_text_layers(text_pdf) assert layers[2]["has_text_layer"] is False def test_disabled_returns_empty(text_pdf, monkeypatch): monkeypatch.setattr(config, "TEXT_LAYER_ENABLED", False) assert extract_text_layers(text_pdf) == {} def test_attach_text_layers(text_pdf, tmp_path): pages = [{"page_number": 1}, {"page_number": 2}] words = attach_text_layers(text_pdf, pages, text_dir=str(tmp_path / "text")) assert pages[0]["text_layer"] and "STUD PACK" in pages[0]["text_layer"] assert pages[1]["text_layer"] is None assert words[1] and not words[2] assert os.path.isfile(tmp_path / "text" / "page-001.txt") assert not os.path.exists(tmp_path / "text" / "page-002.txt") def test_find_evidence_bbox_exact(text_pdf): words = extract_text_layers(text_pdf)[1]["words"] bbox = find_evidence_bbox(words, EVIDENCE) assert bbox is not None assert bbox[2] > bbox[0] and bbox[3] > bbox[1] def test_find_evidence_bbox_fuzzy(text_pdf): # Vision quotes imperfectly: wrong count token, rest exact. words = extract_text_layers(text_pdf)[1]["words"] bbox = find_evidence_bbox(words, "(2) 2X6 STUD PACK @ 16 IN O.C.") assert bbox is not None def test_find_evidence_bbox_miss(text_pdf): words = extract_text_layers(text_pdf)[1]["words"] assert find_evidence_bbox(words, "PENTHOUSE EXHAUST FAN EF-9") is None assert find_evidence_bbox([], EVIDENCE) is None assert find_evidence_bbox(words, "") is None def test_render_crop(text_pdf): words = extract_text_layers(text_pdf)[1]["words"] bbox = find_evidence_bbox(words, EVIDENCE) crop = render_crop(text_pdf, 1, bbox) assert crop is not None # Decodes as an image of plausible size (margin around the text line). doc = fitz.open(stream=crop, filetype="jpeg") pix = doc[0].get_pixmap() assert pix.width > 100 and pix.height > 20 doc.close() def test_render_crop_bad_page(text_pdf): assert render_crop(text_pdf, 99, (0, 0, 10, 10)) is None def test_coverage_gaps(): pages = [{"page_number": 1, "text_layer": "some real text"}, {"page_number": 2, "text_layer": "more text"}, {"page_number": 3, "text_layer": None}] sheets = [{"page_number": 1, "assertions": [{"id": "a"}]}, {"page_number": 2, "assertions": []}] assert coverage_gaps(pages, sheets) == [2]