Skip to content

Commit 62dabad

Browse files
authored
re-allow using RelatedNode as input to cardinality=one rel (#453)
* re-allow using RelatedNode as input to cardinality=one rel * add test * test update, changelog * don't reuse RelatedNode from other Node * typing fix * update InfrahubNodeSync too, add unit test * one more unit test so codecov won't make me feel bad
1 parent 9a5b3ae commit 62dabad

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

changelog/452.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Re-enable specifying a cardinality-one relationship using a RelatedNode when creating an InfrahubNode

infrahub_sdk/node/node.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,11 +501,21 @@ async def from_graphql(
501501

502502
return cls(client=client, schema=schema, branch=branch, data=cls._strip_alias(data))
503503

504-
def _init_relationships(self, data: dict | None = None) -> None:
504+
def _init_relationships(self, data: dict | RelatedNode | None = None) -> None:
505505
for rel_schema in self._schema.relationships:
506506
rel_data = data.get(rel_schema.name, None) if isinstance(data, dict) else None
507507

508508
if rel_schema.cardinality == "one":
509+
if isinstance(rel_data, RelatedNode):
510+
peer_id_data: dict[str, Any] = {}
511+
if rel_data.id:
512+
peer_id_data["id"] = rel_data.id
513+
if rel_data.hfid:
514+
peer_id_data["hfid"] = rel_data.hfid
515+
if peer_id_data:
516+
rel_data = peer_id_data
517+
else:
518+
rel_data = None
509519
self._relationship_cardinality_one_data[rel_schema.name] = RelatedNode(
510520
name=rel_schema.name, branch=self._branch, client=self._client, schema=rel_schema, data=rel_data
511521
)
@@ -1079,10 +1089,19 @@ def _init_relationships(self, data: dict | None = None) -> None:
10791089
rel_data = data.get(rel_schema.name, None) if isinstance(data, dict) else None
10801090

10811091
if rel_schema.cardinality == "one":
1092+
if isinstance(rel_data, RelatedNodeSync):
1093+
peer_id_data: dict[str, Any] = {}
1094+
if rel_data.id:
1095+
peer_id_data["id"] = rel_data.id
1096+
if rel_data.hfid:
1097+
peer_id_data["hfid"] = rel_data.hfid
1098+
if peer_id_data:
1099+
rel_data = peer_id_data
1100+
else:
1101+
rel_data = None
10821102
self._relationship_cardinality_one_data[rel_schema.name] = RelatedNodeSync(
10831103
name=rel_schema.name, branch=self._branch, client=self._client, schema=rel_schema, data=rel_data
10841104
)
1085-
10861105
else:
10871106
self._relationship_cardinality_many_data[rel_schema.name] = RelationshipManagerSync(
10881107
name=rel_schema.name,

tests/integration/test_node.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ async def test_node_create_with_relationships(
6363
assert node_after.name.value == node.name.value
6464
assert node_after.manufacturer.peer.id == manufacturer_mercedes.id
6565

66+
async def test_node_create_with_relationships_using_related_node(
67+
self,
68+
default_branch: str,
69+
client: InfrahubClient,
70+
initial_schema: None,
71+
manufacturer_mercedes,
72+
car_golf,
73+
person_joe,
74+
):
75+
related_node = car_golf.owner
76+
node = await client.create(
77+
kind=TESTING_CAR, name="Tiguan", color="Black", manufacturer=manufacturer_mercedes, owner=related_node
78+
)
79+
await node.save(allow_upsert=True)
80+
assert node.id is not None
81+
82+
node_after = await client.get(kind=TESTING_CAR, id=node.id, prefetch_relationships=True)
83+
assert node_after.name.value == node.name.value
84+
assert node_after.manufacturer.peer.id == manufacturer_mercedes.id
85+
assert node_after.owner.peer.id == person_joe.id
86+
6687
async def test_node_update_with_original_data(
6788
self,
6889
default_branch: str,

tests/unit/sdk/test_node.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
parse_human_friendly_id,
1616
)
1717
from infrahub_sdk.node.constants import SAFE_VALUE
18+
from infrahub_sdk.node.related_node import RelatedNode, RelatedNodeSync
1819
from infrahub_sdk.schema import GenericSchema, NodeSchemaAPI
1920

2021
if TYPE_CHECKING:
@@ -194,6 +195,50 @@ async def test_init_node_data_user_with_relationships(client, location_schema: N
194195
assert "get_kind" in keys
195196

196197

198+
@pytest.mark.parametrize("client_type", client_types)
199+
@pytest.mark.parametrize("rel_data", [{"id": "pppppppp"}, {"hfid": ["pppp", "pppp"]}])
200+
async def test_init_node_data_user_with_relationships_using_related_node(
201+
client, location_schema: NodeSchemaAPI, client_type, rel_data
202+
):
203+
rel_schema = location_schema.get_relationship(name="primary_tag")
204+
if client_type == "standard":
205+
primary_tag = RelatedNode(name="primary_tag", branch="main", client=client, schema=rel_schema, data=rel_data)
206+
else:
207+
primary_tag = RelatedNodeSync(
208+
name="primary_tag", branch="main", client=client, schema=rel_schema, data=rel_data
209+
)
210+
211+
data = {
212+
"name": {"value": "JFK1"},
213+
"description": {"value": "JFK Airport"},
214+
"type": {"value": "SITE"},
215+
"primary_tag": primary_tag,
216+
"tags": [{"id": "aaaaaa"}, {"id": "bbbb"}],
217+
}
218+
if client_type == "standard":
219+
node = InfrahubNode(client=client, schema=location_schema, data=data)
220+
else:
221+
node = InfrahubNodeSync(client=client, schema=location_schema, data=data)
222+
223+
assert node.name.value == "JFK1"
224+
assert node.name.is_protected is None
225+
assert node.description.value == "JFK Airport"
226+
assert node.type.value == "SITE"
227+
228+
assert isinstance(node.tags, RelationshipManagerBase)
229+
assert len(node.tags.peers) == 2
230+
assert isinstance(node.tags.peers[0], RelatedNodeBase)
231+
assert isinstance(node.primary_tag, RelatedNodeBase)
232+
assert node.primary_tag.id == rel_data.get("id")
233+
assert node.primary_tag.hfid == rel_data.get("hfid")
234+
235+
keys = dir(node)
236+
assert "name" in keys
237+
assert "type" in keys
238+
assert "tags" in keys
239+
assert "get_kind" in keys
240+
241+
197242
@pytest.mark.parametrize("property_test", property_tests)
198243
@pytest.mark.parametrize("client_type", client_types)
199244
async def test_init_node_data_graphql(

0 commit comments

Comments
 (0)