fix(ical) : fiabiliser le parsing Pronote 2026 #31
@@ -370,7 +370,8 @@ def generate_homework_id(
|
|||||||
:rtype: str
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
payload = (
|
payload = (
|
||||||
f"{due_on.isoformat()}|{subject}|{','.join(sorted(teachers))}|{normalized_text}".encode()
|
f"{due_on.isoformat()}|{subject.casefold()}|"
|
||||||
|
f"{','.join(sorted(teacher.casefold() for teacher in teachers))}|{normalized_text}".encode()
|
||||||
)
|
)
|
||||||
return hashlib.sha1(payload, usedforsecurity=False).hexdigest()[:12]
|
return hashlib.sha1(payload, usedforsecurity=False).hexdigest()[:12]
|
||||||
|
|
||||||
@@ -397,7 +398,7 @@ def collect_homeworks(lessons: list[Lesson], target_date: date) -> list[Homework
|
|||||||
normalized_text = normalize_homework_text(block.text)
|
normalized_text = normalize_homework_text(block.text)
|
||||||
key = (
|
key = (
|
||||||
lesson.subject.casefold(),
|
lesson.subject.casefold(),
|
||||||
tuple(teacher.casefold() for teacher in lesson.teachers),
|
tuple(sorted(teacher.casefold() for teacher in lesson.teachers)),
|
||||||
normalized_text,
|
normalized_text,
|
||||||
)
|
)
|
||||||
if key not in by_context:
|
if key not in by_context:
|
||||||
@@ -421,7 +422,7 @@ def collect_homeworks(lessons: list[Lesson], target_date: date) -> list[Homework
|
|||||||
normalized_text = normalize_homework_text(block.text)
|
normalized_text = normalize_homework_text(block.text)
|
||||||
key = (
|
key = (
|
||||||
lesson.subject.casefold(),
|
lesson.subject.casefold(),
|
||||||
tuple(teacher.casefold() for teacher in lesson.teachers),
|
tuple(sorted(teacher.casefold() for teacher in lesson.teachers)),
|
||||||
normalized_text,
|
normalized_text,
|
||||||
)
|
)
|
||||||
if key not in by_context:
|
if key not in by_context:
|
||||||
|
|||||||
@@ -398,6 +398,36 @@ def test_collect_homeworks_keeps_distinct_subjects() -> None:
|
|||||||
assert {homework.subject for homework in homeworks} == {"Math", "Physique"}
|
assert {homework.subject for homework in homeworks} == {"Math", "Physique"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_collect_homeworks_deduplicates_teacher_order_variants() -> None:
|
||||||
|
"""Deux ordres d'enseignants équivalents ne créent pas de doublon.
|
||||||
|
|
||||||
|
:return: None
|
||||||
|
"""
|
||||||
|
homework_block = HomeworkBlock(
|
||||||
|
kind="due",
|
||||||
|
date=date(2026, 9, 10),
|
||||||
|
text="Devoir commun",
|
||||||
|
html="<p>Devoir commun</p>",
|
||||||
|
)
|
||||||
|
lesson = Lesson(
|
||||||
|
id="lesson1",
|
||||||
|
start=datetime(2026, 9, 10, 8, 0),
|
||||||
|
end=datetime(2026, 9, 10, 9, 0),
|
||||||
|
subject="Math",
|
||||||
|
teachers=("M. Martin", "M. Dupont"),
|
||||||
|
group=None,
|
||||||
|
content=None,
|
||||||
|
homework_blocks=(homework_block,),
|
||||||
|
)
|
||||||
|
other_lesson = lesson.model_copy(
|
||||||
|
update={"id": "lesson2", "teachers": ("M. Dupont", "M. Martin")}
|
||||||
|
)
|
||||||
|
|
||||||
|
homeworks = collect_homeworks([lesson, other_lesson], target_date=date(2026, 9, 10))
|
||||||
|
|
||||||
|
assert len(homeworks) == 1
|
||||||
|
|
||||||
|
|
||||||
def test_parse_body_accepts_html_variants_and_sanitizes() -> None:
|
def test_parse_body_accepts_html_variants_and_sanitizes() -> None:
|
||||||
"""Les attributs HTML, les espaces et le contenu actif sont traités correctement.
|
"""Les attributs HTML, les espaces et le contenu actif sont traités correctement.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user