IT-Stock/tests/test_email_alerts.py
maxsoch a788bf4392 Résumé de stock dans les alertes + email récapitulatif planifié
L'alerte immédiate de stock bas inclut maintenant un résumé de tous les
articles actuellement sous leur seuil, pas seulement celui qui l'a
déclenchée. Ajout d'un second email, planifié via une expression cron
(RESUME_STOCK_CRON, APScheduler intégré à l'app — pas de cron système à
configurer) : stock bas en tête, puis le reste du stock groupé par
catégorie. scripts/envoyer_resume_stock.py permet de le déclencher
manuellement, ou de brancher l'envoi sur un cron système à la place.
2026-07-14 19:28:39 +02:00

72 lines
2.7 KiB
Python

"""
Tests du contenu des emails : le résumé des articles en stock bas ajouté à
l'alerte immédiate, et l'email récapitulatif périodique (stock bas puis
reste du stock groupé par catégorie).
"""
from sqlmodel import Session
from app.email_alerts import envoyer_resume_stock, verifier_et_alerter
from app.models import Categorie, DestinataireAlerte, Materiel
def _categorie(session: Session, nom: str) -> Categorie:
categorie = Categorie(nom=nom)
session.add(categorie)
session.commit()
session.refresh(categorie)
return categorie
def test_alerte_immediate_inclut_le_resume_des_stocks_bas(session: Session, capsys):
categorie = _categorie(session, "Ordinateurs")
# Un autre matériel déjà en stock bas, pour vérifier qu'il apparaît
# dans le résumé même s'il n'est pas celui qui déclenche l'alerte.
session.add(Materiel(nom="Souris USB", categorie_id=categorie.id, quantite=1, seuil_alerte=5))
materiel = Materiel(nom="PC Dell XPS 13", categorie_id=categorie.id, quantite=2, seuil_alerte=5)
session.add(materiel)
session.add(DestinataireAlerte(email="it-dept@clinique.local"))
session.commit()
session.refresh(materiel)
verifier_et_alerter(materiel, session)
sortie = capsys.readouterr().out
assert "Stock bas : PC Dell XPS 13" in sortie
assert "Tous les articles actuellement en stock bas" in sortie
assert "Souris USB" in sortie
assert "PC Dell XPS 13" in sortie
def test_resume_stock_separe_stock_bas_et_reste_du_stock(session: Session, capsys):
categorie = _categorie(session, "Réseau")
session.add(
Materiel(nom="Câble RJ45 2m", categorie_id=categorie.id, quantite=1, seuil_alerte=10)
)
session.add(Materiel(nom="Switch 8 ports", categorie_id=categorie.id, quantite=6))
session.add(DestinataireAlerte(email="it-dept@clinique.local"))
session.commit()
envoyer_resume_stock(session)
sortie = capsys.readouterr().out
assert "=== Stock bas ===" in sortie
assert "=== Reste du stock ===" in sortie
position_bas = sortie.index("=== Stock bas ===")
position_reste = sortie.index("=== Reste du stock ===")
position_cable = sortie.index("Câble RJ45 2m")
position_switch = sortie.index("Switch 8 ports")
# Le câble (en stock bas) doit apparaître dans la première section,
# le switch (pas en stock bas) dans la seconde.
assert position_bas < position_cable < position_reste
assert position_reste < position_switch
def test_resume_stock_sans_destinataire_ne_leve_pas_derreur(session: Session, capsys):
_categorie(session, "Réseau")
envoyer_resume_stock(session)
sortie = capsys.readouterr().out
assert "aucun destinataire" in sortie.lower()