|
18 | 18 | ) |
19 | 19 | from aignostics_foundry_core.gui.nav import ( |
20 | 20 | BaseNavBuilder, |
21 | | - NavGroup, |
22 | 21 | NavItem, |
23 | 22 | gui_get_nav_groups, |
24 | 23 | ) |
@@ -62,41 +61,6 @@ def test_explicit_marker_is_preserved(self) -> None: |
62 | 61 | item = NavItem(icon="home", label="Home", target="/", marker="MY_CUSTOM_MARKER") |
63 | 62 | assert item.marker == "MY_CUSTOM_MARKER" |
64 | 63 |
|
65 | | - def test_new_tab_defaults_to_false(self) -> None: |
66 | | - """new_tab defaults to False (same-tab navigation).""" |
67 | | - item = NavItem(icon="link", label="Link", target="/link") |
68 | | - assert item.new_tab is False |
69 | | - |
70 | | - |
71 | | -# --------------------------------------------------------------------------- |
72 | | -# NavGroup |
73 | | -# --------------------------------------------------------------------------- |
74 | | - |
75 | | - |
76 | | -@pytest.mark.unit |
77 | | -class TestNavGroup: |
78 | | - """Tests for NavGroup dataclass defaults.""" |
79 | | - |
80 | | - def test_position_default(self) -> None: |
81 | | - """Default position is 1000 (lowest priority).""" |
82 | | - group = NavGroup(name="My Module") |
83 | | - assert group.position == 1000 |
84 | | - |
85 | | - def test_icon_default(self) -> None: |
86 | | - """Default icon is 'folder'.""" |
87 | | - group = NavGroup(name="My Module") |
88 | | - assert group.icon == "folder" |
89 | | - |
90 | | - def test_use_expansion_default(self) -> None: |
91 | | - """Default use_expansion is True.""" |
92 | | - group = NavGroup(name="My Module") |
93 | | - assert group.use_expansion is True |
94 | | - |
95 | | - def test_items_default_empty(self) -> None: |
96 | | - """Default items list is empty.""" |
97 | | - group = NavGroup(name="My Module") |
98 | | - assert group.items == [] |
99 | | - |
100 | 64 |
|
101 | 65 | # --------------------------------------------------------------------------- |
102 | 66 | # BaseNavBuilder |
@@ -195,10 +159,40 @@ def get_nav_items() -> list[NavItem]: |
195 | 159 | return [] |
196 | 160 |
|
197 | 161 | with patch(_PATH_NAV_LOCATE, return_value=[EmptyBuilder]): |
198 | | - result = gui_get_nav_groups("myproject") |
| 162 | + result = gui_get_nav_groups(_PROJECT_NAME) |
199 | 163 |
|
200 | 164 | assert result == [] |
201 | 165 |
|
| 166 | + def test_builder_without_explicit_position_sorts_after_lower_position(self) -> None: |
| 167 | + """A builder with no position override (default 1000) sorts after one with explicit 100.""" |
| 168 | + |
| 169 | + class DefaultPositionBuilder(BaseNavBuilder): |
| 170 | + @staticmethod |
| 171 | + def get_nav_name() -> str: |
| 172 | + return "Default" |
| 173 | + |
| 174 | + @staticmethod |
| 175 | + def get_nav_items() -> list[NavItem]: |
| 176 | + return [NavItem(icon="d", label="D", target="/d")] |
| 177 | + |
| 178 | + class ExplicitPositionBuilder(BaseNavBuilder): |
| 179 | + @staticmethod |
| 180 | + def get_nav_name() -> str: |
| 181 | + return "Explicit" |
| 182 | + |
| 183 | + @staticmethod |
| 184 | + def get_nav_items() -> list[NavItem]: |
| 185 | + return [NavItem(icon="e", label="E", target="/e")] |
| 186 | + |
| 187 | + @staticmethod |
| 188 | + def get_nav_position() -> int: |
| 189 | + return 100 |
| 190 | + |
| 191 | + with patch(_PATH_NAV_LOCATE, return_value=[DefaultPositionBuilder, ExplicitPositionBuilder]): |
| 192 | + result = gui_get_nav_groups(_PROJECT_NAME) |
| 193 | + |
| 194 | + assert [g.name for g in result] == ["Explicit", "Default"] |
| 195 | + |
202 | 196 |
|
203 | 197 | # --------------------------------------------------------------------------- |
204 | 198 | # BasePageBuilder |
@@ -712,11 +706,15 @@ def test_registers_route_with_ui_page(self) -> None: |
712 | 706 | class TestGUINamespace: |
713 | 707 | """Tests for GUINamespace and the gui singleton.""" |
714 | 708 |
|
715 | | - def test_gui_singleton_is_gui_namespace(self) -> None: |
716 | | - """The module-level gui object is an instance of GUINamespace.""" |
717 | | - from aignostics_foundry_core.gui.auth import GUINamespace, gui |
| 709 | + def test_gui_exposes_all_decorator_methods(self) -> None: |
| 710 | + """The gui singleton exposes all page decorator methods as callables.""" |
| 711 | + from aignostics_foundry_core.gui.auth import gui |
718 | 712 |
|
719 | | - assert isinstance(gui, GUINamespace) |
| 713 | + assert callable(gui.public) |
| 714 | + assert callable(gui.authenticated) |
| 715 | + assert callable(gui.admin) |
| 716 | + assert callable(gui.internal) |
| 717 | + assert callable(gui.internal_admin) |
720 | 718 |
|
721 | 719 | def test_public_method_delegates_to_page_public(self) -> None: |
722 | 720 | """GUINamespace.public registers a route via ui.page.""" |
|
0 commit comments