Skip to content

Commit 650a2c6

Browse files
committed
Forbid converting objects with profiles
1 parent e1bb469 commit 650a2c6

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

backend/infrahub/graphql/mutations/convert_object_type.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
from infrahub.core.convert_object_type.repository_conversion import convert_repository_type
1111
from infrahub.core.convert_object_type.schema_mapping import get_schema_mapping
1212
from infrahub.core.manager import NodeManager
13+
from infrahub.exceptions import ValidationError
1314
from infrahub.repositories.create_repository import RepositoryFinalizer
1415

1516
if TYPE_CHECKING:
17+
from infrahub.core.attribute import BaseAttribute
1618
from infrahub.graphql.initialization import GraphqlContext
1719

1820

@@ -49,14 +51,22 @@ async def mutate(
4951

5052
fields_mapping: dict[str, ConversionFieldInput] = {}
5153
if not isinstance(data.fields_mapping, dict):
52-
raise ValueError(f"Expected `fields_mapping` to be a `dict`, got {type(data.fields_mapping)}")
54+
raise ValidationError(
55+
input_value=f"Expected `fields_mapping` to be a `dict`, got {type(data.fields_mapping)}"
56+
)
5357

5458
for field_name, input_for_dest_field_str in data.fields_mapping.items():
5559
fields_mapping[field_name] = ConversionFieldInput(**input_for_dest_field_str)
5660

5761
node_to_convert = await NodeManager.get_one(
5862
id=str(data.node_id), db=graphql_context.db, branch=graphql_context.branch
5963
)
64+
for attribute_name in source_schema.attribute_names:
65+
attribute: BaseAttribute = getattr(node_to_convert, attribute_name)
66+
if attribute.is_from_profile:
67+
raise ValidationError(
68+
input_value=f"The attribute '{attribute_name}' is from a profile, converting objects that use profiles is not yet supported."
69+
)
6070

6171
# Complete fields mapping with auto-mapping.
6272
mapping = get_schema_mapping(source_schema=source_schema, target_schema=target_schema)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING, Any
4+
5+
from infrahub_sdk.convert_object_type import ConversionFieldInput, ConversionFieldValue
6+
7+
from infrahub.core.node import Node
8+
from infrahub.core.registry import registry
9+
from infrahub.core.schema import SchemaRoot
10+
from infrahub.graphql.initialization import prepare_graphql_params
11+
from tests.helpers.graphql import graphql
12+
13+
if TYPE_CHECKING:
14+
from infrahub.core.branch import Branch
15+
from infrahub.database import InfrahubDatabase
16+
17+
18+
async def test_convert_object_type_with_profile_error(
19+
db: InfrahubDatabase, schemas_conversion: dict[str, Any], default_branch: Branch
20+
) -> None:
21+
"""Test that converting an object type with a profile returns the appropriate error message."""
22+
23+
schema = SchemaRoot(**schemas_conversion)
24+
registry.schema.register_schema(schema=schema, branch=default_branch.name)
25+
26+
person1_profile = await Node.init(db=db, schema="ProfileTestconvPerson1")
27+
await person1_profile.new(db=db, profile_name="person1-profile", profile_priority=10, height=175)
28+
await person1_profile.save(db=db)
29+
30+
default_branch.update_schema_hash()
31+
gql_params = await prepare_graphql_params(db=db, branch=default_branch)
32+
33+
create_person_mutation = f"""
34+
mutation {{
35+
TestconvPerson1Create(data: {{
36+
name: {{value: "John"}},
37+
profiles: [{{id: "{person1_profile.id}"}}]
38+
}}) {{
39+
ok
40+
object {{
41+
id
42+
}}
43+
}}
44+
}}
45+
"""
46+
47+
create_result = await graphql(
48+
schema=gql_params.schema,
49+
source=create_person_mutation,
50+
context_value=gql_params.context,
51+
root_value=None,
52+
variable_values={},
53+
)
54+
55+
assert create_result.errors is None
56+
assert create_result.data
57+
assert create_result.data["TestconvPerson1Create"]["ok"] is True
58+
person1_node_id = create_result.data["TestconvPerson1Create"]["object"]["id"]
59+
60+
mapping = {
61+
"name": ConversionFieldInput(source_field="name"),
62+
"age": ConversionFieldInput(data=ConversionFieldValue(attribute_value=30)),
63+
}
64+
mapping_dict = {field_name: model.model_dump(mode="json") for field_name, model in mapping.items()}
65+
66+
result = await graphql(
67+
schema=gql_params.schema,
68+
source=CONVERT_OBJECT_TYPE_MUTATION,
69+
context_value=gql_params.context,
70+
root_value=None,
71+
variable_values={
72+
"node_id": person1_node_id,
73+
"target_kind": "TestconvPerson2",
74+
"fields_mapping": mapping_dict,
75+
},
76+
)
77+
78+
assert result.errors
79+
assert (
80+
"The attribute 'height' is from a profile, converting objects that use profiles is not yet supported."
81+
in str(result.errors)
82+
)
83+
84+
85+
CONVERT_OBJECT_TYPE_MUTATION = """
86+
mutation ConvertObjectType(
87+
$node_id: String!
88+
$target_kind: String!
89+
$fields_mapping: GenericScalar!
90+
) {
91+
ConvertObjectType(data: {
92+
node_id: $node_id,
93+
target_kind: $target_kind,
94+
fields_mapping: $fields_mapping
95+
}) {
96+
ok
97+
node
98+
}
99+
}
100+
"""

0 commit comments

Comments
 (0)