Files
pdf_oralia_vibe/tests/test_extractor.py
Bertrand Benjamin ea5bdac18a refactor: retire les parseurs texte de repli
Les parseurs géométriques (par cellules de tableau) traitent les 5 PDF du
corpus sans jamais déclencher le repli : les parseurs texte étaient 586
lignes de regex fragiles, non testées, à maintenir à chaque évolution du
format de sortie. Les références golden sont inchangées après leur
suppression — l'extraction produit exactement la même chose.

Le parseur géométrique devient donc le seul chemin : ce qu'il ne lit pas
est perdu. L'orchestrateur distingue maintenant les deux cas :

- aucun lot lu -> ExtractionError (422 côté API). Un compte rendu sans
  lot n'existe pas : c'est le tableau qui n'a pas été reconnu, et mieux
  vaut échouer que d'enregistrer un document vide découvert bien plus
  tard, au moment de relire les chiffres ;
- aucune opération -> accepté. Un mois sans dépense reste plausible.

_extract_lot_code_from_description était la seule fonction encore
utilisée : elle rejoint utils.lots sous le nom
extract_lot_numero_from_description, à côté de normalize_lot_numero.
extract_text_from_pdf, sans appelant, disparaît au passage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 09:44:20 +02:00

64 lines
2.2 KiB
Python

"""Tests de l'orchestrateur d'extraction.
Depuis la suppression des parseurs texte de repli, le parseur geometrique est le
seul chemin : ce qu'il ne lit pas est definitivement perdu. L'orchestrateur doit
donc distinguer un PDF illisible d'un mois calme.
"""
import pytest
from plesna_gerance import extractor
from plesna_gerance.extractor import ExtractionError, extract_compte_rendu
from plesna_gerance.parsers.pdf import PdfContent
_UN_LOT = [{"lot": {"numero": "01", "type": "Appartement T2"}, "lignes": []}]
@pytest.fixture
def parseurs(monkeypatch):
"""Neutralise la lecture PDF et pilote ce que renvoie chaque parseur."""
def configurer(situation, operations):
monkeypatch.setattr(
extractor, "read_pdf", lambda _: PdfContent(text="", words=[])
)
monkeypatch.setattr(extractor, "extract_metadata", lambda *_: {})
monkeypatch.setattr(
extractor, "extract_situation_locataires_from_pdf", lambda _: situation
)
monkeypatch.setattr(
extractor, "extract_recapitulatif_operations_from_pdf", lambda _: operations
)
return configurer
def test_sans_aucun_lot_l_extraction_echoue(parseurs):
"""Un PDF dont le tableau des locataires est illisible doit lever."""
parseurs(situation=[], operations=[{"categorie": "DIVERS"}])
with pytest.raises(ExtractionError, match="Aucun lot"):
extract_compte_rendu("document.pdf")
def test_sans_operation_l_extraction_reussit(parseurs):
"""Un mois sans depense est plausible : la liste vide est acceptee."""
parseurs(situation=_UN_LOT, operations=[])
resultat = extract_compte_rendu("document.pdf")
assert resultat["situation_locataires"] == _UN_LOT
assert resultat["recapitulatif_operations"] == []
def test_extraction_complete(parseurs):
"""Cas nominal : les deux sections sont remontees telles quelles."""
operations = [{"categorie": "DEPENSES_LOCATIVES"}]
parseurs(situation=_UN_LOT, operations=operations)
resultat = extract_compte_rendu("document.pdf")
assert resultat["situation_locataires"] == _UN_LOT
assert resultat["recapitulatif_operations"] == operations
assert "metadata" in resultat