Coverage for src/lexigram/admin/dashboard/settings_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 SettingsPanelDefinition, 

11) 

12 

13 

14class SettingsPanelAssembler: 

15 """Collects and validates ``SettingsPanelDefinition`` 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[SettingsPanelDefinition]: 

31 """Collect settings panels from all *contributors*.""" 

32 collected: list[SettingsPanelDefinition] = [] 

33 for c in contributors: 

34 for panel in c.get_settings_panels(): 

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

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

37 p = SettingsPanelDefinition( 

38 name=ns_name, 

39 title=panel.title, 

40 contributor=c.package_source, 

41 route_path=panel.route_path, 

42 handler=panel.handler, 

43 icon=panel.icon, 

44 category=panel.category, 

45 permission=panel.permission, 

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 )