"""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