85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
from datetime import datetime, timezone
|
|
|
|
from govoplan_core.core.poll import (
|
|
CAPABILITY_POLL_SCHEDULING,
|
|
PollAnswerRef,
|
|
PollOptionUpdateCommand,
|
|
PollResponseRef,
|
|
PollResponseRetirementCommand,
|
|
PollResponseRetirementProvider,
|
|
poll_response_retirement_provider,
|
|
)
|
|
|
|
|
|
class _RetirementProvider:
|
|
def retire_responses(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
|
|
class _Registry:
|
|
def __init__(self, capability: object | None) -> None:
|
|
self.capability_value = capability
|
|
|
|
def has_capability(self, name: str) -> bool:
|
|
return (
|
|
name == CAPABILITY_POLL_SCHEDULING
|
|
and self.capability_value is not None
|
|
)
|
|
|
|
def capability(self, name: str) -> object:
|
|
if not self.has_capability(name):
|
|
raise KeyError(name)
|
|
return self.capability_value
|
|
|
|
|
|
class PollContractTests(unittest.TestCase):
|
|
def test_response_ref_remains_backwards_compatible_and_can_carry_answers(self) -> None:
|
|
submitted_at = datetime(2026, 7, 20, tzinfo=timezone.utc)
|
|
|
|
legacy = PollResponseRef(None, submitted_at)
|
|
detailed = PollResponseRef(
|
|
invitation_id="invitation-1",
|
|
submitted_at=submitted_at,
|
|
respondent_id="person-1",
|
|
answers=(PollAnswerRef(option_id="option-1", option_key="slot-1", value="available"),),
|
|
)
|
|
|
|
self.assertEqual(legacy.answers, ())
|
|
self.assertEqual(detailed.answers[0].value, "available")
|
|
|
|
def test_option_update_command_is_a_complete_immutable_snapshot(self) -> None:
|
|
command = PollOptionUpdateCommand(
|
|
label="Tuesday 10:00",
|
|
value={"slot_id": "slot-1"},
|
|
metadata={"source": "scheduling"},
|
|
)
|
|
|
|
self.assertEqual(command.label, "Tuesday 10:00")
|
|
self.assertEqual(command.value, {"slot_id": "slot-1"})
|
|
|
|
def test_response_retirement_is_an_optional_idempotent_extension(self) -> None:
|
|
command = PollResponseRetirementCommand(
|
|
respondent_ids=("account-1", "alice@example.test"),
|
|
invitation_id="invitation-1",
|
|
reason="scheduling_participant_removed",
|
|
idempotency_key="scheduling:request-1:participant-1:removed",
|
|
metadata={"source_module": "scheduling"},
|
|
)
|
|
provider = _RetirementProvider()
|
|
|
|
self.assertEqual(command.respondent_ids[0], "account-1")
|
|
self.assertIsInstance(provider, PollResponseRetirementProvider)
|
|
self.assertIs(
|
|
poll_response_retirement_provider(_Registry(provider)),
|
|
provider,
|
|
)
|
|
self.assertIsNone(poll_response_retirement_provider(_Registry(object())))
|
|
self.assertIsNone(poll_response_retirement_provider(None))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|