feat: monthly_stats() — médiane journalière et hebdomadaire

This commit is contained in:
2026-03-13 14:34:49 +01:00
parent d768156e0d
commit 6d5e58273f
2 changed files with 84 additions and 2 deletions

View File

@@ -43,8 +43,9 @@ def test_week_balance_negative():
from app.business.time_calc import count_day_types
from app.models import WorkEntry
from datetime import date
from app.models import WorkEntry, TimeSlot
from app.business.time_calc import monthly_stats
from datetime import date, time as dtime
def test_count_day_types_basic():
@@ -62,6 +63,63 @@ def test_count_day_types_empty():
assert count_day_types([]) == {}
def _entry(d: date, *slots: tuple[str, str]) -> WorkEntry:
"""Helper : crée un WorkEntry avec des TimeSlots."""
entry = WorkEntry(date=d, day_type="WORK")
entry.time_slots = [
TimeSlot(start_time=dtime(*[int(x) for x in s.split(":")]),
end_time=dtime(*[int(x) for x in e.split(":")]))
for s, e in slots
]
return entry
def _absence(d: date) -> WorkEntry:
"""Helper : crée un WorkEntry sans time_slots (0 min)."""
entry = WorkEntry(date=d, day_type="CONGE")
entry.time_slots = []
return entry
def test_monthly_stats_empty():
result = monthly_stats([])
assert result == {"median_daily_min": 0, "median_weekly_min": 0}
def test_monthly_stats_median_daily_odd():
# 420, 465, 510 → médiane = 465
entries = [
_entry(date(2025, 1, 6), ("9:00", "16:00")), # 420 min
_entry(date(2025, 1, 7), ("9:00", "16:45")), # 465 min
_entry(date(2025, 1, 8), ("9:00", "17:30")), # 510 min
]
result = monthly_stats(entries)
assert result["median_daily_min"] == 465
def test_monthly_stats_includes_absences():
# 0, 465 → médiane de 2 valeurs = (0+465)/2 = 232 (int)
entries = [
_absence(date(2025, 1, 6)),
_entry(date(2025, 1, 7), ("9:00", "16:45")),
]
result = monthly_stats(entries)
assert result["median_daily_min"] == 232
def test_monthly_stats_median_weekly():
# Semaine 1 : 465+465 = 930 min
# Semaine 2 : 420 min
# médiane([930, 420]) = (420+930)/2 = 675
entries = [
_entry(date(2025, 1, 6), ("9:00", "16:45")), # sem 2
_entry(date(2025, 1, 7), ("9:00", "16:45")), # sem 2
_entry(date(2025, 1, 13), ("9:00", "16:00")), # sem 3
]
result = monthly_stats(entries)
assert result["median_weekly_min"] == 675
def test_count_day_types_single_type():
entries = [
WorkEntry(date=date(2025, 2, 1), day_type="RTT"),