Files
pointeuse-optimisator/app/tests/test_ui_refonte.py
Jacquin Antoine d760842121 Forfait d'astreinte : bonifié comme réalisé en journée du jour AS
Le forfait était suivi brut, sans bonification. Considéré réalisé en
journée du jour où il est attribué, il reçoit désormais le facteur
journée correspondant : ×1 en semaine, ×1,5 le samedi, ×2 le dimanche
ou un jour férié (suit les règles de ratios configurées). Toujours hors
heures travaillées ; affiché pondéré sur la ligne du jour, dans les
totaux du récapitulatif et expliqué dans Réglages.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-09-10 17:05:05 +02:00

116 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Refonte de l'interface : auto-enregistrement (plus de bouton ✓), menu
d'état unique (congé / férié / astreinte) et panneau aujourd'hui.
Vérifie le rendu de la page semaine et les réponses HTMX (swaps OOB) qui
régénèrent ces composants.
"""
import datetime as dt_module
import sys
# DATA_DIR temporaire est positionné par conftest.py avant l'import de models.
import models # noqa: F401
sys.path.insert(0, ".")
import main
from fastapi.testclient import TestClient
client = TestClient(main.app)
TODAY = "2026-07-17" # vendredi de la semaine 29 (cf. datetime gelé)
class _FrozenDatetime(dt_module.datetime):
@classmethod
def today(cls):
return cls(2026, 7, 17, 10, 30)
def _login(uid: str) -> dict:
import bcrypt
models.save_auth(uid, email=f"{uid}@x.fr",
password_hash=bcrypt.hashpw(b"x" * 12, bcrypt.gensalt()).decode())
r = client.post("/login/password",
data={"email": f"{uid}@x.fr", "password": "x" * 12},
follow_redirects=False)
assert r.status_code == 302, r.text
return {"user_id": r.cookies.get("user_id")}
def test_page_semaine_rend_les_nouveaux_composants(monkeypatch):
monkeypatch.setattr(main, "datetime", _FrozenDatetime)
cookies = _login("u-ui")
r = client.get("/semaine/2026/29", cookies=cookies, follow_redirects=False)
assert r.status_code == 200
# Auto-enregistrement : un témoin par jour, plus de bouton ✓ ni sa colonne
assert "btn-valider" not in r.text
assert "col-save" not in r.text
assert r.text.count('class="autosave"') == 7
assert 'hx-trigger="save-day"' in r.text
# Menu d'état : un par jour, options des cinq bascules
assert r.text.count('class="cg-menu"') == 7
assert "Congé matin" in r.text
assert "Jour férié" in r.text
assert 'cg-opt-chip as">AS</span>' in r.text # option jour d'astreinte
# Panneau aujourd'hui (le jour gelé appartient à la semaine affichée)
assert "today-panel" in r.text
assert "Aujourd'hui ·" in r.text # Jinja laisse l'apostrophe telle quelle
def test_pointage_htmx_rafrachit_panneau_et_compteurs(monkeypatch):
monkeypatch.setattr(main, "datetime", _FrozenDatetime)
cookies = _login("u-ui-pointage")
r = client.post(f"/pointage/{TODAY}", cookies=cookies,
data={"matin_entree": "08:00", "matin_sortie": "12:00"},
headers={"HX-Request": "true"}, follow_redirects=False)
assert r.status_code == 200
assert f'id="calc-{TODAY}-trav"' in r.text # compteurs OOB
assert "today-panel" in r.text # soldes + panneau re-rendus
def test_bascule_congen_regenere_le_menu_d_etat(monkeypatch):
monkeypatch.setattr(main, "datetime", _FrozenDatetime)
cookies = _login("u-ui-conge")
r = client.post(f"/conge/{TODAY}/matin", cookies=cookies,
headers={"HX-Request": "true"}, follow_redirects=False)
assert r.status_code == 200
# Le swap OOB régénère le bouton avec la pastille MA active
assert 'cg-chip st-ma">MA<' in r.text
assert 'id="cg-btn-' + TODAY + '"' in r.text
def test_retour_decale_affiche_le_credit_de_presence(monkeypatch):
"""Retour mercredi 11:00 (event mardi 22:39→23:49) : la colonne Travaillé
crédite les 2h de présence couvertes, avec badge et détail explicites."""
monkeypatch.setattr(main, "datetime", _FrozenDatetime)
cookies = _login("u-ui-credit")
client.post("/astreinte/2026-07-14/toggle", cookies=cookies, follow_redirects=False)
r = client.post("/pointage/2026-07-14", cookies=cookies,
data={"astreinte_debut": ["22:39"], "astreinte_fin": ["23:49"]},
headers={"HX-Request": "true"}, follow_redirects=False)
assert r.status_code == 200
# Le crédit s'affiche sur la ligne du lendemain (jour du retour décalé)
r = client.get("/semaine/2026/29", cookies=cookies, follow_redirects=False)
assert r.status_code == 200
assert 'class="calc-couvert"' in r.text
assert "+2h00 repos" in r.text
assert "matin 09:00→11:00" in r.text # détail des plages couvertes
assert "de présence comptées" in r.text # rappel dans le bloc astreinte
def test_forfait_bonifie_journee_affiche_dans_le_recap(monkeypatch):
"""Forfait 1h00 réglé + AS le samedi 18/07 : le récapitulatif montre le
forfait pondéré par la bonification journée du samedi (×1,5 → 1h30)."""
monkeypatch.setattr(main, "datetime", _FrozenDatetime)
cookies = _login("u-ui-forfait")
r = client.post("/settings/astreinte-forfait", cookies=cookies,
data={"astreinte_forfait": "01:00"}, follow_redirects=False)
assert r.status_code == 303, r.text
client.post("/astreinte/2026-07-18/toggle", cookies=cookies, follow_redirects=False)
r = client.get("/semaine/2026/29", cookies=cookies, follow_redirects=False)
assert r.status_code == 200, r.text
assert "forfait 1h00 → 1h30 pondérées" in r.text # ligne du jour (bloc AS)
assert "forfaits 1h00 → 1h30 pondérés" in r.text # totaux du récapitulatif
assert "considéré réalisé en journée" in r.text # explication au survol