Add product presentation extension contracts
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from govoplan_core.auth import get_api_principal
|
||||
from govoplan_core.core.modules import (
|
||||
FrontendModule,
|
||||
FrontendRoute,
|
||||
ModuleManifest,
|
||||
ProductAreaContribution,
|
||||
QuickAccessTool,
|
||||
)
|
||||
from govoplan_core.core.registry import PlatformRegistry, RegistryError
|
||||
from govoplan_core.core.views import ViewSurface
|
||||
from govoplan_core.server.platform import create_platform_router
|
||||
|
||||
|
||||
def presentation_manifest() -> ModuleManifest:
|
||||
return ModuleManifest(
|
||||
id="example",
|
||||
name="Example",
|
||||
version="test",
|
||||
frontend=FrontendModule(
|
||||
module_id="example",
|
||||
routes=(
|
||||
FrontendRoute(
|
||||
path="/example",
|
||||
component="ExamplePage",
|
||||
surface_id="example.route.main",
|
||||
),
|
||||
),
|
||||
view_surfaces=(
|
||||
ViewSurface(
|
||||
id="example.quick.summary",
|
||||
module_id="example",
|
||||
kind="quick_access",
|
||||
label="Example summary",
|
||||
),
|
||||
),
|
||||
product_areas=(
|
||||
ProductAreaContribution(
|
||||
id="work",
|
||||
module_id="example",
|
||||
label="Work",
|
||||
icon="list-checks",
|
||||
surface_ids=("example.route.main",),
|
||||
),
|
||||
),
|
||||
quick_access_tools=(
|
||||
QuickAccessTool(
|
||||
id="example.summary",
|
||||
module_id="example",
|
||||
category_id="work",
|
||||
label="Example summary",
|
||||
surface_id="example.quick.summary",
|
||||
icon="list-checks",
|
||||
full_page_path="/example",
|
||||
required_any=("example:item:read",),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class PresentationContractTests(unittest.TestCase):
|
||||
def test_registry_accepts_owned_presentation_contributions(self) -> None:
|
||||
registry = PlatformRegistry()
|
||||
registry.register(presentation_manifest())
|
||||
|
||||
snapshot = registry.validate()
|
||||
|
||||
self.assertEqual("example", snapshot.manifests[0].id)
|
||||
|
||||
def test_registry_rejects_unknown_tool_surface(self) -> None:
|
||||
manifest = presentation_manifest()
|
||||
frontend = manifest.frontend
|
||||
assert frontend is not None
|
||||
invalid = ModuleManifest(
|
||||
id=manifest.id,
|
||||
name=manifest.name,
|
||||
version=manifest.version,
|
||||
frontend=FrontendModule(
|
||||
module_id="example",
|
||||
routes=frontend.routes,
|
||||
quick_access_tools=(
|
||||
QuickAccessTool(
|
||||
id="example.summary",
|
||||
module_id="example",
|
||||
category_id="work",
|
||||
label="Example summary",
|
||||
surface_id="example.missing",
|
||||
icon="list-checks",
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
registry = PlatformRegistry()
|
||||
registry.register(invalid)
|
||||
|
||||
with self.assertRaisesRegex(RegistryError, "unknown surface"):
|
||||
registry.validate()
|
||||
|
||||
def test_platform_payload_exposes_presentation_catalogue(self) -> None:
|
||||
registry = PlatformRegistry()
|
||||
registry.register(presentation_manifest())
|
||||
registry.validate()
|
||||
app = FastAPI()
|
||||
app.state.govoplan_registry = registry
|
||||
app.include_router(create_platform_router(), prefix="/api/v1")
|
||||
app.dependency_overrides[get_api_principal] = lambda: object()
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.get("/api/v1/platform/modules")
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
frontend = response.json()["modules"][0]["frontend"]
|
||||
self.assertEqual("1", frontend["presentation_contract_version"])
|
||||
self.assertEqual("work", frontend["product_areas"][0]["id"])
|
||||
self.assertEqual("example.summary", frontend["quick_access_tools"][0]["id"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user