Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang

<!-- towncrier release notes start -->

## [1.4.1](https://github.com/opsmill/infrahub-sdk-python/tree/v1.3.0) - 2025-01-05

### Fixed

- Fixes an issue introduced in 1.4 that would prevent a node with relationship of cardinality one from being updated.

## [1.4.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.4.0) - 2025-01-03

### Changed
Expand Down
2 changes: 1 addition & 1 deletion infrahub_sdk/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ def _strip_unmodified_dict(data: dict, original_data: dict, variables: dict, ite
variables.pop(variable_key)

# TODO: I do not feel _great_ about this
if not data_item and data_item != []:
if not data_item and data_item != [] and item in data:
data.pop(item)

def _strip_unmodified(self, data: dict, variables: dict) -> tuple[dict, dict]:
Expand Down
12 changes: 12 additions & 0 deletions infrahub_sdk/testing/schemas/car_person.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@
await obj.save()
return obj

@pytest.fixture(scope="class")

Check warning on line 173 in infrahub_sdk/testing/schemas/car_person.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/testing/schemas/car_person.py#L173

Added line #L173 was not covered by tests
async def person_jane(self, client: InfrahubClient, person_jane_data: TestingPersonData) -> InfrahubNode:
obj = await client.create(**asdict(person_jane_data))
await obj.save()
return obj

Check warning on line 177 in infrahub_sdk/testing/schemas/car_person.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/testing/schemas/car_person.py#L175-L177

Added lines #L175 - L177 were not covered by tests

@pytest.fixture(scope="class")
async def manufacturer_mercedes(
self, client: InfrahubClient, manufacturer_mercedes_data: TestingManufacturerData
Expand Down Expand Up @@ -202,6 +208,12 @@
await obj.save()
return obj

@pytest.fixture(scope="class")

Check warning on line 211 in infrahub_sdk/testing/schemas/car_person.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/testing/schemas/car_person.py#L211

Added line #L211 was not covered by tests
async def tag_green(self, client: InfrahubClient) -> InfrahubNode:
obj = await client.create(kind=BUILTIN_TAG, name="Green")
await obj.save()
return obj

Check warning on line 215 in infrahub_sdk/testing/schemas/car_person.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/testing/schemas/car_person.py#L213-L215

Added lines #L213 - L215 were not covered by tests

async def create_persons(self, client: InfrahubClient, branch: str) -> list[InfrahubNode]:
john = await client.create(kind=TESTING_PERSON, name="John Doe", branch=branch)
await john.save()
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[project]
name = "infrahub-sdk"
version = "1.4.0"
version = "1.4.1"
requires-python = ">=3.9"

[tool.poetry]
name = "infrahub-sdk"
version = "1.4.0"
version = "1.4.1"
description = "Python Client to interact with Infrahub"
authors = ["OpsMill <info@opsmill.com>"]
readme = "README.md"
Expand Down
58 changes: 13 additions & 45 deletions tests/integration/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,48 +143,31 @@ async def test_node_update(
initial_schema: None,
manufacturer_mercedes,
person_joe,
person_jane,
car_golf,
tag_blue,
tag_red,
tag_green,
):
car_golf.color.value = "White"
await car_golf.tags.fetch()
car_golf.tags.add(tag_blue.id)
car_golf.tags.add(tag_red.id)
await car_golf.save()

node_after = await client.get(kind=TESTING_CAR, id=car_golf.id)
assert node_after.color.value == "White"
await node_after.tags.fetch()
assert len(node_after.tags.peers) == 2
car2 = await client.get(kind=TESTING_CAR, id=car_golf.id)
assert car2.color.value == "White"
await car2.tags.fetch()
assert len(car2.tags.peers) == 2

# async def test_node_update_2(
# self,
# db: InfrahubDatabase,
# client: InfrahubClient,
# init_db_base,
# load_builtin_schema,
# tag_green: Node,
# tag_red: Node,
# tag_blue: Node,
# gqlquery02: Node,
# repo99: Node,
# ):
# node = await client.get(kind="CoreGraphQLQuery", name__value="query02")
# assert node.id is not None
car2.owner = person_jane.id
car2.tags.add(tag_green.id)
car2.tags.remove(tag_red.id)
await car2.save()

# node.name.value = "query021"
# node.repository = repo99.id
# node.tags.add(tag_green.id)
# node.tags.remove(tag_red.id)
# await node.save()

# nodedb = await NodeManager.get_one(id=node.id, db=db, include_owner=True, include_source=True)
# repodb = await nodedb.repository.get_peer(db=db)
# assert repodb.id == repo99.id

# tags = await nodedb.tags.get(db=db)
# assert sorted([tag.peer_id for tag in tags]) == sorted([tag_green.id, tag_blue.id])
car3 = await client.get(kind=TESTING_CAR, id=car_golf.id)
await car3.tags.fetch()
assert sorted([tag.id for tag in car3.tags.peers]) == sorted([tag_green.id, tag_blue.id])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use sets for these instead of sorting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, not sure how i missed that, I'll fix in another PR


# async def test_node_update_3_idempotency(
# self,
Expand Down Expand Up @@ -222,21 +205,6 @@ async def test_node_update(
# assert "query" not in second_update["data"]["data"]
# assert not second_update["variables"]

# async def test_convert_node(
# self,
# db: InfrahubDatabase,
# client: InfrahubClient,
# location_schema,
# init_db_base,
# load_builtin_schema,
# location_cdg: Node,
# ):
# data = await location_cdg.to_graphql(db=db)
# node = InfrahubNode(client=client, schema=location_schema, data=data)

# # pylint: disable=no-member
# assert node.name.value == "cdg01"

# async def test_relationship_manager_errors_without_fetch(self, client: InfrahubClient, load_builtin_schema):
# organization = await client.create("TestOrganization", name="organization-1")
# await organization.save()
Expand Down
104 changes: 104 additions & 0 deletions tests/unit/sdk/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,47 @@ async def location_data02_no_pagination():

@pytest.fixture
async def location_data01():
data = {
"node": {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
"display_label": "dfw1",
"name": {
"value": "DFW",
},
"description": {
"value": None,
},
"type": {
"value": "SITE",
},
"primary_tag": {
"node": {
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
"display_label": "red",
"__typename": "BuiltinTag",
},
},
"tags": {
"count": 1,
"edges": [
{
"node": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"display_label": "blue",
"__typename": "BuiltinTag",
},
}
],
},
}
}

return data


@pytest.fixture
async def location_data01_property():
data = {
"node": {
"__typename": "BuiltinLocation",
Expand Down Expand Up @@ -438,6 +479,47 @@ async def location_data01():

@pytest.fixture
async def location_data02():
data = {
"node": {
"__typename": "BuiltinLocation",
"id": "llllllll-llll-llll-llll-llllllllllll",
"display_label": "dfw1",
"name": {
"value": "dfw1",
},
"description": {
"value": None,
},
"type": {
"value": "SITE",
},
"primary_tag": {
"node": {
"id": "rrrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr",
"display_label": "red",
"__typename": "BuiltinTag",
},
},
"tags": {
"count": 1,
"edges": [
{
"node": {
"id": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"display_label": "blue",
"__typename": "BuiltinTag",
},
}
],
},
}
}

return data


@pytest.fixture
async def location_data02_property():
data = {
"node": {
"__typename": "BuiltinLocation",
Expand Down Expand Up @@ -517,6 +599,28 @@ async def location_data02():
return data


@pytest.fixture
async def rfile_userdata01():
return {
"name": {"value": "rfile01"},
"template_path": {"value": "mytemplate.j2"},
"query": {"id": "qqqqqqqq"},
"repository": {"id": "rrrrrrrr"},
"tags": [{"id": "t1t1t1t1"}, "t2t2t2t2"],
}


@pytest.fixture
async def rfile_userdata01_property():
return {
"name": {"value": "rfile01", "is_protected": True, "source": "ffffffff"},
"template_path": {"value": "mytemplate.j2"},
"query": {"id": "qqqqqqqq", "source": "ffffffff", "owner": "ffffffff", "is_protected": True},
"repository": {"id": "rrrrrrrr", "source": "ffffffff", "owner": "ffffffff"},
"tags": [{"id": "t1t1t1t1"}, "t2t2t2t2"],
}


@pytest.fixture
async def tag_schema() -> NodeSchemaAPI:
data = {
Expand Down
Loading
Loading