""" Peer access-control tests (scenarios 14 & 15). PrivateRoute.jsx (confirmed): - Unauthenticated users → - Authenticated user with wrong role → A peer (role='peer') visiting an admin-only route must be redirected to '/'. A peer must NOT see admin sidebar links (Peers, Settings, WireGuard, etc.). """ import pytest pytestmark = pytest.mark.ui # All routes that require role='admin' (from App.jsx Routes). ADMIN_ONLY_ROUTES = [ '/peers', '/network', '/wireguard', '/email', '/calendar', '/files', '/routing', '/vault', '/containers', '/cell-network', '/logs', '/settings', ] # Admin-only sidebar link names (from App.jsx adminNavigation). ADMIN_ONLY_NAV_LINKS = [ 'Peers', 'Network Services', 'WireGuard', 'Email', 'Calendar', 'Files', 'Routing', 'Vault', 'Containers', 'Cell Network', 'Logs', 'Settings', ] # ── Scenario 14: peer redirected from admin routes ─────────────────────────── @pytest.mark.parametrize('admin_route', ADMIN_ONLY_ROUTES) def test_peer_redirected_from_admin_route(peer_page, webui_base, admin_route): """ A peer navigating to an admin-only route must NOT land on that route. PrivateRoute redirects them to '/' instead. """ page, _ = peer_page page.goto(f"{webui_base}{admin_route}") page.wait_for_load_state('networkidle') current_path = page.url.replace(webui_base, '') assert current_path.rstrip('/') not in [admin_route.rstrip('/')], ( f"Peer was allowed to reach admin-only route '{admin_route}'. " f"Expected redirect to '/'. Got: {page.url}" ) # Must not have been sent to /login either — peer IS authenticated. assert '/login' not in page.url, ( f"Peer was unexpectedly redirected to /login from '{admin_route}'. " "PrivateRoute should redirect role-mismatches to '/', not /login." ) # ── Scenario 15: peer sidebar lacks admin links ────────────────────────────── def test_peer_nav_does_not_show_admin_only_links(peer_page, webui_base): """ The peer sidebar (peerNavigation in App.jsx) only contains Dashboard, My Services, and Account. Admin-only links must be absent. """ page, _ = peer_page # Navigate to root so the sidebar is fully rendered. page.goto(f"{webui_base}/") page.wait_for_load_state('networkidle') for link_name in ADMIN_ONLY_NAV_LINKS: assert not page.get_by_role('link', name=link_name).first.is_visible(), ( f"Admin-only sidebar link '{link_name}' should NOT be visible to a peer" ) def test_peer_nav_shows_allowed_links(peer_page, webui_base): """ The peer sidebar must contain exactly the three peer navigation items: Dashboard, My Services, Account. """ page, _ = peer_page page.goto(f"{webui_base}/") page.wait_for_load_state('networkidle') # Use .first to avoid strict-mode errors when desktop + mobile nav are both mounted. for link_name in ('Dashboard', 'My Services', 'Account'): assert page.get_by_role('link', name=link_name).first.is_visible(), ( f"Peer sidebar should show link '{link_name}'" ) def test_peer_my_services_is_accessible(peer_page, webui_base): """ /my-services is restricted to role='peer' (requireRole="peer" in App.jsx). A logged-in peer must be able to reach it. """ page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') assert '/login' not in page.url assert '/my-services' in page.url