Release govoplan-views v0.1.22: unify interface contracts and documentation
This commit is contained in:
@@ -26,6 +26,7 @@ from govoplan_views.backend.db.models import (
|
||||
from govoplan_views.backend.dsar_provider import (
|
||||
VIEWS_DSAR_CAPABILITY,
|
||||
ViewsDsarProvider,
|
||||
_presentation_projection,
|
||||
)
|
||||
from govoplan_views.backend.manifest import manifest
|
||||
|
||||
@@ -118,6 +119,12 @@ class ViewsDsarProviderTests(unittest.TestCase):
|
||||
surface_contract_version="1.0.0",
|
||||
visible_surface_ids=["files.route.files"],
|
||||
presentation={
|
||||
"navigation": {
|
||||
"order": ["separator:work", "files.nav.files"],
|
||||
"hidden": ["mail.nav.mail"],
|
||||
"separators": [{"id": "separator:work", "label": "Personal layout", "private": "separator-private-do-not-export"}],
|
||||
"private": "navigation-private-do-not-export",
|
||||
},
|
||||
"navigation_mode": "flat",
|
||||
"quick_access_focused_tool_ids": ["files.recent"],
|
||||
"private_payload_do_not_export": f"private-{definition_id}",
|
||||
@@ -240,12 +247,28 @@ class ViewsDsarProviderTests(unittest.TestCase):
|
||||
exported = json.dumps([record.to_dict() for record in records])
|
||||
self.assertIn("My personal work", exported)
|
||||
self.assertIn("files.recent", exported)
|
||||
self.assertIn("Personal layout", exported)
|
||||
self.assertIn("files.nav.files", exported)
|
||||
self.assertNotIn("navigation-private-do-not-export", exported)
|
||||
self.assertNotIn("separator-private-do-not-export", exported)
|
||||
self.assertNotIn("personal-metadata-do-not-export", exported)
|
||||
self.assertNotIn("tenant-metadata-do-not-export", exported)
|
||||
self.assertNotIn("private-tenant-definition-do-not-export", exported)
|
||||
self.assertNotIn("definition-other-account", exported)
|
||||
self.assertNotIn("definition-other-tenant", exported)
|
||||
|
||||
def test_navigation_projection_is_bounded_and_preserves_inheritance(self) -> None:
|
||||
self.assertEqual({"navigation": None}, _presentation_projection({"navigation": None}))
|
||||
self.assertNotIn("separators", _presentation_projection({"navigation": {"order": []}})["navigation"])
|
||||
self.assertEqual([], _presentation_projection({"navigation": {"separators": []}})["navigation"]["separators"])
|
||||
for navigation in (
|
||||
{"order": ["files.nav.files"] * 257},
|
||||
{"separators": [{"id": "separator:work"}] * 257},
|
||||
{"separators": ["invalid"]},
|
||||
):
|
||||
with self.subTest(navigation=navigation), self.assertRaises(ValueError):
|
||||
_presentation_projection({"navigation": navigation})
|
||||
|
||||
def test_resource_references_narrow_and_conflicts_fail_closed(self) -> None:
|
||||
definition = self.provider.search_subject(
|
||||
self.session,
|
||||
|
||||
@@ -56,6 +56,10 @@ class ViewsInterfaceDocumentationContractTests(unittest.TestCase):
|
||||
)
|
||||
)
|
||||
self.assertEqual("reference", reference.metadata["kind"])
|
||||
self.assertIn("shared navigation editor", workflow.body)
|
||||
self.assertIn("gemeinsamen Navigationseditor", workflow.translations["de"]["body"])
|
||||
self.assertIn("Views cannot create navigation", reference.body)
|
||||
self.assertIn("keine Navigationssperren", reference.translations["de"]["body"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -207,6 +207,12 @@ class ViewsServiceTests(unittest.TestCase):
|
||||
catalogue=self.catalogue,
|
||||
actor_id="account-admin",
|
||||
presentation={
|
||||
"navigation": {
|
||||
"contract_version": "1",
|
||||
"order": ["separator:work", "files.nav.files"],
|
||||
"hidden": ["mail.nav.mail"],
|
||||
"separators": [{"id": "separator:work", "label": "My work"}],
|
||||
},
|
||||
"navigation_mode": "grouped",
|
||||
"product_area_order": ["work", "records-documents"],
|
||||
"product_area_labels": {"work": "My work"},
|
||||
@@ -254,6 +260,40 @@ class ViewsServiceTests(unittest.TestCase):
|
||||
catalogue=self.catalogue,
|
||||
)
|
||||
self.assertEqual("My work", state.effective.presentation["product_area_labels"]["work"])
|
||||
self.assertEqual(revision.presentation["navigation"], state.effective.presentation["navigation"])
|
||||
changed = create_revision(
|
||||
self.session,
|
||||
definition,
|
||||
visible_surface_ids=lockout_safe_surface_ids(),
|
||||
catalogue=self.catalogue,
|
||||
actor_id="account-admin",
|
||||
presentation={**revision.presentation, "navigation": {"separators": []}},
|
||||
)
|
||||
self.assertNotEqual(revision.content_hash, changed.content_hash)
|
||||
self.assertEqual([], changed.presentation["navigation"]["separators"])
|
||||
self.assertEqual("My work", revision.presentation["navigation"]["separators"][0]["label"])
|
||||
|
||||
def test_view_navigation_inheritance_flatness_and_bounds(self) -> None:
|
||||
self.assertNotIn("navigation", normalize_view_presentation({}))
|
||||
self.assertIsNone(normalize_view_presentation({"navigation": None})["navigation"])
|
||||
inherited = normalize_view_presentation({"navigation": {"order": [" files.nav.files ", "files.nav.files"]}})["navigation"]
|
||||
self.assertEqual(["files.nav.files"], inherited["order"])
|
||||
self.assertNotIn("separators", inherited)
|
||||
flat = normalize_view_presentation({"navigation": {"separators": []}})["navigation"]
|
||||
self.assertEqual([], flat["separators"])
|
||||
for navigation in (
|
||||
{"locked": ["files.nav.files"]},
|
||||
{"grant": ["files.read"]},
|
||||
{"contract_version": "2"},
|
||||
{"order": ["files.nav.files"] * 257},
|
||||
{"hidden": ["files.nav.files"] * 257},
|
||||
{"separators": [{"id": "separator:work", "label": "a" * 121}]},
|
||||
{"separators": [{"id": "files.nav.files", "label": "Not a separator"}]},
|
||||
{"separators": [{"id": "separator:work", "label": "Unsafe\nlabel"}]},
|
||||
{"separators": [{"id": "separator:work", "private": "payload"}]},
|
||||
):
|
||||
with self.subTest(navigation=navigation), self.assertRaises(ViewsValidationError):
|
||||
normalize_view_presentation({"navigation": navigation})
|
||||
|
||||
def test_view_presentation_rejects_unknown_or_unavailable_fields(self) -> None:
|
||||
with self.assertRaises(ViewsValidationError):
|
||||
|
||||
Reference in New Issue
Block a user