Skip to content

Commit 9fa5ac8

Browse files
Merge pull request #140 from JohnsonChin1009/test/acpClient
test: added unit and integration testing for client.py
2 parents d7ac87f + 3003f34 commit 9fa5ac8

2 files changed

Lines changed: 1459 additions & 0 deletions

File tree

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import pytest
2+
import os
3+
from virtuals_acp.client import VirtualsACP
4+
from virtuals_acp.contract_clients.contract_client_v2 import ACPContractClientV2
5+
from virtuals_acp.configs.configs import BASE_MAINNET_CONFIG_V2
6+
from virtuals_acp.models import ACPAgentSort
7+
8+
9+
@pytest.mark.integration
10+
class TestClientIntegration:
11+
@pytest.fixture(scope="class")
12+
def acp_client(self):
13+
"""Create a real VirtualsACP client for integration testing"""
14+
wallet_private_key = os.getenv("WHITELISTED_WALLET_PRIVATE_KEY")
15+
agent_wallet_address = os.getenv("SELLER_AGENT_WALLET_ADDRESS")
16+
entity_id_str = os.getenv("SELLER_ENTITY_ID")
17+
18+
if not all([wallet_private_key, agent_wallet_address, entity_id_str]):
19+
pytest.skip("Integration test environment variables not set")
20+
21+
entity_id = int(entity_id_str)
22+
23+
contract_client = ACPContractClientV2(
24+
agent_wallet_address=agent_wallet_address,
25+
wallet_private_key=wallet_private_key,
26+
entity_id=entity_id,
27+
config=BASE_MAINNET_CONFIG_V2,
28+
)
29+
30+
client = VirtualsACP(acp_contract_clients=contract_client)
31+
yield client
32+
33+
if hasattr(client, 'sio') and client.sio:
34+
client.sio.disconnect()
35+
36+
class TestBrowseAgents:
37+
"""Integration tests for browse_agents method"""
38+
39+
def test_should_browse_agents_with_keyword(self, acp_client):
40+
"""Should successfully browse agents with keyword search"""
41+
agents = acp_client.browse_agents(keyword="Trading Agent", top_k=5)
42+
43+
# Verify we got results
44+
assert isinstance(agents, list)
45+
assert len(agents) >= 0
46+
47+
# If we got agents, verify their structure
48+
if len(agents) > 0:
49+
agent = agents[0]
50+
assert hasattr(agent, 'id')
51+
assert hasattr(agent, 'wallet_address')
52+
assert hasattr(agent, 'job_offerings')
53+
54+
def test_should_filter_out_self(self, acp_client):
55+
"""Should exclude self from agent search results"""
56+
agents = acp_client.browse_agents(
57+
keyword="Trading Agent", top_k=10)
58+
59+
# Verify none of the agents are the client itself
60+
for agent in agents:
61+
assert agent.wallet_address.lower() != acp_client.agent_address.lower()
62+
63+
def test_should_respect_top_k_parameter(self, acp_client):
64+
"""Should respect the top_k parameter for result limiting"""
65+
top_k = 3
66+
agents = acp_client.browse_agents(keyword="", top_k=top_k)
67+
68+
# Result count should be <= top_k
69+
assert len(agents) <= top_k
70+
71+
def test_should_handle_sort_by_parameter(self, acp_client):
72+
"""Should handle sort_by parameter without errors"""
73+
# This should not raise an error
74+
agents = acp_client.browse_agents(
75+
keyword="",
76+
sort_by=[ACPAgentSort.SUCCESSFUL_JOB_COUNT],
77+
top_k=5
78+
)
79+
80+
assert isinstance(agents, list)
81+
82+
def test_should_search_with_keyword(self, acp_client):
83+
"""Should search agents with specific keyword"""
84+
# Search for something generic
85+
agents = acp_client.browse_agents(keyword="ai", top_k=5)
86+
87+
assert isinstance(agents, list)
88+
# Even if no results, should return empty list, not error
89+
90+
class TestGetAgent:
91+
"""Integration tests for get_agent method"""
92+
93+
def test_should_get_own_agent_info(self, acp_client):
94+
"""Should successfully retrieve own agent information"""
95+
agent = acp_client.get_agent(acp_client.agent_address)
96+
97+
# Should return the agent or None
98+
# If the agent exists
99+
if agent:
100+
assert agent.wallet_address.lower() == acp_client.agent_address.lower()
101+
assert hasattr(agent, 'id')
102+
assert hasattr(agent, 'job_offerings')
103+
assert hasattr(agent, 'name')
104+
105+
def test_should_return_none_for_nonexistent_agent(self, acp_client):
106+
"""Should return None for non-existent agent"""
107+
# Use a random address that likely doesn't exist
108+
fake_address = "0x0000000000000000000000000000000000000001"
109+
agent = acp_client.get_agent(fake_address)
110+
111+
assert agent is None
112+
113+
def test_should_handle_valid_agent_address(self, acp_client):
114+
"""Should handle valid agent address without errors"""
115+
# First browse to find a real agent
116+
agents = acp_client.browse_agents(keyword="", top_k=1)
117+
118+
if len(agents) > 0:
119+
# Get the first agent's details
120+
agent_address = agents[0].wallet_address
121+
agent = acp_client.get_agent(agent_address)
122+
123+
# Should return agent info or None
124+
if agent:
125+
assert agent.wallet_address.lower() == agent_address.lower()
126+
127+
class TestJobFetching:
128+
"""Integration tests for job fetching methods"""
129+
130+
def test_should_fetch_active_jobs(self, acp_client):
131+
"""Should successfully fetch active jobs"""
132+
jobs = acp_client.get_active_jobs(page=1, page_size=5)
133+
134+
assert isinstance(jobs, list)
135+
# Should return a list (could be empty)
136+
137+
def test_should_fetch_pending_memo_jobs(self, acp_client):
138+
"""Should successfully fetch pending memo jobs"""
139+
jobs = acp_client.get_pending_memo_jobs(page=1, page_size=5)
140+
141+
assert isinstance(jobs, list)
142+
143+
def test_should_fetch_completed_jobs(self, acp_client):
144+
"""Should successfully fetch completed jobs"""
145+
jobs = acp_client.get_completed_jobs(page=1, page_size=5)
146+
147+
assert isinstance(jobs, list)
148+
149+
def test_should_fetch_cancelled_jobs(self, acp_client):
150+
"""Should successfully fetch cancelled jobs"""
151+
jobs = acp_client.get_cancelled_jobs(page=1, page_size=5)
152+
153+
assert isinstance(jobs, list)
154+
155+
class TestAccountMethods:
156+
"""Integration tests for account-related methods"""
157+
158+
def test_get_by_client_and_provider_should_handle_no_account(self, acp_client):
159+
"""Should handle case when no account exists between client and provider"""
160+
# Use a random provider address that likely doesn't have an account
161+
fake_provider = "0x0000000000000000000000000000000000000001"
162+
163+
account = acp_client.get_by_client_and_provider(
164+
acp_client.agent_address,
165+
fake_provider
166+
)
167+
168+
# Should return None for non-existent account
169+
assert account is None

0 commit comments

Comments
 (0)