feat(scheduling): persist candidate slot ordering

This commit is contained in:
2026-07-22 03:26:21 +02:00
parent a316341226
commit 835ad82916
5 changed files with 142 additions and 33 deletions

View File

@@ -1180,6 +1180,103 @@ class SchedulingResponseEditingTests(unittest.TestCase):
self.assertEqual(raised.exception.status_code, 409)
def test_full_edit_reorders_slots_and_poll_options_without_losing_answers(self) -> None:
request = self._request(create_participant_invitations=False)
self._submit_both(request)
first_slot, second_slot = request.slots
first_slot.tentative_hold_event_id = "calendar-hold-1"
self.session.flush()
def reconcile_input(
slot: SchedulingCandidateSlot,
) -> SchedulingCandidateSlotReconcileInput:
return SchedulingCandidateSlotReconcileInput(
id=slot.id,
revision=scheduling_slot_revision(slot),
label=slot.label,
description=slot.description,
start_at=slot.start_at.replace(tzinfo=timezone.utc),
end_at=slot.end_at.replace(tzinfo=timezone.utc),
timezone=slot.timezone,
location=slot.location,
metadata=slot.metadata_ or {},
)
response = api_update_scheduling_request(
request.id,
SchedulingRequestUpdateRequest(
slots=[reconcile_input(second_slot), reconcile_input(first_slot)]
),
session=self.session,
principal=self._principal(
"organizer-1",
email=None,
scopes={WRITE_SCOPE},
),
)
self.assertEqual(
[(slot.id, slot.position) for slot in response.slots],
[(second_slot.id, 0), (first_slot.id, 1)],
)
poll_options = (
self.session.query(PollOption)
.filter(
PollOption.poll_id == request.poll_id,
PollOption.deleted_at.is_(None),
)
.order_by(PollOption.position.asc())
.all()
)
self.assertEqual(
[option.id for option in poll_options],
[second_slot.poll_option_id, first_slot.poll_option_id],
)
current = api_get_my_scheduling_availability(
request.id,
session=self.session,
principal=self._principal(
"alice-account",
email="alice@example.test",
scopes={RESPOND_SCOPE},
),
)
self.assertEqual(
{answer.slot_id: answer.value for answer in current.answers},
{first_slot.id: "available", second_slot.id: "maybe"},
)
self.assertEqual(first_slot.tentative_hold_event_id, "calendar-hold-1")
replayed = api_update_scheduling_request(
request.id,
SchedulingRequestUpdateRequest(
slots=[reconcile_input(second_slot), reconcile_input(first_slot)]
),
session=self.session,
principal=self._principal(
"organizer-1",
email=None,
scopes={WRITE_SCOPE},
),
)
self.assertEqual(
[(slot.id, slot.position) for slot in replayed.slots],
[(second_slot.id, 0), (first_slot.id, 1)],
)
current = api_get_my_scheduling_availability(
request.id,
session=self.session,
principal=self._principal(
"alice-account",
email="alice@example.test",
scopes={RESPOND_SCOPE},
),
)
self.assertEqual(
{answer.slot_id: answer.value for answer in current.answers},
{first_slot.id: "available", second_slot.id: "maybe"},
)
def test_draft_edit_does_not_issue_link_for_added_participant(self) -> None:
request = self._request(
status="draft",