Skip to content

Commit 7a75390

Browse files
committed
test: add unit and integration tests for Agentic type hierarchy
- 40 unit tests covering Agentic, Skill, SkillArtifact, ContextRepository, and ContextArtifact models - Tests validate creators, NanoID QN generation, type hierarchy, getter/setter round-trips, enum variants, parent ref population - Integration tests cover CRUD, retrieve, certificate update, delete+restore for all 4 concrete types
1 parent 373ed60 commit 7a75390

6 files changed

Lines changed: 639 additions & 0 deletions

File tree

tests/integration/agentic_test.py

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
from typing import Generator
2+
3+
import pytest
4+
5+
from pyatlan.client.atlan import AtlanClient
6+
from pyatlan.model.assets import (
7+
ContextArtifact,
8+
ContextRepository,
9+
Skill,
10+
SkillArtifact,
11+
)
12+
from pyatlan.model.enums import (
13+
CertificateStatus,
14+
ContextLifecycleStatus,
15+
EntityStatus,
16+
FileType,
17+
)
18+
from tests.integration.client import TestId, delete_asset
19+
20+
MODULE_NAME = TestId.make_unique("AGENTIC")
21+
22+
SKILL_NAME = f"{MODULE_NAME}-skill"
23+
SKILL_ARTIFACT_NAME = f"{MODULE_NAME}-skill-artifact"
24+
CONTEXT_REPO_NAME = f"{MODULE_NAME}-context-repo"
25+
CONTEXT_ARTIFACT_NAME = f"{MODULE_NAME}-context-artifact"
26+
27+
CERTIFICATE_STATUS = CertificateStatus.VERIFIED
28+
CERTIFICATE_MESSAGE = "Automated testing of the Python SDK."
29+
30+
31+
# ── Skill fixtures ──────────────────────────────────────────────────────────
32+
33+
34+
@pytest.fixture(scope="module")
35+
def skill(client: AtlanClient) -> Generator[Skill, None, None]:
36+
to_create = Skill.creator(name=SKILL_NAME)
37+
response = client.asset.save(to_create)
38+
result = response.assets_created(asset_type=Skill)[0]
39+
yield result
40+
delete_asset(client, guid=result.guid, asset_type=Skill)
41+
42+
43+
@pytest.fixture(scope="module")
44+
def skill_artifact(
45+
client: AtlanClient, skill: Skill
46+
) -> Generator[SkillArtifact, None, None]:
47+
assert skill.qualified_name
48+
to_create = SkillArtifact.creator(
49+
name=SKILL_ARTIFACT_NAME,
50+
skill_qualified_name=skill.qualified_name,
51+
file_type=FileType.TXT,
52+
)
53+
response = client.asset.save(to_create)
54+
result = response.assets_created(asset_type=SkillArtifact)[0]
55+
yield result
56+
delete_asset(client, guid=result.guid, asset_type=SkillArtifact)
57+
58+
59+
# ── Context fixtures ────────────────────────────────────────────────────────
60+
61+
62+
@pytest.fixture(scope="module")
63+
def context_repository(
64+
client: AtlanClient,
65+
) -> Generator[ContextRepository, None, None]:
66+
to_create = ContextRepository.creator(name=CONTEXT_REPO_NAME)
67+
response = client.asset.save(to_create)
68+
result = response.assets_created(asset_type=ContextRepository)[0]
69+
yield result
70+
delete_asset(client, guid=result.guid, asset_type=ContextRepository)
71+
72+
73+
@pytest.fixture(scope="module")
74+
def context_artifact(
75+
client: AtlanClient, context_repository: ContextRepository
76+
) -> Generator[ContextArtifact, None, None]:
77+
assert context_repository.qualified_name
78+
to_create = ContextArtifact.creator(
79+
name=CONTEXT_ARTIFACT_NAME,
80+
context_repository_qualified_name=context_repository.qualified_name,
81+
file_type=FileType.TXT,
82+
)
83+
response = client.asset.save(to_create)
84+
result = response.assets_created(asset_type=ContextArtifact)[0]
85+
yield result
86+
delete_asset(client, guid=result.guid, asset_type=ContextArtifact)
87+
88+
89+
# ── Skill tests ─────────────────────────────────────────────────────────────
90+
91+
92+
def test_skill(client: AtlanClient, skill: Skill):
93+
assert skill
94+
assert skill.guid
95+
assert skill.qualified_name
96+
assert skill.name == SKILL_NAME
97+
98+
99+
def test_skill_artifact(
100+
client: AtlanClient, skill: Skill, skill_artifact: SkillArtifact
101+
):
102+
assert skill_artifact
103+
assert skill_artifact.guid
104+
assert skill_artifact.qualified_name
105+
assert skill_artifact.name == SKILL_ARTIFACT_NAME
106+
107+
108+
@pytest.mark.order(after="test_skill_artifact")
109+
def test_retrieve_skill(client: AtlanClient, skill: Skill):
110+
retrieved = client.asset.get_by_guid(
111+
skill.guid, asset_type=Skill, ignore_relationships=False
112+
)
113+
assert retrieved
114+
assert retrieved.guid == skill.guid
115+
assert retrieved.qualified_name == skill.qualified_name
116+
assert retrieved.name == SKILL_NAME
117+
118+
119+
@pytest.mark.order(after="test_skill_artifact")
120+
def test_update_skill_certificate(client: AtlanClient, skill: Skill):
121+
assert skill.name
122+
assert skill.qualified_name
123+
updated = client.asset.update_certificate(
124+
name=skill.name,
125+
asset_type=Skill,
126+
qualified_name=skill.qualified_name,
127+
message=CERTIFICATE_MESSAGE,
128+
certificate_status=CERTIFICATE_STATUS,
129+
)
130+
assert updated
131+
assert updated.certificate_status == CERTIFICATE_STATUS
132+
133+
134+
# ── Context tests ───────────────────────────────────────────────────────────
135+
136+
137+
def test_context_repository(
138+
client: AtlanClient, context_repository: ContextRepository
139+
):
140+
assert context_repository
141+
assert context_repository.guid
142+
assert context_repository.qualified_name
143+
assert context_repository.name == CONTEXT_REPO_NAME
144+
145+
146+
def test_context_artifact(
147+
client: AtlanClient,
148+
context_repository: ContextRepository,
149+
context_artifact: ContextArtifact,
150+
):
151+
assert context_artifact
152+
assert context_artifact.guid
153+
assert context_artifact.qualified_name
154+
assert context_artifact.name == CONTEXT_ARTIFACT_NAME
155+
156+
157+
@pytest.mark.order(after="test_context_artifact")
158+
def test_retrieve_context_repository(
159+
client: AtlanClient, context_repository: ContextRepository
160+
):
161+
retrieved = client.asset.get_by_guid(
162+
context_repository.guid,
163+
asset_type=ContextRepository,
164+
ignore_relationships=False,
165+
)
166+
assert retrieved
167+
assert retrieved.guid == context_repository.guid
168+
assert retrieved.qualified_name == context_repository.qualified_name
169+
assert retrieved.name == CONTEXT_REPO_NAME
170+
171+
172+
@pytest.mark.order(after="test_context_artifact")
173+
def test_delete_context_artifact(
174+
client: AtlanClient, context_artifact: ContextArtifact
175+
):
176+
response = client.asset.delete_by_guid(context_artifact.guid)
177+
assert response
178+
deleted = response.assets_deleted(asset_type=ContextArtifact)
179+
assert deleted
180+
assert len(deleted) == 1
181+
assert deleted[0].guid == context_artifact.guid
182+
assert deleted[0].status == EntityStatus.DELETED
183+
184+
185+
@pytest.mark.order(after="test_delete_context_artifact")
186+
def test_restore_context_artifact(
187+
client: AtlanClient, context_artifact: ContextArtifact
188+
):
189+
assert context_artifact.qualified_name
190+
assert client.asset.restore(
191+
asset_type=ContextArtifact,
192+
qualified_name=context_artifact.qualified_name,
193+
)
194+
restored = client.asset.get_by_qualified_name(
195+
asset_type=ContextArtifact,
196+
qualified_name=context_artifact.qualified_name,
197+
)
198+
assert restored
199+
assert restored.guid == context_artifact.guid
200+
assert restored.status == EntityStatus.ACTIVE

