feat: add operational Dashboard

This commit is contained in:
lussierj committed 2026-08-17 17:11:40 +00:00
1 parent 4a1959ecd6
commit b8b741ccee
23 files changed
+1278 -59

No files matched your search

+84 -5
View File
@@ -132,13 +132,41 @@ class FrontendShellTests(unittest.TestCase):
def test_dashboard_does_not_fabricate_operational_values(self):
self.authenticate()
response = self.client.get("/dashboard")
self.assertIn(
"Live health summary not yet connected",
response.text,
)
self.assertIn("No events are fabricated", response.text)
for value in (
'id="dashboardFleetTotal"',
'id="dashboardActiveRepairs"',
'id="dashboardSites"',
"/assets/minerops-dashboard.js",
"Runtime and lifecycle are separate dimensions",
):
self.assertIn(value, response.text)
self.assertIn("Loading operational overview", response.text)
self.assertNotIn("Live health summary not yet connected", response.text)
self.assertNotIn("100 TH/s", response.text)
def test_dashboard_html_omits_unauthorized_sections_and_links(self):
self.authenticate(permissions=("dashboard.view", "locations.view"))
response = self.client.get("/dashboard")
self.assertIn("Locations", response.text)
self.assertIn("Open Mine Map", response.text)
self.assertNotIn("Fleet overview", response.text)
self.assertNotIn("Needs attention", response.text)
self.assertNotIn("Open Fleet", response.text)
self.assertNotIn("Active repair records", response.text)
self.assertNotIn("Open Repair Center", response.text)
self.assertNotIn("Mapped miners", response.text)
self.assertNotIn("Unmapped miners", response.text)
def test_dashboard_script_dom_contract_matches_authorized_page(self):
self.authenticate()
response = self.client.get("/dashboard")
javascript = (STATIC_ROOT / "dashboard.js").read_text(encoding="utf-8")
declared_ids = re.search(r"const ids = \[(.*?)\];", javascript, re.DOTALL)
self.assertIsNotNone(declared_ids)
required = set(re.findall(r'"([A-Za-z][A-Za-z0-9]+)"', declared_ids.group(1)))
rendered = set(re.findall(r'id="([A-Za-z][A-Za-z0-9]+)"', response.text))
self.assertEqual(required - rendered, set())
def test_map_is_a_structured_operational_view(self):
self.authenticate()
response = self.client.get("/monitoring/map")
@@ -230,6 +258,7 @@ class FrontendShellTests(unittest.TestCase):
def test_live_app_prefers_new_shell_and_preserves_legacy_pages(self):
from app.main import app
from app.frontend.router import dashboard_page
first_handlers = {}
for route in app.routes:
@@ -250,6 +279,55 @@ class FrontendShellTests(unittest.TestCase):
with self.subTest(legacy_path=path):
self.assertIn(path, first_handlers)
dashboard_handlers = [
route.endpoint
for route in app.routes
if route.path == "/dashboard" and "GET" in (route.methods or set())
]
self.assertIs(dashboard_handlers[0], dashboard_page)
self.assertEqual(dashboard_handlers.count(dashboard_page), 1)
def test_live_dashboard_excludes_legacy_dashboard_injections(self):
from app.main import app
current_user = {
"id": "00000000-0000-0000-0000-000000000654",
"username": "dashboard-reader",
"display_name": "Dashboard Reader",
"role": "Read Only",
"permissions": [
"dashboard.view",
"miners.view",
"locations.view",
"repairs.view",
],
}
app.dependency_overrides[get_current_user] = lambda: current_user
try:
with patch(
"app.identity.request_user_or_none",
return_value=current_user,
):
client = TestClient(app)
try:
response = client.get("/dashboard")
finally:
client.close()
finally:
app.dependency_overrides.pop(get_current_user, None)
self.assertEqual(response.status_code, 200)
self.assertIn("<title>Dashboard | MinerOps</title>", response.text)
self.assertIn('id="dashboardFleetTotal"', response.text)
self.assertEqual(response.text.count('id="dashboardFleetTotal"'), 1)
self.assertNotIn("/assets/minerops-repair-quick-nav.js", response.text)
self.assertNotIn(
"/assets/minerops-dashboard-repair-summary.js",
response.text,
)
self.assertNotIn("mineropsDashboardRepairSummary", response.text)
self.assertNotIn("Repair Summary", response.text)
def test_safe_next_path_accepts_only_protected_local_pages(self):
valid = (
@@ -365,6 +443,7 @@ class FrontendShellTests(unittest.TestCase):
for path in (
"/assets/minerops-app.css",
"/assets/minerops-app.js",
"/assets/minerops-dashboard.js",
"/assets/minerops-mine-map.js",
"/assets/minerops-fleet.js",
):