import datetime as dt import uuid from sqlmodel import select from app.models import Artist, Role, VolunteerArtist from tests.factories import make_artist, make_volunteer def _url(edition, suffix=""): return f"/editions/{edition.id}/artists{suffix}" def _payload(name: str, performance_date: str, **overrides) -> dict: body = { "name": name, "performance_date": performance_date, "start_time": "20:00", "end_time": "21:00", } body.update(overrides) return body def test_create_and_list_ordered_by_date_then_name(client, edition): client.post(_url(edition), json=_payload("Ziak", "2026-07-11")) client.post(_url(edition), json=_payload("Aloïse Sauvage", "2026-07-11")) r = client.post(_url(edition), json=_payload("Chilla", "2026-07-10")) assert r.status_code == 201 assert r.json()["start_time"] == "20:00:00" assert r.json()["end_time"] == "21:00:00" body = client.get(_url(edition)).json() assert [(a["name"], a["performance_date"]) for a in body] == [ ("Chilla", "2026-07-10"), ("Aloïse Sauvage", "2026-07-11"), ("Ziak", "2026-07-11"), ] def test_blank_name_is_422(client, edition): r = client.post(_url(edition), json=_payload(" ", "2026-07-10")) assert r.status_code == 422 assert r.json()["detail"]["code"] == "artist.name_required" def test_duplicate_name_and_date_conflicts(client, edition): payload = _payload("Chilla", "2026-07-10") assert client.post(_url(edition), json=payload).status_code == 201 r = client.post(_url(edition), json=payload) assert r.status_code == 409 assert r.json()["detail"]["code"] == "artist.duplicate" # Même nom, autre jour : autorisé. r2 = client.post(_url(edition), json=_payload("Chilla", "2026-07-11")) assert r2.status_code == 201 def test_update_artist(client, edition, session): artist = make_artist(session, edition, name="Chila") r = client.patch( _url(edition, f"/{artist.id}"), json={"name": "Chilla", "performance_date": "2026-07-12", "start_time": "22:00"}, ) assert r.status_code == 200 assert r.json()["name"] == "Chilla" assert r.json()["performance_date"] == "2026-07-12" assert r.json()["start_time"] == "22:00:00" # Non transmis : inchangé. assert r.json()["end_time"] == "21:00:00" def test_delete_artist_removes_volunteer_wishes(client, edition, session): artist = make_artist(session, edition) volunteer = make_volunteer(session, edition, email="fan@e.fr") assert client.patch( f"/editions/{edition.id}/volunteers/{volunteer.id}", json={"artist_ids": [str(artist.id)]}, ).json()["artist_ids"] == [str(artist.id)] assert client.delete(_url(edition, f"/{artist.id}")).status_code == 204 assert session.exec(select(Artist)).all() == [] assert session.exec(select(VolunteerArtist)).all() == [] fiche = client.get( f"/editions/{edition.id}/volunteers/{volunteer.id}" ).json() assert fiche["artist_ids"] == [] def test_unknown_edition_is_404(client): assert client.get(f"/editions/{uuid.uuid4()}/artists").status_code == 404 def test_write_is_coordinator_only(edition, make_account, as_account): lead = make_account(Role.LEAD, email="lead@e.fr") api = as_account(lead) resp = api.post(_url(edition), json=_payload("X", "2026-07-10")) assert resp.status_code == 403 # La lecture reste ouverte à tout compte de l'édition. assert api.get(_url(edition)).status_code == 200 def test_other_edition_artist_is_404(client, edition, session): from app.models import Edition other = Edition( year=2027, start_date=dt.date(2027, 7, 1), end_date=dt.date(2027, 7, 4), ) session.add(other) session.commit() session.refresh(other) stranger = make_artist(session, other, name="Ailleurs") assert client.patch( _url(edition, f"/{stranger.id}"), json={"name": "Y"} ).status_code == 404