from __future__ import annotations import unittest from govoplan_core.core.modules import ModuleContext, ModuleManifest from govoplan_core.core.people import ( CAPABILITY_ACCESS_PEOPLE_SEARCH, CAPABILITY_ADDRESSES_PEOPLE_SEARCH, PeopleSearchGroup, PersonSearchCandidate, people_search_providers, person_selection_key, search_visible_people, ) from govoplan_core.core.registry import PlatformRegistry class FakePeopleSearchProvider: def __init__(self, *groups: PeopleSearchGroup) -> None: self.groups = groups self.calls: list[tuple[object, object, str, int]] = [] def search_people(self, session: object, principal: object, *, query: str, limit: int = 25): self.calls.append((session, principal, query, limit)) return self.groups class PeopleSearchContractTests(unittest.TestCase): def test_collects_optional_providers_in_stable_group_order(self) -> None: duplicate = PersonSearchCandidate( selection_key="account:1", kind="account", reference_id="1", display_name="Ada Lovelace", ) access = FakePeopleSearchProvider(PeopleSearchGroup(key="accounts", label="Accounts", candidates=(duplicate, duplicate))) addresses = FakePeopleSearchProvider( PeopleSearchGroup( key="contacts", label="Contacts", candidates=( PersonSearchCandidate( selection_key="contact:2:ada@example.test", kind="contact", reference_id="2", display_name="Ada Lovelace", email="ada@example.test", ), ), ) ) registry = PlatformRegistry() registry.register(ModuleManifest( id="access", name="Access", version="1.0.0", capability_factories={CAPABILITY_ACCESS_PEOPLE_SEARCH: lambda _context: access}, )) registry.register(ModuleManifest( id="addresses", name="Addresses", version="1.0.0", capability_factories={CAPABILITY_ADDRESSES_PEOPLE_SEARCH: lambda _context: addresses}, )) registry.configure_capability_context(ModuleContext(registry=registry, settings=object())) session = object() principal = object() groups = search_visible_people(registry, session, principal, query=" ada ", limit=200) self.assertEqual([group.key for group in groups], ["accounts", "contacts"]) self.assertEqual([len(group.candidates) for group in groups], [1, 1]) self.assertEqual(access.calls, [(session, principal, "ada", 100)]) self.assertEqual(addresses.calls, [(session, principal, "ada", 100)]) self.assertEqual(people_search_providers(None), ()) def test_omits_empty_groups_and_ignores_unrelated_capabilities(self) -> None: registry = PlatformRegistry() registry.register(ModuleManifest( id="access", name="Access", version="1.0.0", capability_factories={CAPABILITY_ACCESS_PEOPLE_SEARCH: lambda _context: object()}, )) registry.configure_capability_context(ModuleContext(registry=registry, settings=object())) self.assertEqual(search_visible_people(registry, object(), object(), query="ada"), ()) def test_selection_key_is_stable_and_validated(self) -> None: self.assertEqual( person_selection_key("Account", "account-1", email=" Ada@Example.Test "), "account:account-1:ada@example.test", ) with self.assertRaises(ValueError): person_selection_key("", "account-1") if __name__ == "__main__": unittest.main()