"""Filtres de la page Depenses : plusieurs fournisseurs, et l'absence de tag. Le filtre fournisseur cherchait une sous-chaine, ce qui interdisait d'en comparer deux et retenait au passage leurs homonymes. Il retient desormais une liste de noms exacts. Le filtre tag, lui, ne savait pas demander « ce qui n'est pas encore tague » - c'est pourtant la question qui amorce le travail de tagging. Ces tests verrouillent aussi l'accord entre la table et le resume : les deux endpoints doivent voir le meme perimetre, sinon les totaux affiches ne sont pas ceux des lignes listees. """ import copy import pytest from plesna_gerance.database.models import Depense, Tag from plesna_gerance.database.service import DatabaseService @pytest.fixture def depenses_de_trois_fournisseurs(db_session, sample_data): """Quatre depenses : ACME (2), ACME SUD (1), BOREAL (1). « ACME SUD » est la pour verifier qu'une selection sur « ACME » ne l'emporte pas au passage, ce que faisait l'ancienne recherche. """ donnees = copy.deepcopy(sample_data) donnees["recapitulatif_operations"] = [ { "categorie": "DEPENSES_LOCATIVES", "fournisseur": "ACME", "description": "Nettoyage janvier", "montants": {"debit": 50.0}, }, { "categorie": "DEPENSES_LOCATIVES", "fournisseur": "ACME", "description": "Nettoyage fevrier", "montants": {"debit": 60.0}, }, { "categorie": "TRAVAUX", "fournisseur": "ACME SUD", "description": "Reprise peinture", "montants": {"debit": 200.0}, }, { "categorie": "TRAVAUX", "fournisseur": "BOREAL", "description": "Toiture", "montants": {"debit": 300.0}, }, ] DatabaseService(db_session).save_document(data=donnees) return donnees def _noms(lignes): """Les fournisseurs des lignes retournees, tries pour comparer sans l'ordre.""" return sorted(ligne["fournisseur"] for ligne in lignes) def test_retient_les_fournisseurs_demandes(api_client, depenses_de_trois_fournisseurs): reponse = api_client.get( "/api/analytics/depenses?fournisseur=ACME&fournisseur=BOREAL" ) assert reponse.status_code == 200 assert _noms(reponse.json()) == ["ACME", "ACME", "BOREAL"] def test_un_fournisseur_selectionne_exclut_ses_homonymes( api_client, depenses_de_trois_fournisseurs ): """« ACME » ne doit plus ramener « ACME SUD » : la selection est exacte.""" reponse = api_client.get("/api/analytics/depenses?fournisseur=ACME") assert _noms(reponse.json()) == ["ACME", "ACME"] def test_sans_fournisseur_demande_tout_reste_visible( api_client, depenses_de_trois_fournisseurs ): assert len(api_client.get("/api/analytics/depenses").json()) == 4 def test_le_resume_porte_sur_les_memes_lignes_que_la_table( api_client, depenses_de_trois_fournisseurs ): requete = "fournisseur=ACME&fournisseur=BOREAL" lignes = api_client.get(f"/api/analytics/depenses?{requete}").json() resume = api_client.get(f"/api/analytics/depenses/summary?{requete}").json() assert resume["total_count"] == len(lignes) assert resume["total_debit"] == pytest.approx( sum(ligne["debit"] for ligne in lignes) ) assert resume["total_debit"] == pytest.approx(410.0) def test_filtre_les_depenses_sans_tag( api_client, db_session, depenses_de_trois_fournisseurs ): """tag_id=0 demande les depenses non taggees, la ou l'omettre les prend toutes.""" tag = db_session.query(Tag).order_by(Tag.id).first() taggee = db_session.query(Depense).filter(Depense.fournisseur == "BOREAL").one() taggee.tag_id = tag.id db_session.flush() sans_tag = api_client.get("/api/analytics/depenses?tag_id=0").json() avec_ce_tag = api_client.get(f"/api/analytics/depenses?tag_id={tag.id}").json() toutes = api_client.get("/api/analytics/depenses").json() assert _noms(sans_tag) == ["ACME", "ACME", "ACME SUD"] assert _noms(avec_ce_tag) == ["BOREAL"] assert len(toutes) == len(sans_tag) + len(avec_ce_tag) def test_le_resume_par_tag_montre_les_non_taggees( api_client, depenses_de_trois_fournisseurs ): """La masse non taggee reste une part du camembert, pas un trou.""" resume = api_client.get("/api/analytics/depenses/summary").json() non_taggees = [part for part in resume["by_tag"] if part["tag_id"] is None] assert len(non_taggees) == 1 assert non_taggees[0]["count"] == 4 assert non_taggees[0]["total_debit"] == pytest.approx(610.0)