from __future__ import annotations from pathlib import Path import unittest from govoplan_notifications.backend.manifest import get_manifest REPO_ROOT = Path(__file__).resolve().parents[1] class NotificationsInterfaceDocumentationContractTests(unittest.TestCase): def test_backend_surfaces_and_hierarchy_remain_declared(self) -> None: frontend = get_manifest().frontend self.assertIsNotNone(frontend) surfaces = {item.id: item for item in frontend.view_surfaces} # type: ignore[union-attr] expected = { "notifications.page.inbox", "notifications.page.detail", "notifications.page.delivery", "notifications.action.mark-read", "notifications.action.acknowledge", "notifications.action.cancel", "notifications.action.dispatch", "notifications.settings.preferences", "notifications.widget.summary", } self.assertEqual(expected, set(surfaces)) self.assertEqual( "notifications.route.notifications", frontend.routes[0].surface_id, # type: ignore[union-attr] ) self.assertEqual( "notifications.route.notifications", surfaces["notifications.page.inbox"].parent_id, ) self.assertEqual( "notifications.route.notifications", surfaces["notifications.page.detail"].parent_id, ) self.assertEqual( "notifications.page.detail", surfaces["notifications.page.delivery"].parent_id, ) self.assertEqual( "notifications.page.delivery", surfaces["notifications.action.dispatch"].parent_id, ) def test_help_and_consequence_metadata_remain_published(self) -> None: topics = {topic.id: topic for topic in get_manifest().documentation} center = topics["notifications.center-and-preferences"] delivery = topics["notifications.delivery-operations"] self.assertIn("notifications.page.detail", center.metadata["help_contexts"]) self.assertIn("notifications.settings.preferences", center.metadata["help_contexts"]) self.assertIn("acknowledge", center.metadata["consequence_classes"]) self.assertIn("cancel", center.metadata["consequence_classes"]) self.assertIn("notifications.action.dispatch", delivery.metadata["help_contexts"]) self.assertIn("dispatch_pending", delivery.metadata["consequence_classes"]) def test_webui_uses_shared_consequence_and_draft_patterns(self) -> None: center = (REPO_ROOT / "webui/src/features/notifications/NotificationCenterPage.tsx").read_text(encoding="utf-8") settings = (REPO_ROOT / "webui/src/features/notifications/NotificationSettingsPanel.tsx").read_text(encoding="utf-8") widget = (REPO_ROOT / "webui/src/features/notifications/NotificationSummaryWidget.tsx").read_text(encoding="utf-8") for component in ( "ActionBlockerHint", "ConfirmDialog", "DocumentationHelpLink", "SelectionList", ): self.assertIn(component, center) for component in ( "ActionBlockerHint", "DocumentationHelpLink", "ReferenceMultiSelect", "useUnsavedDraftGuard", ): self.assertIn(component, settings) self.assertIn("DocumentationHelpLink", widget) if __name__ == "__main__": unittest.main()