tests/unit/model/agentic_test.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import pytest
2+
3+
from pyatlan.model.assets import (
4+
Agentic,
5+
Artifact,
6+
Context,
7+
ContextArtifact,
8+
ContextRepository,
9+
Skill,
10+
SkillArtifact,
11+
)
12+
13+
14+
def test_agentic_type_name():
15+
sut = Agentic()
16+
assert sut.type_name == "Agentic"
17+
18+
19+
def test_agentic_type_name_is_immutable():
20+
sut = Agentic()
21+
with pytest.raises(TypeError):
22+
sut.type_name = "NotAgentic"
23+
24+
25+
def test_type_hierarchy():
26+
"""Verify MRO: concrete types extend through Agentic → Catalog."""
27+
assert issubclass(Skill, Agentic)
28+
assert issubclass(SkillArtifact, Artifact)
29+
assert issubclass(Artifact, Agentic)
30+
assert issubclass(ContextRepository, Context)
31+
assert issubclass(ContextArtifact, Context)
32+
assert issubclass(Context, Agentic)
33+
34+
35+
def test_isinstance_checks():
36+
"""Creator instances are recognizable as their parent types."""
37+
skill = Skill.creator(name="test-skill")
38+
assert isinstance(skill, Skill)
39+
assert isinstance(skill, Agentic)
40+
41+
repo = ContextRepository.creator(name="test-repo")
42+
assert isinstance(repo, ContextRepository)
43+
assert isinstance(repo, Context)
44+
assert isinstance(repo, Agentic)

0 commit comments

Comments
 (0)