85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from govoplan_core.core.poll_participation import (
|
|
CAPABILITY_POLL_PARTICIPATION_GATEWAY,
|
|
PollParticipationGatewayProvider,
|
|
PollParticipationPolicy,
|
|
participation_token_fingerprint,
|
|
poll_participation_gateway_provider,
|
|
)
|
|
|
|
|
|
class _CompleteGateway:
|
|
def create_governed_invitation(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def resolve_participation(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def submit_governed_response(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def resolve_authenticated_participation(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def submit_authenticated_response(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def add_option(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def remove_option(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def revoke_invitation(self, *args, **kwargs):
|
|
raise NotImplementedError
|
|
|
|
def update_invitation_expiry(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_PARTICIPATION_GATEWAY
|
|
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 PollParticipationContractTests(unittest.TestCase):
|
|
def test_capability_name_and_policy_defaults_remain_stable(self) -> None:
|
|
policy = PollParticipationPolicy()
|
|
|
|
self.assertEqual("poll.participation_gateway", CAPABILITY_POLL_PARTICIPATION_GATEWAY)
|
|
self.assertEqual(1, policy.version)
|
|
self.assertTrue(policy.allow_maybe)
|
|
|
|
def test_token_fingerprint_is_deterministic_and_non_reversible(self) -> None:
|
|
fingerprint = participation_token_fingerprint("secret-token")
|
|
|
|
self.assertEqual(fingerprint, participation_token_fingerprint("secret-token"))
|
|
self.assertEqual(64, len(fingerprint))
|
|
self.assertNotIn("secret-token", fingerprint)
|
|
|
|
def test_registry_lookup_accepts_only_the_complete_structural_contract(self) -> None:
|
|
provider = _CompleteGateway()
|
|
|
|
self.assertIsInstance(provider, PollParticipationGatewayProvider)
|
|
self.assertIs(provider, poll_participation_gateway_provider(_Registry(provider)))
|
|
self.assertIsNone(poll_participation_gateway_provider(_Registry(object())))
|
|
self.assertIsNone(poll_participation_gateway_provider(None))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|