Skip to content

Commit 7ba8326

Browse files
committed
Add tests
1 parent 81089af commit 7ba8326

File tree

7 files changed

+287
-0
lines changed

7 files changed

+287
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# yaml-language-server: $schema=https://schema.infrahub.app/python-sdk/repository-config/develop.json
2+
---
3+
python_transforms:
4+
- name: animal_person
5+
class_name: AnimalPerson
6+
file_path: "transforms/animal_person.py"
7+
convert_query_response: false
8+
- name: animal_person_converted
9+
class_name: ConvertedAnimalPerson
10+
file_path: "transforms/converted.py"
11+
convert_query_response: true
12+
13+
generator_definitions:
14+
- name: animal_tags
15+
file_path: "generators/tag_generator.py"
16+
targets: pet_owners
17+
query: animal_person
18+
convert_query_response: false
19+
parameters:
20+
name: "name__value"
21+
- name: animal_tags_convert
22+
file_path: "generators/tag_generator_convert.py"
23+
targets: pet_owners
24+
query: animal_person
25+
convert_query_response: true
26+
parameters:
27+
name: "name__value"
28+
29+
30+
queries:
31+
- name: animal_person
32+
file_path: queries/animal_person.gql
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from infrahub_sdk.generator import InfrahubGenerator
2+
3+
4+
class Generator(InfrahubGenerator):
5+
async def generate(self, data: dict) -> None:
6+
response_person = data["TestingPerson"]["edges"][0]["node"]
7+
name: str = response_person["name"]["value"]
8+
9+
for animal in data["TestingPerson"]["edges"][0]["node"]["animals"]["edges"]:
10+
payload = {
11+
"name": f"raw-{name.lower().replace(' ', '-')}-{animal['node']['name']['value'].lower()}",
12+
"description": "Without converting query response",
13+
}
14+
obj = await self.client.create(kind="BuiltinTag", data=payload)
15+
await obj.save(allow_upsert=True)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from infrahub_sdk.generator import InfrahubGenerator
2+
3+
4+
class Generator(InfrahubGenerator):
5+
async def generate(self, data: dict) -> None:
6+
response_person = data["TestingPerson"]["edges"][0]["node"]
7+
name: str = response_person["name"]["value"]
8+
person = self.store.get(key=name, kind="TestingPerson")
9+
10+
for animal in person.animals.peers:
11+
payload = {
12+
"name": f"converted-{name.lower().replace(' ', '-')}-{animal.peer.name.value.lower()}",
13+
"description": "Using convert_query_response",
14+
}
15+
obj = await self.client.create(kind="BuiltinTag", data=payload)
16+
await obj.save(allow_upsert=True)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
query TestPersonQuery($name: String!) {
2+
TestingPerson(name__value: $name) {
3+
edges {
4+
node {
5+
__typename
6+
id
7+
name {
8+
value
9+
}
10+
height {
11+
value
12+
}
13+
animals {
14+
edges {
15+
node {
16+
__typename
17+
id
18+
name {
19+
value
20+
}
21+
}
22+
}
23+
}
24+
}
25+
}
26+
}
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import Any
2+
3+
from infrahub_sdk.transforms import InfrahubTransform
4+
5+
6+
class AnimalPerson(InfrahubTransform):
7+
query = "animal_person"
8+
9+
async def transform(self, data) -> dict[str, Any]:
10+
response_person = data["TestingPerson"]["edges"][0]["node"]
11+
name: str = response_person["name"]["value"]
12+
animal_names = sorted(
13+
animal["node"]["name"]["value"] for animal in data["TestingPerson"]["edges"][0]["node"]["animals"]["edges"]
14+
)
15+
16+
return {"person": name, "pets": animal_names}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from operator import itemgetter
2+
from typing import Any
3+
4+
from infrahub_sdk.transforms import InfrahubTransform
5+
6+
7+
class ConvertedAnimalPerson(InfrahubTransform):
8+
query = "animal_person"
9+
10+
async def transform(self, data) -> dict[str, Any]:
11+
response_person = data["TestingPerson"]["edges"][0]["node"]
12+
name: str = response_person["name"]["value"]
13+
person = self.store.get(key=name, kind="TestingPerson")
14+
15+
animals = [{"type": animal.peer.typename, "name": animal.peer.name.value} for animal in person.animals.peers]
16+
animals.sort(key=itemgetter("name"))
17+
18+
return {"person": person.name.value, "herd_size": len(animals), "animals": animals}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
from __future__ import annotations
2+
3+
import json
4+
import os
5+
import shutil
6+
import tempfile
7+
from collections.abc import Generator
8+
from pathlib import Path
9+
from typing import TYPE_CHECKING
10+
11+
import pytest
12+
from typer.testing import CliRunner
13+
14+
from infrahub_sdk.ctl import config
15+
from infrahub_sdk.ctl.cli_commands import app, generator
16+
from infrahub_sdk.ctl.parameters import load_configuration
17+
from infrahub_sdk.repository import GitRepoManager
18+
from infrahub_sdk.testing.docker import TestInfrahubDockerClient
19+
from infrahub_sdk.testing.schemas.animal import SchemaAnimal
20+
from tests.helpers.utils import change_directory, strip_color
21+
22+
if TYPE_CHECKING:
23+
from infrahub_sdk import InfrahubClient
24+
25+
FIXTURE_BASE_DIR = Path(Path(os.path.abspath(__file__)).parent / ".." / "fixtures")
26+
27+
28+
runner = CliRunner()
29+
30+
31+
class TestInfrahubCtl(TestInfrahubDockerClient, SchemaAnimal):
32+
@pytest.fixture(scope="class")
33+
async def base_dataset(
34+
self,
35+
client: InfrahubClient,
36+
load_schema,
37+
person_liam,
38+
person_ethan,
39+
person_sophia,
40+
cat_luna,
41+
cat_bella,
42+
dog_daisy,
43+
dog_rocky,
44+
ctl_client_config,
45+
):
46+
await client.branch.create(branch_name="branch01")
47+
48+
@pytest.fixture(scope="class")
49+
def repository(self) -> Generator[str]:
50+
temp_dir = tempfile.mkdtemp()
51+
52+
try:
53+
fixture_path = Path(FIXTURE_BASE_DIR / "repos" / "ctl_integration")
54+
shutil.copytree(fixture_path, temp_dir, dirs_exist_ok=True)
55+
# Initialize fixture as git repository. This is necessary to run some infrahubctl commands.
56+
GitRepoManager(temp_dir)
57+
58+
yield temp_dir
59+
60+
finally:
61+
shutil.rmtree(temp_dir)
62+
63+
@pytest.fixture(scope="class")
64+
def ctl_client_config(self, client: InfrahubClient) -> Generator:
65+
load_configuration(value="infrahubctl.toml")
66+
assert config.SETTINGS._settings
67+
config.SETTINGS._settings.server_address = client.config.address
68+
original_username = os.environ.get("INFRAHUB_USERNAME")
69+
original_password = os.environ.get("INFRAHUB_PASSWORD")
70+
if client.config.username and client.config.password:
71+
os.environ["INFRAHUB_USERNAME"] = client.config.username
72+
os.environ["INFRAHUB_PASSWORD"] = client.config.password
73+
yield
74+
if original_username:
75+
os.environ["INFRAHUB_USERNAME"] = original_username
76+
if original_password:
77+
os.environ["INFRAHUB_PASSWORD"] = original_password
78+
79+
def test_infrahubctl_transform_cmd_animal_person(self, repository: str, base_dataset: None) -> None:
80+
"""Test infrahubctl transform without converting nodes."""
81+
82+
with change_directory(repository):
83+
ethans_output = runner.invoke(app, ["transform", "animal_person", "name=Ethan Carter"])
84+
structured_ethan_output = json.loads(strip_color(ethans_output.stdout))
85+
86+
liams_output = runner.invoke(app, ["transform", "animal_person", "name=Liam Walker"])
87+
structured_liam_output = json.loads(strip_color(liams_output.stdout))
88+
89+
assert structured_ethan_output == {"person": "Ethan Carter", "pets": ["Bella", "Daisy", "Luna"]}
90+
assert structured_liam_output == {"person": "Liam Walker", "pets": []}
91+
92+
def test_infrahubctl_transform_cmd_convert_animal_person(self, repository: str, base_dataset: None) -> None:
93+
"""Test infrahubctl transform when converting nodes."""
94+
95+
with change_directory(repository):
96+
ethans_output = runner.invoke(app, ["transform", "animal_person_converted", "name=Ethan Carter"])
97+
structured_ethan_output = json.loads(strip_color(ethans_output.stdout))
98+
99+
liams_output = runner.invoke(app, ["transform", "animal_person_converted", "name=Liam Walker"])
100+
structured_liam_output = json.loads(strip_color(liams_output.stdout))
101+
102+
assert structured_ethan_output == {
103+
"animals": [
104+
{"name": "Bella", "type": "TestingCat"},
105+
{"name": "Daisy", "type": "TestingDog"},
106+
{"name": "Luna", "type": "TestingCat"},
107+
],
108+
"herd_size": 3,
109+
"person": "Ethan Carter",
110+
}
111+
assert structured_liam_output == {
112+
"animals": [],
113+
"herd_size": 0,
114+
"person": "Liam Walker",
115+
}
116+
117+
async def test_infrahubctl_generator_cmd_animal_tags(
118+
self, repository: str, base_dataset: None, client: InfrahubClient
119+
) -> None:
120+
"""Test infrahubctl generator without converting nodes."""
121+
122+
expected_generated_tags = ["raw-ethan-carter-bella", "raw-ethan-carter-daisy", "raw-ethan-carter-luna"]
123+
initial_tags = await client.all(kind="BuiltinTag")
124+
125+
with change_directory(repository):
126+
await generator(
127+
generator_name="animal_tags", variables=["name=Ethan Carter"], list_available=False, path="."
128+
)
129+
130+
final_tags = await client.all(kind="BuiltinTag")
131+
132+
initial_tag_names = [tag.name.value for tag in initial_tags]
133+
final_tag_names = [tag.name.value for tag in final_tags]
134+
135+
for tag in expected_generated_tags:
136+
assert tag not in initial_tag_names
137+
assert tag in final_tag_names
138+
139+
async def test_infrahubctl_generator_cmd_animal_tags_convert_query(
140+
self, repository: str, base_dataset: None, client: InfrahubClient
141+
) -> None:
142+
"""Test infrahubctl generator with conversion of nodes."""
143+
144+
expected_generated_tags = [
145+
"converted-ethan-carter-bella",
146+
"converted-ethan-carter-daisy",
147+
"converted-ethan-carter-luna",
148+
]
149+
initial_tags = await client.all(kind="BuiltinTag")
150+
151+
with change_directory(repository):
152+
await generator(
153+
generator_name="animal_tags_convert", variables=["name=Ethan Carter"], list_available=False, path="."
154+
)
155+
156+
final_tags = await client.all(kind="BuiltinTag")
157+
158+
initial_tag_names = [tag.name.value for tag in initial_tags]
159+
final_tag_names = [tag.name.value for tag in final_tags]
160+
161+
for tag in expected_generated_tags:
162+
assert tag not in initial_tag_names
163+
assert tag in final_tag_names

0 commit comments

Comments
 (0)