feat(policy): add scheduling participant privacy contract
This commit is contained in:
95
tests/test_scheduling_privacy_contract.py
Normal file
95
tests/test_scheduling_privacy_contract.py
Normal file
@@ -0,0 +1,95 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from govoplan_core.core.modules import ModuleContext, ModuleManifest
|
||||
from govoplan_core.core.policy import (
|
||||
CAPABILITY_POLICY_SCHEDULING_PARTICIPANT_PRIVACY,
|
||||
PolicySourceStep,
|
||||
SchedulingParticipantPrivacyDecision,
|
||||
SchedulingParticipantPrivacyPolicy,
|
||||
SchedulingParticipantPrivacyRequest,
|
||||
scheduling_participant_privacy_policy,
|
||||
)
|
||||
from govoplan_core.core.registry import PlatformRegistry
|
||||
|
||||
|
||||
class _PrivacyPolicy:
|
||||
def resolve_scheduling_participant_visibility(
|
||||
self,
|
||||
session: object,
|
||||
*,
|
||||
request: SchedulingParticipantPrivacyRequest,
|
||||
) -> SchedulingParticipantPrivacyDecision:
|
||||
del session
|
||||
return SchedulingParticipantPrivacyDecision(
|
||||
effective_visibility="aggregates_only",
|
||||
reason=f"Participant roster is restricted for {request.scheduling_request_id}.",
|
||||
details={"requested_visibility": request.requested_visibility},
|
||||
)
|
||||
|
||||
|
||||
class SchedulingPrivacyContractTests(unittest.TestCase):
|
||||
def test_capability_name_and_request_context_are_stable(self) -> None:
|
||||
self.assertEqual(
|
||||
CAPABILITY_POLICY_SCHEDULING_PARTICIPANT_PRIVACY,
|
||||
"policy.schedulingParticipantPrivacy",
|
||||
)
|
||||
request = SchedulingParticipantPrivacyRequest(
|
||||
tenant_id="tenant-1",
|
||||
scheduling_request_id="request-1",
|
||||
participant_id="participant-1",
|
||||
actor_user_id="user-1",
|
||||
requested_visibility="names_and_statuses",
|
||||
context={"request_status": "open"},
|
||||
)
|
||||
|
||||
self.assertEqual(request.requested_visibility, "names_and_statuses")
|
||||
self.assertEqual(request.context["request_status"], "open")
|
||||
|
||||
def test_decision_serializes_policy_provenance(self) -> None:
|
||||
decision = SchedulingParticipantPrivacyDecision(
|
||||
effective_visibility="aggregates_only",
|
||||
reason="Tenant privacy policy restricts the participant roster.",
|
||||
source_path=(
|
||||
PolicySourceStep(
|
||||
scope_type="tenant",
|
||||
scope_id="tenant-1",
|
||||
label="Tenant",
|
||||
applied_fields=("scheduling_participant_visibility",),
|
||||
),
|
||||
),
|
||||
details={"requested_visibility": "names_and_statuses"},
|
||||
)
|
||||
|
||||
payload = decision.to_dict()
|
||||
self.assertEqual(payload["effective_visibility"], "aggregates_only")
|
||||
self.assertEqual(payload["source_path"][0]["path"], "tenant:tenant-1")
|
||||
self.assertEqual(payload["details"]["requested_visibility"], "names_and_statuses")
|
||||
|
||||
def test_optional_provider_resolves_through_platform_registry(self) -> None:
|
||||
provider = _PrivacyPolicy()
|
||||
self.assertIsInstance(provider, SchedulingParticipantPrivacyPolicy)
|
||||
|
||||
registry = PlatformRegistry()
|
||||
registry.register(
|
||||
ModuleManifest(
|
||||
id="policy_test",
|
||||
name="Policy test",
|
||||
version="test",
|
||||
capability_factories={
|
||||
CAPABILITY_POLICY_SCHEDULING_PARTICIPANT_PRIVACY: lambda context: provider,
|
||||
},
|
||||
),
|
||||
)
|
||||
registry.configure_capability_context(ModuleContext(registry=registry, settings=object()))
|
||||
|
||||
self.assertIs(scheduling_participant_privacy_policy(registry), provider)
|
||||
|
||||
def test_optional_provider_lookup_does_not_choose_a_fallback(self) -> None:
|
||||
self.assertIsNone(scheduling_participant_privacy_policy(None))
|
||||
self.assertIsNone(scheduling_participant_privacy_policy(PlatformRegistry()))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user