from __future__ import annotations import json import re import unittest from pathlib import Path from unittest.mock import patch from tests.preservation_helpers import reassembled_frontend_runtime ROOT = Path(__file__).resolve().parents[1] STATIC = ROOT / "frontend" class FrontendBoundaryTests(unittest.TestCase): def test_shared_api_is_the_only_application_fetch_exit(self) -> None: fetch_files = [] for path in STATIC.rglob("*.js"): if "vendor" in path.parts: continue if re.search(r"\bfetch\s*\(", path.read_text(encoding="utf-8")): fetch_files.append(path.relative_to(STATIC).as_posix()) self.assertEqual(fetch_files, ["shared/api.js"]) def test_shared_dependencies_load_before_application(self) -> None: html = (STATIC / "index.html").read_text(encoding="utf-8") ui_position = html.index('/shared/ui-core.js') components_position = html.index('/shared/components.js') pages_position = html.index('/pages.config.js') runtime_position = html.index('/pages/runtime.js') state_position = html.index('/shared/state.js') api_position = html.index('/shared/api.js') shell_position = html.index('/shared/shell.js') app_position = html.index('/app.js') self.assertLess(ui_position, components_position) self.assertLess(components_position, pages_position) self.assertLess(pages_position, state_position) self.assertLess(pages_position, runtime_position) self.assertLess(runtime_position, state_position) self.assertLess(state_position, api_position) self.assertLess(api_position, shell_position) self.assertLess(shell_position, app_position) def test_application_state_is_created_through_shared_boundary(self) -> None: app = reassembled_frontend_runtime() self.assertIn("const state = window.XiaobaiState.create({", app) self.assertNotIn("const state = {", app) def test_candidate_runtime_reassembly_does_not_require_original_static(self) -> None: with patch( "tests.preservation_helpers.ORIGINAL_STATIC", ROOT / "missing-original-static", ): app = reassembled_frontend_runtime() self.assertIn("function openView(", app) def test_runtime_page_registry_matches_governance_registry(self) -> None: expected = json.loads( (ROOT / "config" / "pages.config.json").read_text(encoding="utf-8") )["pages"] runtime = (STATIC / "pages.config.js").read_text(encoding="utf-8") rows = re.findall( r'^\s*\["([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", (true|false)\],$', runtime, re.MULTILINE, ) actual = [ { "id": row[0], "title": row[1], "feature": row[2], "group": row[3], "access": row[4], "default": row[5] == "true", "desktop_scroll": "page", "mobile_layout": "dedicated", } for row in rows ] self.assertEqual(actual, expected) def test_shell_owns_navigation_and_page_mounting(self) -> None: app = reassembled_frontend_runtime() shell = (STATIC / "shared" / "shell.js").read_text(encoding="utf-8") self.assertNotIn("function syncNavigationState", app) self.assertNotIn("function initializeApplicationShell", app) self.assertIn("function syncNavigation(viewId)", shell) self.assertIn("function mount(viewId, mountOptions = {})", shell) self.assertIn("function openModalDialog(dialog)", shell) self.assertNotIn('document.querySelectorAll(".module-tab").forEach', app) def test_every_registered_view_has_one_feature_page_module(self) -> None: html = (STATIC / "index.html").read_text(encoding="utf-8") runtime_position = html.index('/pages/runtime.js') app_position = html.index('/app.js') expected = { page["id"]: page["feature"] for page in json.loads( (ROOT / "config" / "pages.config.json").read_text(encoding="utf-8") )["pages"] } expected["screenerTrackingView"] = "screener" actual: dict[str, str] = {} for path in (STATIC / "pages").glob("*/page.js"): script_url = f'/pages/{path.parent.name}/page.js' self.assertIn(script_url, html) self.assertLess(runtime_position, html.index(script_url)) self.assertLess(html.index(script_url), app_position) script = path.read_text(encoding="utf-8") for match in re.finditer( r'XiaobaiPageModules\.register\("([^"]+)",\s*\[(.*?)\]', script, re.DOTALL, ): feature = match.group(1) for view_id in re.findall(r'"([A-Za-z][A-Za-z0-9]+)"', match.group(2)): self.assertNotIn(view_id, actual) actual[view_id] = feature self.assertEqual(actual, expected) def test_page_lifecycle_is_owned_outside_application_monolith(self) -> None: app = reassembled_frontend_runtime() runtime = (STATIC / "pages" / "runtime.js").read_text(encoding="utf-8") start = app.index("function openView(") end = app.index("\nfunction initializeAutoTableSorting", start) open_view = app[start:end] self.assertIn("pageModules.beforeMount(viewId, previousView);", open_view) self.assertIn("pageModules.afterMount(viewId, previousView);", open_view) self.assertNotRegex(open_view, r'viewId\s*[!=]==?\s*"') self.assertIn("function beforeMount(viewId, previousView)", runtime) self.assertIn("function afterMount(viewId, previousView)", runtime) def test_shared_empty_state_component_is_used_by_multiple_features(self) -> None: components = (STATIC / "shared" / "components.js").read_text(encoding="utf-8") app = reassembled_frontend_runtime() self.assertIn("function emptyStateHtml(message, options = {})", components) self.assertIn("function renderEmptyState(target, message, options = {})", components) self.assertGreaterEqual(app.count("renderEmptyState("), 8) self.assertGreaterEqual(app.count("emptyStateHtml("), 8) if __name__ == "__main__": unittest.main()