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.
72 lines
2.7 KiB
Python
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()
|