Édition éditable (dates) + robustesse de l'écran Postes & créneaux

Back-end :
- GET /editions/{id} (tout compte de l'édition) et PATCH /editions/{id}
  (COORDINATION) : name, year, start_date, end_date, retention_days.
  Refus si end_date < start_date (edition.dates_inconsistent). Tests.

Front-end :
- api : EditionRead/Update, editions.get/update (http + mock), hooks
  useEdition / useUpdateEdition.
- ConfigGrid : le bouton « ajouter un poste » sélectionne le poste créé et
  affiche l'état (pending) + les erreurs (ErrorNote) — avant, un échec ou
  même un succès passaient inaperçus. Renommage du poste + choix de la
  catégorie + suppression dans l'en-tête. Une colonne par jour de l'édition
  (même vide) → on peut ajouter un créneau n'importe quel jour.
- ConfigRules : formulaire d'édition (nom + dates) → c'est là qu'on ajoute
  ou retire des jours ; compteur de jours ; retour d'enregistrement.
- i18n mis à jour.

144 tests back OK ; typecheck + lint + build + smoke front OK.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
This commit is contained in:
AdamThomas
2026-09-10 20:02:50 +02:00
co-authored by Claude Sonnet 5
parent 9521034207
commit e0a0c56307
14 changed files with 517 additions and 115 deletions
+57
View File
@@ -0,0 +1,57 @@
import datetime as dt
import uuid
from app.models import Role
def _url(edition):
return f"/editions/{edition.id}"
def test_read_edition_exposes_the_date_range(client, edition):
body = client.get(_url(edition)).json()
assert body["start_date"] == "2026-07-09"
assert body["end_date"] == "2026-07-12"
assert body["year"] == 2026
def test_coordinator_can_extend_the_edition(client, edition):
resp = client.patch(_url(edition), json={"end_date": "2026-07-15"})
assert resp.status_code == 200
assert resp.json()["end_date"] == "2026-07-15"
assert client.get(_url(edition)).json()["end_date"] == "2026-07-15"
def test_end_before_start_is_rejected(client, edition):
resp = client.patch(_url(edition), json={"end_date": "2026-07-01"})
assert resp.status_code == 422
assert resp.json()["detail"]["code"] == "edition.dates_inconsistent"
def test_lead_cannot_update_the_edition(edition, make_account, as_account):
lead = make_account(Role.LEAD, email="lead@e.fr")
resp = as_account(lead).patch(_url(edition), json={"name": "Renommée"})
assert resp.status_code == 403
def test_volunteer_can_read_but_not_update(edition, session, make_account, as_account):
from tests.factories import make_volunteer
volunteer = make_volunteer(session, edition, email="v@e.fr")
account = make_account(Role.VOLUNTEER, volunteer_id=volunteer.id, email="v@e.fr")
client = as_account(account)
assert client.get(_url(edition)).status_code == 200
assert client.patch(_url(edition), json={"name": "X"}).status_code == 403
def test_unknown_edition_is_404(client):
assert client.get(f"/editions/{uuid.uuid4()}").status_code == 404
def test_update_keeps_unchanged_fields(client, edition):
resp = client.patch(_url(edition), json={"name": "Festival 2026"})
assert resp.status_code == 200
body = resp.json()
assert body["name"] == "Festival 2026"
assert body["start_date"] == "2026-07-09"
assert dt.date.fromisoformat(body["end_date"]) == dt.date(2026, 7, 12)