Files
benevoles/backend/tests/test_badges_pdf.py
T
AdamThomasandClaude Sonnet 5 b7fc80a7dc Étape 20 : planches de badges bénévoles (PDF)
Recto personnalisable (fond image + champs positionnés : nom, poste(s)
affectés, catégorie, rôle) via un éditeur visuel glisser-déposer ; verso
fixe, la même image pour tous les bénévoles. Nouvel écran « Badges »
(COORDINATION uniquement, /badges).

Backend : modèle BadgeTemplate/BadgeField (migration 0011), génération
PDF isolée (app/badges/pdf.py, ReportLab — planches recto suivies des
planches verso correspondantes pour une impression recto-verso), route
POST /editions/{id}/badges/generate, tests (module pur + API).

Frontend : client HTTP (upload multipart, réponses binaires images/PDF),
client mock (mode démonstration), éditeur de positionnement en
millimètres (coordonnées partagées avec le backend), écran de génération
avec sélection des bénévoles et téléchargement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 20:05:03 +02:00

63 lines
1.9 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.
"""Génération des planches de badges (module pur, sans base)."""
from app.badges.pdf import (
BadgeFieldSpec,
BadgeSpec,
_cell_origin,
_grid_size,
generate_badge_sheets_pdf,
)
def _badge(text="Alex Martin") -> BadgeSpec:
return BadgeSpec(
fields=(
BadgeFieldSpec(
text=text,
x_mm=5,
y_mm=5,
width_mm=60,
height_mm=10,
font_size=12,
align="LEFT",
bold=True,
color="#000000",
),
)
)
def test_grid_size_fits_a4_with_cr80_badges():
# A4 (210 × 297 mm), marge 10 mm, gouttière 4 mm, badge CR80 85,6 × 54 mm
# ⇒ 2 colonnes (190 mm utiles / 89,6 mm par badge+gouttière) x 4 rangées
# (277 mm utiles / 58 mm par badge+gouttière).
assert _grid_size() == (2, 4)
def test_cell_origin_places_badges_left_to_right_top_to_bottom():
cols, _ = _grid_size()
x0, y0 = _cell_origin(0, cols)
x1, _ = _cell_origin(1, cols)
_, y_row2 = _cell_origin(cols, cols)
assert x1 > x0 # la 2e colonne est à droite de la 1re
assert y_row2 < y0 # la 2e rangée est plus bas (repère PDF : Y croît vers le haut)
def test_generates_a_valid_pdf_for_a_single_badge():
pdf = generate_badge_sheets_pdf([_badge()], front_image=None, back_image=None)
assert pdf.startswith(b"%PDF")
assert pdf.rstrip().endswith(b"%%EOF")
def test_more_badges_than_one_sheet_produces_a_larger_pdf():
cols, rows = _grid_size()
per_page = cols * rows
one_page = generate_badge_sheets_pdf(
[_badge() for _ in range(per_page)], front_image=None, back_image=None
)
# Un badge de plus déborde sur une 2e planche (recto + verso en plus).
two_pages = generate_badge_sheets_pdf(
[_badge() for _ in range(per_page + 1)], front_image=None, back_image=None
)
assert len(two_pages) > len(one_page)