Disponibilités déclarées supprimées (table `availability`, migration 0022, API, éditeur de la fiche bénévole, badge de couverture du panneau d'affectation, colonnes des statistiques) ainsi que les règles OUTSIDE_AVAILABILITY, DAILY_HOURS_EXCEEDED et INSUFFICIENT_REST, les malus de disponibilité et de repos du solveur et le filtre « Surchargés » de la vue bénévoles. Seul le chevauchement reste contrôlé. La case « je suis disponible » du formulaire public est conservée. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.6 KiB
Python
69 lines
2.6 KiB
Python
from sqlmodel import select
|
|
|
|
from app.models import Edition, FeePaymentStatus, Volunteer
|
|
from app.seed import DEMO_EDITION_NAME, build
|
|
|
|
|
|
def test_build_creates_a_realistic_dataset(session):
|
|
summary = build(session)
|
|
|
|
assert summary.volunteers == 120
|
|
assert summary.positions == 15
|
|
assert summary.shifts > 40
|
|
assert summary.assignments > 100
|
|
assert summary.understaffed_shifts >= 3 # « quelques trous d'effectif »
|
|
assert summary.blocking == 0 # aucune violation bloquante
|
|
# Programmation et vœux des bénévoles : le mode démo doit les illustrer.
|
|
assert summary.artists > 0
|
|
assert summary.position_wishes > 0
|
|
assert summary.artist_wishes > 0
|
|
assert summary.companion_wishes > 0
|
|
# Paiement de la cotisation : au moins un exemple de chaque chemin.
|
|
assert summary.fee_paid_classique > 0
|
|
assert summary.fee_paid_mecenat > 0
|
|
|
|
edition = session.exec(
|
|
select(Edition).where(Edition.name == DEMO_EDITION_NAME)
|
|
).one()
|
|
volunteers = session.exec(
|
|
select(Volunteer).where(Volunteer.edition_id == edition.id)
|
|
).all()
|
|
assert len(volunteers) == 120
|
|
|
|
paid = [v for v in volunteers if v.fee_payment_status == FeePaymentStatus.PAID]
|
|
assert len(paid) == summary.fee_paid_classique + summary.fee_paid_mecenat
|
|
mecenat = [v for v in paid if v.mecenat_address is not None]
|
|
assert len(mecenat) == summary.fee_paid_mecenat
|
|
for volunteer in mecenat:
|
|
assert volunteer.mecenat_city and volunteer.mecenat_postal_code
|
|
assert volunteer.mecenat_country == "France"
|
|
assert volunteer.fee_payment_label == "Mécénat"
|
|
classique = [v for v in paid if v.mecenat_address is None]
|
|
for volunteer in classique:
|
|
assert volunteer.fee_payment_label == "Cotisation classique"
|
|
assert volunteer.fee_amount == 15.0
|
|
|
|
|
|
def test_build_is_deterministic_and_idempotent(session):
|
|
first = build(session)
|
|
second = build(session)
|
|
|
|
assert (second.volunteers, second.positions, second.shifts) == (
|
|
first.volunteers,
|
|
first.positions,
|
|
first.shifts,
|
|
)
|
|
assert second.assignments == first.assignments
|
|
assert second.understaffed_shifts == first.understaffed_shifts
|
|
assert second.artists == first.artists
|
|
assert second.position_wishes == first.position_wishes
|
|
assert second.artist_wishes == first.artist_wishes
|
|
assert second.companion_wishes == first.companion_wishes
|
|
assert second.fee_paid_classique == first.fee_paid_classique
|
|
assert second.fee_paid_mecenat == first.fee_paid_mecenat
|
|
|
|
editions = session.exec(
|
|
select(Edition).where(Edition.name == DEMO_EDITION_NAME)
|
|
).all()
|
|
assert len(editions) == 1
|