import datetime as dt from app.models import Assignment, AssignmentStatus, AvailabilityStatus from app.validation import AvailabilityDeclaration from app.validation.loader import build_validation_input from tests.factories import ( dt_at, make_availability, make_position, make_shift, make_volunteer, ) def test_build_input_gathers_everything_from_db(client, edition, session, day_parts): position = make_position(session, edition) candidate = make_shift( session, edition, position, start=dt_at(10, 14), end=dt_at(10, 18), skills=["SST"], ) active_shift = make_shift( session, edition, position, start=dt_at(11, 9), end=dt_at(11, 12) ) declined_shift = make_shift( session, edition, position, start=dt_at(12, 9), end=dt_at(12, 12) ) volunteer = make_volunteer( session, edition, email="v@ex.fr", skills=["SST", "PERMIS_B"] ) make_availability( session, edition, volunteer, day_parts["AFTERNOON"], date=dt.date(2026, 7, 10), status=AvailabilityStatus.IF_NEEDED, ) session.add_all( [ Assignment( edition_id=edition.id, volunteer_id=volunteer.id, shift_id=active_shift.id, status=AssignmentStatus.CONFIRMED, ), Assignment( edition_id=edition.id, volunteer_id=volunteer.id, shift_id=declined_shift.id, status=AssignmentStatus.DECLINED, ), ] ) session.commit() data = build_validation_input( session=session, edition=edition, volunteer=volunteer, shift=candidate ) assert data.candidate_shift.id == str(candidate.id) assert data.candidate_shift.required_skill_codes == frozenset({"SST"}) assert data.volunteer_skill_codes == frozenset({"SST", "PERMIS_B"}) # Seul le créneau de l'affectation active, ni le candidat ni la DECLINEE. assert [s.id for s in data.existing_shifts] == [str(active_shift.id)] assert len(data.day_parts) == 3 assert data.availabilities == ( AvailabilityDeclaration( dt.date(2026, 7, 10), "AFTERNOON", AvailabilityStatus.IF_NEEDED ), ) def test_exclude_assignment_id_is_honoured(client, edition, session, day_parts): position = make_position(session, edition) candidate = make_shift( session, edition, position, start=dt_at(10, 14), end=dt_at(10, 18) ) other_shift = make_shift( session, edition, position, start=dt_at(11, 9), end=dt_at(11, 12) ) volunteer = make_volunteer(session, edition, email="v@ex.fr") own = Assignment( edition_id=edition.id, volunteer_id=volunteer.id, shift_id=other_shift.id, status=AssignmentStatus.PROPOSED, ) session.add(own) session.commit() session.refresh(own) data = build_validation_input( session=session, edition=edition, volunteer=volunteer, shift=candidate, exclude_assignment_id=own.id, ) assert data.existing_shifts == ()