"""Tests for the Phase 1 operator console application shell (#638).""" import sys import unittest from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from starlette.routing import Route from starlette.testclient import TestClient from webui import layout from webui.app import create_app from webui.nav import NAV_GROUPS, STUB_PAGES, nav_hrefs class TestShellNav(unittest.TestCase): def setUp(self): self.client = TestClient(create_app()) def test_nav_group_labels_present(self): text = self.client.get("/").text for group in NAV_GROUPS: with self.subTest(group=group.label): self.assertIn(f">{group.label}<", text) def test_phase1_group_labels_cover_expected_ia(self): labels = {group.label for group in NAV_GROUPS} for expected in ( "Health", "Traffic", "Runtime/Sessions", "Projects", "Inventory", "Timeline", "Policy", "Insights", ): with self.subTest(label=expected): self.assertIn(expected, labels) def test_every_nav_href_resolves_to_a_get_route(self): app = create_app() get_paths = { route.path for route in app.routes if isinstance(route, Route) and "GET" in route.methods } for href in nav_hrefs(): with self.subTest(href=href): self.assertIn(href, get_paths, f"nav href {href} has no GET route") def test_legacy_hrefs_still_navigable(self): text = self.client.get("/").text for href in ("/queue", "/projects", "/prompts", "/runtime", "/audit", "/worktrees", "/leases", "/actions"): with self.subTest(href=href): self.assertIn(f'href="{href}"', text) class TestShellBadges(unittest.TestCase): def setUp(self): self.client = TestClient(create_app()) def test_mode_badge_present(self): self.assertIn("mode: read-only", self.client.get("/").text) def test_environment_badge_present(self): self.assertIn("env:", self.client.get("/").text) def test_default_environment_is_local(self): self.assertEqual(layout.environment_label(), "local") def test_remote_bind_reports_remote_environment(self): import os prior = os.environ.get("WEBUI_HOST") os.environ["WEBUI_HOST"] = "10.0.0.5" try: self.assertEqual(layout.environment_label(), "remote") finally: if prior is None: os.environ.pop("WEBUI_HOST", None) else: os.environ["WEBUI_HOST"] = prior def test_docs_link_present(self): text = self.client.get("/").text self.assertIn(layout.DOCS_URL, text) self.assertIn(">Docs<", text) class TestShellStubs(unittest.TestCase): def setUp(self): self.client = TestClient(create_app()) def test_stub_routes_render_200(self): for path, (title, _desc) in STUB_PAGES.items(): with self.subTest(path=path): response = self.client.get(path) self.assertEqual(response.status_code, 200, path) self.assertIn(title, response.text) self.assertIn("placeholder", response.text) def test_stub_routes_are_read_only(self): for path in STUB_PAGES: with self.subTest(path=path): response = self.client.post(path) self.assertEqual(response.status_code, 405) self.assertEqual(response.json()["error"], "read-only-mvp") def test_stub_pages_carry_nav_and_badges(self): response = self.client.get("/inventory") self.assertIn("mode: read-only", response.text) self.assertIn('href="/queue"', response.text) class TestShellHome(unittest.TestCase): def setUp(self): self.client = TestClient(create_app()) def test_home_summarizes_console(self): text = self.client.get("/").text self.assertIn("Operator console", text) self.assertIn("Phase 1", text) def test_home_links_legacy_pages(self): text = self.client.get("/").text self.assertIn("MVP legacy pages", text) for href in ("/queue", "/audit", "/leases"): with self.subTest(href=href): self.assertIn(f'href="{href}"', text) if __name__ == "__main__": unittest.main()