Fiches de poste rapides, badges sans initiales, vue par bénévole sur l'axe des temps
ci-cd / build-backend (push) Successful in 34s
ci-cd / build-frontend (push) Successful in 19s
ci-cd / deploy (push) Successful in 11s

Étape 62 : les fiches de poste intégraient la photo d'origine de chaque
bénévole pour chaque créneau (CPU à 300 %, puis erreur) — photos réduites
à la vignette une fois par PDF ; badges : photo recadrée une fois par
génération et décodée à taille réduite.

Étape 61 : sans photo, le cadre de la photo reste vide sur le badge.

Étape 60 : vue par bénévole en tranches de 30 min, affectations étirées
sur toute leur durée, postes simultanés empilés, ligne de l'heure actuelle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AdamThomas
2026-10-28 19:01:48 +01:00
co-authored by Claude Opus 5.5
parent c57c70569c
commit c6ea7378c7
13 changed files with 424 additions and 296 deletions
+14 -21
View File
@@ -242,7 +242,7 @@ def test_table_rows_beyond_the_frame_are_not_drawn():
# Éditeur v2 : verso, fond de zone, réduction automatique, photo #
# --------------------------------------------------------------------------- #
from app.badges import pdf as pdf_module # noqa: E402
from app.badges.pdf import fit_text, initials # noqa: E402
from app.badges.pdf import fit_text # noqa: E402
def _text_field(**kw) -> BadgeFieldSpec:
@@ -269,9 +269,9 @@ def test_back_page_draws_each_volunteer_back_fields_at_the_mirrored_slot(monkeyp
calls = []
original = pdf_module._draw_fields
def spy(c, fields, x0, y0, badge_height_mm):
def spy(c, fields, x0, y0, badge_height_mm, photos):
calls.append((fields, x0, y0))
original(c, fields, x0, y0, badge_height_mm)
original(c, fields, x0, y0, badge_height_mm, photos)
monkeypatch.setattr(pdf_module, "_draw_fields", spy)
back = (_text_field(text="Verso Alex"),)
@@ -376,30 +376,23 @@ def test_middle_aligned_text_is_lower_than_top_aligned_text(monkeypatch):
assert middle < top
def test_initials_are_the_uppercase_first_letters():
assert initials("alex", "martin") == "AM"
assert initials("Élodie", "de la Tour") == "ÉD"
def test_missing_photo_prints_the_initials(monkeypatch):
drawn = []
monkeypatch.setattr(
pdf_module.canvas.Canvas, "drawCentredString",
lambda self, x, y, text, *a, **k: drawn.append(text),
)
for image in (None, b"pas une image"):
badge = BadgeSpec(
fields=(BadgeFieldSpec(**{**_photo_badge(image).fields[0].__dict__, "text": "AM"}),)
def test_missing_photo_prints_nothing(monkeypatch):
calls = []
for name in ("drawImage", "drawPath", "drawCentredString", "drawString"):
monkeypatch.setattr(
pdf_module.canvas.Canvas, name,
lambda self, *a, _name=name, **k: calls.append(_name),
)
generate_badge_sheets_pdf([badge], None, None)
assert drawn == ["AM", "AM"]
for image in (None, b"pas une image"):
generate_badge_sheets_pdf([_photo_badge(image)], None, None)
assert calls == []
def test_oval_photo_and_oval_initials_generate_a_valid_pdf():
def test_oval_photo_and_missing_oval_photo_generate_a_valid_pdf():
for image in (_jpeg(400, 500), None):
field = _photo_badge(image).fields[0]
badge = BadgeSpec(
fields=(BadgeFieldSpec(**{**field.__dict__, "photo_shape": "OVAL", "text": "AM"}),)
fields=(BadgeFieldSpec(**{**field.__dict__, "photo_shape": "OVAL"}),)
)
pdf = generate_badge_sheets_pdf([badge], None, None)
assert pdf.startswith(b"%PDF")