Files
odoo_ocr/tests/test_branches.py
fegger 570c8585a0 Use shared prompt loader and structured OCR response in branches
- Replaces duplicated _load_prompt() helpers with shared load_prompt().

- Classifier raises cleanly when no renderable pages exist.

- scanned_print, handwritten, and mixed_unknown branches now force

  response_format=OcrResponse and parse via client.parse_json().

- Adds branch tests for multi-page OCR and corrected invoice handling.
2026-08-21 16:44:19 +02:00

60 lines
2.2 KiB
Python

"""Tests for the scanned_print, handwritten, and mixed_unknown branches."""
from __future__ import annotations
from pathlib import Path
import pytest
from PIL import Image
from odoo_ocr.config import Settings
from odoo_ocr.pipeline.handwritten import process_handwritten
from odoo_ocr.pipeline.mixed_unknown import process_mixed_unknown
from odoo_ocr.pipeline.scanned_print import process_scanned_print
from tests.conftest import FakeVLMClient
def _fake_ocr_client(text: str = "Hello invoice 123") -> FakeVLMClient:
return FakeVLMClient(responses={"OCR engine": {"text": text}})
def _pages(count: int = 2) -> list[Image.Image]:
return [Image.new("RGB", (20, 20)) for _ in range(count)]
@pytest.mark.asyncio
async def test_scanned_print_multi_page() -> None:
settings = Settings()
client = _fake_ocr_client()
text = await process_scanned_print(Path("scan.jpg"), _pages(2), client, settings)
assert "--- Page 1 ---" in text
assert "--- Page 2 ---" in text
assert text.count("Hello invoice 123") == 2
assert all(call["model"] == settings.models.ocr for call in client.calls)
@pytest.mark.asyncio
async def test_scanned_print_rejects_invalid_json() -> None:
"""Branches no longer silently fall back to raw content; invalid JSON fails."""
client = FakeVLMClient(responses={"OCR engine": "plain text without json"})
with pytest.raises(ValueError, match="Response does not match schema"):
await process_scanned_print(Path("scan.jpg"), _pages(1), client, Settings())
@pytest.mark.asyncio
async def test_handwritten_extracts_text() -> None:
settings = Settings()
client = _fake_ocr_client("handwritten total 42")
text = await process_handwritten(Path("hand.jpg"), _pages(1), client, settings)
assert "handwritten total 42" in text
assert client.calls[0]["model"] == settings.models.ocr
@pytest.mark.asyncio
async def test_mixed_unknown_extracts_text() -> None:
settings = Settings()
client = _fake_ocr_client("mixed content text")
text = await process_mixed_unknown(Path("mixed.jpg"), _pages(1), client, settings)
assert "mixed content text" in text
assert client.calls[0]["model"] == settings.models.ocr