Coverage for src/lexigram/admin/dashboard/page_assembler.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-21 14:56 +0800

1from __future__ import annotations 

2 

3from collections.abc import Sequence 

4 

5from lexigram.admin.dashboard.naming_policy import NamingPolicy 

6from lexigram.admin.dashboard.permission_filter import PermissionFilter 

7from lexigram.admin.types import AdminUser 

8from lexigram.contracts.admin import ( 

9 BaseAdminContributor, 

10 ManagementPageDefinition, 

11) 

12 

13 

14class PageAssembler: 

15 """Collects and validates ``ManagementPageDefinition`` from contributors.""" 

16 

17 def __init__( 

18 self, 

19 *, 

20 naming_policy: NamingPolicy, 

21 permission_filter: PermissionFilter, 

22 ) -> None: 

23 self._naming = naming_policy 

24 self._perms = permission_filter 

25 

26 def assemble( 

27 self, 

28 contributors: Sequence[BaseAdminContributor], 

29 user: AdminUser | None = None, 

30 ) -> list[ManagementPageDefinition]: 

31 """Collect pages from all *contributors*, namespacing and filtering.""" 

32 collected: list[ManagementPageDefinition] = [] 

33 for c in contributors: 

34 for page in c.get_management_pages(): 

35 ns_name = self._naming.namespaced(c.package_source, page.name) 

36 self._naming.register("page", ns_name) 

37 p = ManagementPageDefinition( 

38 name=ns_name, 

39 title=page.title, 

40 contributor=c.package_source, 

41 route_path=page.route_path, 

42 handler=page.handler, 

43 category=page.category, 

44 permission=page.permission, 

45 filters=page.filters, 

46 ) 

47 collected.append(p) 

48 return self._perms.filter( 

49 collected, 

50 user, 

51 get_required_permissions=lambda p: ( 

52 frozenset({p.permission}) if p.permission else frozenset() 

53 ), 

54 )