feat: durcit l'exécution SQL IA, borne les uploads et ajoute des tests
- sql_executor: remplace le filtre regex fragile par une autorisation SQLite (set_authorizer) en complément de mode=ro ; rejette les instructions multiples - uploads: lecture bornée des PDF (helper read_upload_limited, limite 20 Mo, HTTP 413) branchée sur /extract et /save-with-pdf - tests: suite pytest (54 tests) couvrant amounts, dates, storage, sql_executor, uploads et DatabaseService.save_document ; pytest ajouté en dépendance dev Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
79
tests/conftest.py
Normal file
79
tests/conftest.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Fixtures partagées pour les tests."""
|
||||
|
||||
import pytest
|
||||
|
||||
from plesna_gerance.database import connection
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def db_session(tmp_path, monkeypatch):
|
||||
"""Session SQLAlchemy sur une base SQLite temporaire et isolée.
|
||||
|
||||
Configure aussi PLESNA_DB_PATH / PLESNA_STORAGE_PATH pour que les helpers
|
||||
qui lisent l'environnement (sql_executor, storage) ciblent le temp dir.
|
||||
"""
|
||||
db_path = tmp_path / "test.sqlite"
|
||||
monkeypatch.setenv("PLESNA_DB_PATH", str(db_path))
|
||||
monkeypatch.setenv("PLESNA_STORAGE_PATH", str(tmp_path / "documents"))
|
||||
|
||||
connection.reset_connection()
|
||||
connection.init_db(db_path)
|
||||
|
||||
SessionLocal = connection.get_session_factory()
|
||||
session = SessionLocal()
|
||||
try:
|
||||
yield session
|
||||
finally:
|
||||
session.close()
|
||||
connection.reset_connection()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_data():
|
||||
"""Données extraites minimales mais complètes pour save_document."""
|
||||
return {
|
||||
"metadata": {
|
||||
"document": {
|
||||
"reference": "REF001",
|
||||
"date": "2024-01-15",
|
||||
"type": "COMPTE RENDU DE GESTION",
|
||||
},
|
||||
"immeuble": {
|
||||
"code": "IMM1",
|
||||
"adresse": "4 RUE SERVIENT",
|
||||
"ville": "LYON",
|
||||
"code_postal": "69003",
|
||||
},
|
||||
"editeur": {"nom": "ORALIA", "siret": "12345678901234"},
|
||||
"solde": {
|
||||
"montant": 100.0,
|
||||
"type": "crediteur",
|
||||
"date_arrete": "2024-01-15",
|
||||
},
|
||||
},
|
||||
"situation_locataires": [
|
||||
{
|
||||
"lot": {"numero": "001", "type": "Appartement"},
|
||||
"locataire": {"nom": "DUPONT"},
|
||||
"lignes": [
|
||||
{
|
||||
"type": "loyer",
|
||||
"periode": {"debut": "2024-01-01", "fin": "2024-01-31"},
|
||||
"loyers": 500.0,
|
||||
"total": 500.0,
|
||||
"regles": 500.0,
|
||||
"impayes": 0.0,
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
"recapitulatif_operations": [
|
||||
{
|
||||
"categorie": "DEPENSES_LOCATIVES",
|
||||
"sous_categorie": "Nettoyage",
|
||||
"fournisseur": "ACME",
|
||||
"description": "Nettoyage immeuble",
|
||||
"montants": {"debit": 50.0},
|
||||
}
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user