foxygit / RPA-Remisser Log in
commits tags

/tests/test_ocr.py · 2.94 KB

raw
"""rpa/ocr.py – textlager-PDF, mönster-utplock, värde-nära-etikett."""

import pytest

from rpa import ocr


def test_apply_pattern_whole_match_by_default():
    txt = "Rad 1\nPersonnummer 19850101-1234 skräp\nRad 3"
    assert ocr.apply_pattern(txt, r"(19|20)?\d{6}[-+]?\d{4}") == "19850101-1234"
    assert ocr.apply_pattern(txt, r"\d{4}-\d{2}-\d{2}") == ""


def test_apply_pattern_named_group_wins():
    txt = "Läkare: Anna Andersson (leg)"
    assert ocr.apply_pattern(txt, r"Läkare:\s*(?P<value>[^()]+)").strip() == "Anna Andersson"


def test_apply_pattern_no_match_empty():
    assert ocr.apply_pattern("inget här", r"\d{10}") == ""


def test_value_near_same_line():
    txt = "Avsändare: Vårdcentralen Nordstan\nStatus Öppet"
    assert ocr.value_near(txt, [], "Avsändare", "same_line") == "Vårdcentralen Nordstan"
    assert ocr.value_near(txt, [], "Status", "same_line") == "Öppet"
    assert ocr.value_near(txt, [], "Saknas", "same_line") == ""


def test_value_near_below_uses_word_boxes():
    words = [
        {"text": "Personnummer", "x": 10, "y": 10, "w": 90, "h": 12},
        {"text": "19850101-1234", "x": 12, "y": 40, "w": 100, "h": 12},
        {"text": "Namn", "x": 300, "y": 10, "w": 40, "h": 12},
    ]
    text = "Personnummer   Namn\n19850101-1234"
    assert ocr.value_near(text, words, "Personnummer", "below") == "19850101-1234"


def test_pdf_text_layer_path(tmp_path):
    """En PDF med textlager ska läsas utan OCR (winocr rörs aldrig)."""
    pymupdf = pytest.importorskip("pymupdf")
    p = tmp_path / "remiss.pdf"
    doc = pymupdf.open()
    page = doc.new_page()
    page.insert_text((72, 72), "Personnummer: 19850101-1234\nRemissdatum: 2026-01-15", fontsize=12)
    doc.save(str(p))
    doc.close()

    text = ocr.pdf_to_text(p, "sv-SE")
    assert "19850101-1234" in text
    assert "2026-01-15" in text


def test_image_to_text_parses_winocr_shape(monkeypatch):
    fake = {
        "text": "Personnummer: 19850101-1234",
        "lines": [{
            "text": "Personnummer: 19850101-1234",
            "words": [
                {"text": "Personnummer:", "bounding_rect": {"x": 1, "y": 2, "width": 3, "height": 4}},
                {"text": "19850101-1234", "bounding_rect": {"x": 5, "y": 2, "width": 6, "height": 4}},
            ],
        }],
    }
    monkeypatch.setattr(ocr, "winocr", type("M", (), {"recognize_pil_sync": staticmethod(lambda *a: fake)}))
    text, words = ocr.image_to_text(object(), "sv-SE")
    assert text == "Personnummer: 19850101-1234"
    assert words[1]["text"] == "19850101-1234" and words[1]["x"] == 5


def test_image_to_text_missing_language_is_ocr_unavailable(monkeypatch):
    def boom(*_a):
        raise AssertionError('Add-WindowsCapability -Online -Name "Language.OCR~~~sv-SE~0.0.1.0"')

    monkeypatch.setattr(ocr, "winocr", type("M", (), {"recognize_pil_sync": staticmethod(boom)}))
    with pytest.raises(ocr.OcrUnavailable, match="Add-WindowsCapability"):
        ocr.image_to_text(object(), "sv-SE")