import datetime as dt from tests.factories import make_position def _url(edition, suffix=""): return f"/editions/{edition.id}/shifts{suffix}" def _payload(position, **overrides): base = { "position_id": str(position.id), "starts_at": "2026-07-10T18:00:00", "ends_at": "2026-07-10T22:00:00", "min_staff": 2, "ideal_staff": 4, "required_skill_codes": ["SST"], } base.update(overrides) return base def test_create_shift_with_required_skills(client, edition, session): position = make_position(session, edition) resp = client.post(_url(edition), json=_payload(position)) assert resp.status_code == 201 body = resp.json() assert body["required_skill_codes"] == ["SST"] assert body["min_staff"] == 2 assert body["position_id"] == str(position.id) def test_create_shift_end_before_start_is_422(client, edition, session): position = make_position(session, edition) resp = client.post( _url(edition), json=_payload(position, ends_at="2026-07-10T17:00:00"), ) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "shift.ends_not_after_starts" def test_create_shift_with_position_from_other_edition_is_422(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_position = make_position(session, other) resp = client.post(_url(edition), json=_payload(stranger_position)) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "shift.position_wrong_edition" def test_list_filter_by_position(client, edition, session): p1 = make_position(session, edition, name="P1") p2 = make_position(session, edition, name="P2") client.post(_url(edition), json=_payload(p1)) client.post( _url(edition), json=_payload( p2, starts_at="2026-07-11T09:00:00", ends_at="2026-07-11T12:00:00", ), ) only_p1 = client.get(_url(edition), params={"position_id": str(p1.id)}).json() assert len(only_p1) == 1 assert only_p1[0]["position_id"] == str(p1.id) assert len(client.get(_url(edition)).json()) == 2 def test_patch_shift_times_and_skills(client, edition, session): position = make_position(session, edition) sid = client.post(_url(edition), json=_payload(position)).json()["id"] patched = client.patch( _url(edition, f"/{sid}"), json={ "ends_at": "2026-07-10T23:30:00", "required_skill_codes": ["SOUND", "SST"], }, ) assert patched.status_code == 200 assert patched.json()["ends_at"] == "2026-07-10T23:30:00" assert patched.json()["required_skill_codes"] == ["SOUND", "SST"] def test_patch_shift_into_invalid_range_is_422(client, edition, session): position = make_position(session, edition) sid = client.post(_url(edition), json=_payload(position)).json()["id"] resp = client.patch( _url(edition, f"/{sid}"), json={"starts_at": "2026-07-11T00:00:00"} ) assert resp.status_code == 422