from __future__ import annotations import unittest from govoplan_core.core.access import GroupRef, UserRef from govoplan_views.backend.router import ( _all_assignment_targets, _search_assignment_targets, _validate_assignment_target, ) from govoplan_views.backend.service import ViewsValidationError class FakeDirectory: def users_for_tenant(self, tenant_id: str) -> tuple[UserRef, ...]: return ( UserRef( id="membership-ada", account_id="account-ada", tenant_id=tenant_id, email="ada@example.test", display_name="Ada Lovelace", ), UserRef( id="membership-inactive", account_id="account-inactive", tenant_id=tenant_id, email="inactive@example.test", status="inactive", ), ) def groups_for_tenant(self, tenant_id: str) -> tuple[GroupRef, ...]: return ( GroupRef( id="group-finance", tenant_id=tenant_id, name="Finance", ), GroupRef( id="group-retired", tenant_id=tenant_id, name="Retired group", status="inactive", ), ) class ViewAssignmentTargetTests(unittest.TestCase): def setUp(self) -> None: self.directory = FakeDirectory() def test_user_targets_store_account_ids_and_expose_readable_labels(self) -> None: targets = _all_assignment_targets( self.directory, # type: ignore[arg-type] tenant_id="tenant-1", scope_type="user", ) self.assertEqual("account-ada", targets[0].id) self.assertEqual("Ada Lovelace", targets[0].label) self.assertEqual("ada@example.test", targets[0].detail) self.assertNotEqual("membership-ada", targets[0].id) def test_search_matches_labels_and_secondary_details(self) -> None: by_name = _search_assignment_targets( self.directory, # type: ignore[arg-type] tenant_id="tenant-1", scope_type="group", query="finance", limit=10, ) by_email = _search_assignment_targets( self.directory, # type: ignore[arg-type] tenant_id="tenant-1", scope_type="user", query="ada@example", limit=10, ) self.assertEqual(["group-finance"], [target.id for target in by_name]) self.assertEqual(["account-ada"], [target.id for target in by_email]) def test_inactive_and_unknown_targets_cannot_receive_new_assignments(self) -> None: with self.assertRaisesRegex(ViewsValidationError, "inactive"): _validate_assignment_target( self.directory, # type: ignore[arg-type] tenant_id="tenant-1", scope_type="user", scope_id="account-inactive", ) with self.assertRaisesRegex(ViewsValidationError, "does not exist"): _validate_assignment_target( self.directory, # type: ignore[arg-type] tenant_id="tenant-1", scope_type="group", scope_id="group-missing", ) if __name__ == "__main__": unittest.main()