IT-Stock/tests/test_materiels.py
maxsoch 7ce6540924 Refonte des listings et arborescence de catégories à profondeur illimitée
Catégorie/SousCategorie fusionnées en un seul modèle auto-référencé
(parent_id), pour permettre une imbrication sans limite de niveaux. Les
listings matériels/catégories/destinataires passent en lignes repliées
(<details>) avec recherche côté serveur, ce qui corrige le débordement
horizontal du tableau tout-en-input et reste utilisable sur de longues
listes. Style de l'écran de scan également retravaillé (frontend-design).
2026-07-14 19:06:37 +02:00

117 lines
3.4 KiB
Python

"""
Tests du flux principal : créer une arborescence de catégories, créer un
matériel, le retrouver par scan, ajuster son stock, et vérifier que
l'alerte de stock bas se déclenche (elle est simplement affichée dans la
console tant qu'aucun SMTP n'est configuré, voir app/email_alerts.py).
"""
from sqlmodel import Session, select
from app.models import Categorie, DestinataireAlerte, Materiel
def _creer_sous_categorie(session: Session) -> Categorie:
"""Crée une petite arborescence à 2 niveaux (Ordinateurs > Portables)
pour les tests qui n'ont pas besoin de tester la profondeur illimitée
elle-même — voir test_categories.py pour ça."""
racine = Categorie(nom="Ordinateurs")
session.add(racine)
session.commit()
session.refresh(racine)
enfant = Categorie(nom="Portables", parent_id=racine.id)
session.add(enfant)
session.commit()
session.refresh(enfant)
return enfant
def test_creation_materiel(client, session):
sous_categorie = _creer_sous_categorie(session)
reponse = client.post(
"/materiels",
data={
"nom": "PC Dell XPS 13",
"categorie_id": sous_categorie.id,
"code_barre": "1234567890123",
"quantite": "5",
"seuil_alerte": "2",
},
follow_redirects=False,
)
assert reponse.status_code == 303
materiel = session.exec(select(Materiel)).first()
assert materiel is not None
assert materiel.quantite == 5
def test_scan_trouve_le_materiel_par_code_barre(client, session):
sous_categorie = _creer_sous_categorie(session)
session.add(
Materiel(
nom="Câble RJ45 2m",
categorie_id=sous_categorie.id,
code_barre="9998887776665",
quantite=10,
)
)
session.commit()
reponse = client.post("/scan", data={"code_barre": "9998887776665"})
assert reponse.status_code == 200
assert "Câble RJ45 2m" in reponse.text
def test_scan_code_inconnu_affiche_une_erreur(client, session):
_creer_sous_categorie(session)
reponse = client.post("/scan", data={"code_barre": "0000000000000"})
assert reponse.status_code == 200
assert "Aucun matériel" in reponse.text
def test_alerte_declenchee_sous_le_seuil(client, session, capsys):
sous_categorie = _creer_sous_categorie(session)
materiel = Materiel(
nom="Souris USB",
categorie_id=sous_categorie.id,
quantite=3,
seuil_alerte=5,
)
session.add(materiel)
session.commit()
session.refresh(materiel)
session.add(DestinataireAlerte(email="it-dept@clinique.local"))
session.commit()
reponse = client.post(f"/scan/{materiel.id}/ajuster", data={"delta": "-1"})
assert reponse.status_code == 200
sortie = capsys.readouterr().out
assert "EMAIL SIMULÉ" in sortie
assert "Souris USB" in sortie
def test_pas_alerte_si_stock_suffisant(client, session, capsys):
sous_categorie = _creer_sous_categorie(session)
materiel = Materiel(
nom="Clavier USB",
categorie_id=sous_categorie.id,
quantite=10,
seuil_alerte=5,
)
session.add(materiel)
session.commit()
session.refresh(materiel)
session.add(DestinataireAlerte(email="it-dept@clinique.local"))
session.commit()
client.post(f"/scan/{materiel.id}/ajuster", data={"delta": "-1"})
sortie = capsys.readouterr().out
assert "EMAIL SIMULÉ" not in sortie