73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Dict, List, Optional, Tuple
|
|
|
|
from application.service import InvoiceProcessingService
|
|
from application.strategies import InvoiceExtractorStrategy
|
|
import application.service as service_module
|
|
|
|
|
|
class DummyExtractor(InvoiceExtractorStrategy):
|
|
"""Extractor mínimo para pruebas que devuelve un JSON fijo."""
|
|
def __init__(self, fail_first: bool = False) -> None:
|
|
self.fail_first = fail_first
|
|
self.calls = 0
|
|
|
|
def extract(self, images_b64: List[str], instruction: str) -> Dict[str, Any]:
|
|
self.calls += 1
|
|
if self.fail_first and self.calls == 1:
|
|
raise RuntimeError("forced failure")
|
|
return {
|
|
"raw": '{"ok": true}',
|
|
"usage": {},
|
|
}
|
|
|
|
|
|
def test_extract_full_from_pdf_propagates_tiff_page_range(monkeypatch, tmp_path) -> None:
|
|
dummy_pdf = tmp_path / "doc.tif"
|
|
dummy_pdf.write_bytes(b"fake")
|
|
|
|
captured: List[Dict[str, Any]] = []
|
|
|
|
def fake_document_to_images_bs64(path: str, **kwargs: Any) -> List[str]:
|
|
captured.append({"path": path, **kwargs})
|
|
return ["img"]
|
|
|
|
# Parchear el símbolo importado en el módulo de servicio
|
|
monkeypatch.setattr(service_module, "document_to_images_bs64", fake_document_to_images_bs64)
|
|
|
|
service = InvoiceProcessingService(DummyExtractor())
|
|
data, usage = service.extract_full_from_pdf(str(dummy_pdf), instruction="x", tiff_page_range=(2, 3))
|
|
|
|
assert data == {"ok": True}
|
|
assert isinstance(usage, dict)
|
|
assert captured, "Se esperaba al menos una llamada a document_to_images_bs64"
|
|
# Primera llamada (flujo normal) debe respetar el rango solicitado
|
|
assert captured[0].get("tiff_page_range") == (2, 3)
|
|
|
|
|
|
def test_extract_full_from_pdf_fallback_ignores_tiff_page_range(monkeypatch, tmp_path) -> None:
|
|
dummy_pdf = tmp_path / "doc2.tif"
|
|
dummy_pdf.write_bytes(b"fake")
|
|
|
|
captured: List[Dict[str, Any]] = []
|
|
|
|
def fake_document_to_images_bs64(path: str, **kwargs: Any) -> List[str]:
|
|
captured.append({"path": path, **kwargs})
|
|
return ["img"]
|
|
|
|
monkeypatch.setattr(service_module, "document_to_images_bs64", fake_document_to_images_bs64)
|
|
|
|
service = InvoiceProcessingService(DummyExtractor(fail_first=True))
|
|
data, usage = service.extract_full_from_pdf(str(dummy_pdf), instruction="x", tiff_page_range=(2, 3))
|
|
|
|
assert data == {"ok": True}
|
|
assert isinstance(usage, dict)
|
|
# Deben existir dos llamadas: una normal (que falla el extractor) y otra fallback
|
|
assert len(captured) == 2
|
|
assert captured[0].get("tiff_page_range") == (2, 3)
|
|
# En fallback NO debe propagarse el rango explícito
|
|
assert captured[1].get("tiff_page_range") is None
|
|
|
|
|