"""Tests des règles communes de statut et de consolidation des cours.""" from __future__ import annotations from datetime import datetime import pytest from pronote_sync.models.agenda import Lesson, LessonStatus from pronote_sync.sources.pronote.lessons import collapse_replaced_lessons, lesson_status def _lesson(status: LessonStatus, room: str) -> Lesson: """Construit un cours minimal pour les tests de consolidation. :param status: Statut métier du cours. :param room: Salle du cours. :return: Cours de test. :rtype: Lesson """ return Lesson( id=f"lesson-{room}", start=datetime(2026, 9, 11, 8, 0), end=datetime(2026, 9, 11, 9, 0), subject="Mathématiques", teachers=("Enseignant A",), rooms=(room,), group="Classe entière", status=status, content=None, ) @pytest.mark.parametrize( ("raw_status", "canceled", "expected"), [ ("Changement de salle", False, LessonStatus.MOVED), ("Cours déplacé", False, LessonStatus.MOVED), ("Cours annulé", False, LessonStatus.CANCELLED), (None, True, LessonStatus.CANCELLED), ("Statut inconnu", False, LessonStatus.NORMAL), ], ) def test_lesson_status_maps_pronotepy_variants( raw_status: object, canceled: bool, expected: LessonStatus ) -> None: """Convertit les statuts Pronote connus sans interpréter les inconnus. :param raw_status: Statut brut simulé. :param canceled: Indicateur d'annulation simulé. :param expected: Statut métier attendu. :return: None """ assert lesson_status(raw_status, canceled) == expected def test_collapse_replaced_lessons_keeps_effective_lesson() -> None: """Retire l'ancien exemplaire annulé d'un changement de salle. :return: None """ cancelled = _lesson(LessonStatus.CANCELLED, "101") moved = _lesson(LessonStatus.MOVED, "204") result = collapse_replaced_lessons([cancelled, moved]) assert result == [moved] def test_collapse_replaced_lessons_keeps_real_cancellation() -> None: """Conserve une annulation lorsqu'aucun cours déplacé ne la remplace. :return: None """ cancelled = _lesson(LessonStatus.CANCELLED, "101") assert collapse_replaced_lessons([cancelled]) == [cancelled] def test_collapse_replaced_lessons_keeps_ambiguous_cancellations() -> None: """Conserve les annulations lorsqu'une paire de remplacement est ambiguë. :return: None """ cancelled_old = _lesson(LessonStatus.CANCELLED, "101") cancelled_real = _lesson(LessonStatus.CANCELLED, "305") moved = _lesson(LessonStatus.MOVED, "204") result = collapse_replaced_lessons([cancelled_old, cancelled_real, moved]) assert result == [cancelled_old, cancelled_real, moved]