diff --git a/backend/infrahub/core/schema_manager.py b/backend/infrahub/core/schema_manager.py index 75f782bbf3..9e0f892836 100644 --- a/backend/infrahub/core/schema_manager.py +++ b/backend/infrahub/core/schema_manager.py @@ -903,9 +903,12 @@ def validate_menu_placements(self) -> None: if node.menu_placement: try: placement_node = self.get(name=node.menu_placement, duplicate=False) - except SchemaNotFoundError: - raise ValueError(f"{node.kind}: {node.menu_placement} is not a valid menu placement") from None - + except SchemaNotFoundError as exc: + raise SchemaNotFoundError( + branch_name=self.name, + identifier=node.menu_placement, + message=f"{node.kind} refers to an invalid menu placement node: {node.menu_placement}.", + ) from exc if node == placement_node: raise ValueError(f"{node.kind}: cannot be placed under itself in the menu") from None diff --git a/backend/tests/integration/schema_lifecycle/test_schema_missing_menu_placement.py b/backend/tests/integration/schema_lifecycle/test_schema_missing_menu_placement.py new file mode 100644 index 0000000000..076ea39112 --- /dev/null +++ b/backend/tests/integration/schema_lifecycle/test_schema_missing_menu_placement.py @@ -0,0 +1,30 @@ +from infrahub_sdk import InfrahubClient + +from .shared import ( + TestSchemaLifecycleBase, +) + + +class TestSchemaMissingMenuPlacement(TestSchemaLifecycleBase): + async def test_schema_missing_menu_placement(self, client: InfrahubClient): + schema = { + "version": "1.0", + "nodes": [ + { + "name": "BNode", + "namespace": "Infra", + "menu_placement": "UnexistingNode", + "label": "BNode", + "display_labels": ["name__value"], + "attributes": [{"name": "name", "kind": "Text", "unique": True}], + } + ], + } + + response = await client.schema.load(schemas=[schema], branch="main") + assert response.schema_updated is False + assert response.errors["errors"][0]["extensions"]["code"] == 422 + assert ( + response.errors["errors"][0]["message"] + == "InfraBNode refers to an invalid menu placement node: UnexistingNode." + ) diff --git a/backend/tests/unit/core/schema_manager/test_manager_schema.py b/backend/tests/unit/core/schema_manager/test_manager_schema.py index d2ddf74d95..c21d74dc12 100644 --- a/backend/tests/unit/core/schema_manager/test_manager_schema.py +++ b/backend/tests/unit/core/schema_manager/test_manager_schema.py @@ -835,10 +835,10 @@ async def test_schema_branch_validate_menu_placement(): schema = SchemaBranch(cache={}) schema.load_schema(schema=SchemaRoot(**FULL_SCHEMA)) - with pytest.raises(ValueError) as exc: + with pytest.raises(SchemaNotFoundError) as exc: schema.validate_menu_placements() - assert str(exc.value) == "TestSubObject: NoSuchObject is not a valid menu placement" + assert exc.value.message == "TestSubObject refers to an invalid menu placement node: NoSuchObject." async def test_schema_branch_validate_same_node_menu_placement(): diff --git a/changelog/4089.fixed.md b/changelog/4089.fixed.md new file mode 100644 index 0000000000..daa68d8f53 --- /dev/null +++ b/changelog/4089.fixed.md @@ -0,0 +1 @@ +Loading a schema with a schemanode referencing an incorrect menu placement now returns a proper HTTP 422 error