gateway/tests/unit/graphicalEditor/test_route_options_feature_instance.py
2026-04-26 08:31:35 +02:00

66 lines
2.6 KiB
Python

# Copyright (c) 2026 Patrick Motsch
# All rights reserved.
"""
Smoke test for the new ``GET /options/feature.instance`` endpoint that backs
the frontend ``FeatureInstancePicker`` (Schicht-4 / Phase-5 follow-up).
A heavyweight HTTP integration test would need the full FastAPI client +
DB fixtures; this lightweight test asserts at the router level that the
endpoint exists with the expected method, path, and required query
parameter, so a refactor that drops or renames it fails loudly.
Track-doc: ``wiki/c-work/2-build/2026-04-feature-instance-ref-adapter-migration.md``.
"""
from __future__ import annotations
import pytest
from modules.features.graphicalEditor.routeFeatureGraphicalEditor import router
def _findRoute(path: str, method: str = "GET"):
for route in router.routes:
# FastAPI routes expose `path` and `methods` attributes.
if getattr(route, "path", None) == path and method in (
getattr(route, "methods", set()) or set()
):
return route
return None
_ROUTE_PATH = "/api/workflows/{instanceId}/options/feature.instance"
def test_optionsFeatureInstanceRouteIsRegistered() -> None:
"""The picker endpoint must be available at the documented path."""
route = _findRoute(_ROUTE_PATH, "GET")
assert route is not None, (
f"GET {_ROUTE_PATH} is not registered on graphicalEditor router. "
"The FeatureInstancePicker will fail to load mandate-scoped instances."
)
def test_optionsFeatureInstanceRouteRequiresFeatureCode() -> None:
"""``featureCode`` must be a required query parameter (no default)."""
route = _findRoute(_ROUTE_PATH, "GET")
assert route is not None
endpoint = route.endpoint
sig = __import__("inspect").signature(endpoint)
featureCode = sig.parameters.get("featureCode")
assert featureCode is not None, "featureCode parameter missing"
# FastAPI's Query(...) sentinel produces a FieldInfo whose `is_required()`
# returns True; older variants encoded the same intent via
# `default is Ellipsis` or `default.default is Ellipsis`. Accept any of
# those so the test stays robust across FastAPI/Pydantic versions.
default = featureCode.default
isRequiredFn = getattr(default, "is_required", None)
isRequired = (
(callable(isRequiredFn) and isRequiredFn())
or default is ...
or getattr(default, "default", None) is ...
)
assert isRequired, (
"featureCode must be a required Query parameter; otherwise the picker "
"could ask for ALL feature instances of the mandate, which is not the "
"intent of /options/feature.instance."
)