feat(scheduling): add explicit invitation link lifecycle
This commit is contained in:
@@ -60,6 +60,7 @@ from govoplan_scheduling.backend.service import (
|
||||
cancel_scheduling_request,
|
||||
create_scheduling_request,
|
||||
get_public_scheduling_participation,
|
||||
issue_scheduling_participant_invitation,
|
||||
scheduling_request_summary,
|
||||
scheduling_slot_revision,
|
||||
submit_scheduling_availability,
|
||||
@@ -149,8 +150,9 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
participants: list[SchedulingParticipantInput] | None = None,
|
||||
**settings,
|
||||
) -> tuple[SchedulingRequest, dict[str, str]]:
|
||||
issue_links = bool(settings.pop("create_participant_invitations", True))
|
||||
start = datetime(2026, 7, 20, 9, tzinfo=timezone.utc)
|
||||
return create_scheduling_request(
|
||||
request, automatic_tokens = create_scheduling_request(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
user_id="organizer-1",
|
||||
@@ -184,6 +186,31 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
**settings,
|
||||
),
|
||||
)
|
||||
self.assertEqual(automatic_tokens, {})
|
||||
tokens = (
|
||||
{
|
||||
participant.id: self._issue_copy(request, participant)
|
||||
for participant in request.participants
|
||||
}
|
||||
if issue_links
|
||||
else {}
|
||||
)
|
||||
return request, tokens
|
||||
|
||||
def _issue_copy(
|
||||
self,
|
||||
request: SchedulingRequest,
|
||||
participant: SchedulingParticipant,
|
||||
) -> str:
|
||||
result = issue_scheduling_participant_invitation(
|
||||
self.session,
|
||||
tenant_id=request.tenant_id,
|
||||
request_id=request.id,
|
||||
participant_id=participant.id,
|
||||
action="copy",
|
||||
)
|
||||
self.assertIsNotNone(result.action_url)
|
||||
return str(result.action_url).rsplit("/", 1)[-1]
|
||||
|
||||
def _answer(
|
||||
self,
|
||||
@@ -475,7 +502,8 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
],
|
||||
),
|
||||
)
|
||||
token = tokens[public_request.participants[0].id]
|
||||
self.assertEqual(tokens, {})
|
||||
token = self._issue_copy(public_request, public_request.participants[0])
|
||||
invitation = self.session.query(PollInvitation).filter(
|
||||
PollInvitation.id == public_request.participants[0].poll_invitation_id
|
||||
).one()
|
||||
@@ -568,7 +596,8 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
participants=[SchedulingParticipantInput(display_name="Guest")],
|
||||
),
|
||||
)
|
||||
token = tokens[request.participants[0].id]
|
||||
self.assertEqual(tokens, {})
|
||||
token = self._issue_copy(request, request.participants[0])
|
||||
wrong = SchedulingPublicParticipationAccessRequest(password="wrong password")
|
||||
|
||||
for attempt in range(10):
|
||||
@@ -623,7 +652,8 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
),
|
||||
)
|
||||
participant = request.participants[0]
|
||||
token = tokens[participant.id]
|
||||
self.assertEqual(tokens, {})
|
||||
token = self._issue_copy(request, participant)
|
||||
answer = SchedulingAvailabilityAnswerInput(
|
||||
slot_id=request.slots[0].id,
|
||||
value="available",
|
||||
@@ -1036,8 +1066,16 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
self.assertIsNotNone(removed_slot.deleted_at)
|
||||
bob = next(item for item in response.participants if item.display_name == "Bob")
|
||||
self.assertEqual(bob.email, "bob@example.test")
|
||||
self.assertIsNotNone(bob.poll_invitation_id)
|
||||
self.assertIsNotNone(bob.invitation_token)
|
||||
self.assertIsNone(bob.poll_invitation_id)
|
||||
self.assertIsNone(bob.invitation_token)
|
||||
bob_model = next(
|
||||
item
|
||||
for item in request.participants
|
||||
if item.deleted_at is None and item.display_name == "Bob"
|
||||
)
|
||||
self._issue_copy(request, bob_model)
|
||||
bob_invitation_id = bob_model.poll_invitation_id
|
||||
self.assertIsNotNone(bob_invitation_id)
|
||||
current = api_get_my_scheduling_availability(
|
||||
request.id,
|
||||
session=self.session,
|
||||
@@ -1091,7 +1129,7 @@ class SchedulingResponseEditingTests(unittest.TestCase):
|
||||
),
|
||||
)
|
||||
invitation = self.session.query(PollInvitation).filter(
|
||||
PollInvitation.id == bob.poll_invitation_id
|
||||
PollInvitation.id == bob_invitation_id
|
||||
).one()
|
||||
self.assertIsNotNone(invitation.revoked_at)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user