Files
pdf_oralia_vibe/tests/test_reextraction.py
Bertrand Benjamin 9cf0a89aab feat: expose la re-extraction verifiable d'un document
POST /api/documents/{id}/re-extract retourne desormais, en plus des donnees
re-extraites, les donnees actuelles et les tags des depenses : un seul appel
suffit pour comparer avant/apres et reporter les tags. L'endpoint devient
synchrone pour que FastAPI l'execute dans un thread, l'extraction bloquant
plusieurs secondes par PDF.

PUT /api/documents/{id} enregistre la nouvelle extraction en visant le
document par son ID (save_document(replace_document_id=...)) : une extraction
qui corrige la reference ou la date met a jour le bon document au lieu d'en
creer un second, et refuse la collision avec un document voisin. Le PDF
stocke est conserve.

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

120 lines
4.1 KiB
Python

"""Tests du remplacement d'un document par son ID (re-extraction validee)."""
import copy
from datetime import date
import pytest
from plesna_gerance.database import storage
from plesna_gerance.database.models import Depense, Document, Tag
from plesna_gerance.database.service import DatabaseService, DuplicateDocumentError
@pytest.fixture
def pdf_bytes():
"""Contenu binaire arbitraire : le stockage ne relit jamais le PDF ici."""
return b"%PDF-1.4 fake"
def test_replace_document_met_a_jour_meme_si_la_reference_change(
db_session, sample_data
):
"""Une re-extraction qui corrige la reference met a jour le meme document.
C'est tout l'interet du remplacement par ID : avec un enregistrement par
(reference, date), ce cas creerait un second document.
"""
service = DatabaseService(db_session)
original = service.save_document(data=sample_data)
original_id = original.id
new_data = copy.deepcopy(sample_data)
new_data["metadata"]["document"]["reference"] = "REF001-CORRIGEE"
updated = service.save_document(data=new_data, replace_document_id=original_id)
assert db_session.query(Document).count() == 1
assert updated.reference == "REF001-CORRIGEE"
assert updated.date == date(2024, 1, 15)
def test_replace_document_conserve_le_pdf_et_reecrit_le_json(
db_session, sample_data, pdf_bytes
):
service = DatabaseService(db_session)
original = service.save_document(
data=sample_data, source_file="cr.pdf", pdf_content=pdf_bytes
)
pdf_path, json_path = original.pdf_path, original.json_path
assert pdf_path and json_path
new_data = copy.deepcopy(sample_data)
new_data["situation_locataires"][0]["locataire"]["nom"] = "MARTIN"
# Re-enregistrement sans PDF : celui deja stocke doit etre conserve.
updated = service.save_document(
data=new_data, source_file="cr.pdf", replace_document_id=original.id
)
assert updated.pdf_path == pdf_path
assert updated.json_path == json_path
assert storage.read_pdf(pdf_path) == pdf_bytes
stored = storage.read_json(json_path)
assert stored["situation_locataires"][0]["locataire"]["nom"] == "MARTIN"
def test_replace_document_refuse_une_collision_avec_un_autre_document(
db_session, sample_data
):
"""La nouvelle extraction ne doit pas ecraser un document voisin."""
service = DatabaseService(db_session)
premier = service.save_document(data=sample_data)
autre_data = copy.deepcopy(sample_data)
autre_data["metadata"]["document"]["date"] = "2024-02-15"
service.save_document(data=autre_data)
# Le premier document re-extrait porterait la (reference, date) du second.
collision_data = copy.deepcopy(autre_data)
with pytest.raises(DuplicateDocumentError):
service.save_document(data=collision_data, replace_document_id=premier.id)
assert db_session.query(Document).count() == 2
def test_replace_document_inconnu_leve_value_error(db_session, sample_data):
service = DatabaseService(db_session)
with pytest.raises(ValueError):
service.save_document(data=sample_data, replace_document_id=4242)
def test_get_depenses_tags_puis_report_sur_la_nouvelle_extraction(
db_session, sample_data
):
"""Les tags actuels sont indexes comme les operations, et reportables."""
service = DatabaseService(db_session)
tag = Tag(nom="ENTRETIEN")
db_session.add(tag)
db_session.flush()
original = service.save_document(
data=sample_data, depenses_tags=[{"index": 0, "tag_id": tag.id}]
)
tags = service.get_depenses_tags(original.id)
assert tags == [{"index": 0, "tag_id": tag.id, "tag_nom": "ENTRETIEN"}]
# Report sur une nouvelle extraction du meme document.
new_data = copy.deepcopy(sample_data)
new_data["recapitulatif_operations"][0]["montants"]["debit"] = 75.0
updated = service.save_document(
data=new_data,
depenses_tags=[{"index": t["index"], "tag_id": t["tag_id"]} for t in tags],
replace_document_id=original.id,
)
depenses = db_session.query(Depense).filter_by(document_id=updated.id).all()
assert len(depenses) == 1
assert depenses[0].debit == 75.0
assert depenses[0].tag_id == tag.id