-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathacpClient.integration.test.ts
More file actions
284 lines (229 loc) · 8.53 KB
/
acpClient.integration.test.ts
File metadata and controls
284 lines (229 loc) · 8.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
import { Address } from "viem";
import AcpClient from "../../src/acpClient";
import AcpContractClientV2 from "../../src/contractClients/acpContractClientV2";
import {
AcpAgentSort,
AcpGraduationStatus,
AcpOnlineStatus,
} from "../../src/interfaces";
import AcpJobOffering from "../../src/acpJobOffering";
import AcpJob from "../../src/acpJob";
import {
WHITELISTED_WALLET_PRIVATE_KEY,
BUYER_ENTITY_ID,
BUYER_AGENT_WALLET_ADDRESS,
} from "../env";
import { testBaseAcpConfigV2 } from "../testConfigs";
describe("AcpClient Integration Testing", () => {
let acpClient: AcpClient;
let contractClient: AcpContractClientV2;
beforeAll(async () => {
contractClient = await AcpContractClientV2.build(
WHITELISTED_WALLET_PRIVATE_KEY as Address,
BUYER_ENTITY_ID,
BUYER_AGENT_WALLET_ADDRESS as Address,
testBaseAcpConfigV2,
);
acpClient = new AcpClient({ acpContractClient: contractClient });
}, 45000);
describe("Initialization (init)", () => {
it("should initialize client successfully", () => {
expect(acpClient).toBeDefined();
expect(acpClient).toBeInstanceOf(AcpClient);
});
it("should have correct wallet address", () => {
expect(acpClient.walletAddress).toBe(BUYER_AGENT_WALLET_ADDRESS);
});
it("should have valid acpUrl", () => {
expect(acpClient.acpUrl).toBeDefined();
expect(acpClient.acpUrl).toBe("https://acpx.virtuals.io");
});
it("should have contract client initialized", () => {
expect(acpClient.acpContractClient).toBeDefined();
expect(acpClient.acpContractClient).toBe(contractClient);
});
it("should establish socket connection on initialization", (done) => {
// The socket connection is established in the constructor via init()
// If we reach this point without errors, the connection was successful
expect(acpClient).toBeDefined();
// Give socket time to connect
setTimeout(() => {
// If no connection errors thrown, test passes
done();
}, 2000);
}, 10000);
it("should handle onNewTask callback when provided", (done) => {
const onNewTaskMock = jest.fn((job: AcpJob) => {
expect(job).toBeInstanceOf(AcpJob);
done();
});
// Create a new client with callback
const clientWithCallback = new AcpClient({
acpContractClient: contractClient,
onNewTask: onNewTaskMock,
});
expect(clientWithCallback).toBeDefined();
// Note: This test will pass even if event doesn't fire
// Real socket event testing would require triggering an actual job
setTimeout(() => {
if (onNewTaskMock.mock.calls.length === 0) {
// No event fired, but that's expected in test environment
done();
}
}, 5000);
}, 10000);
it("should handle onEvaluate callback when provided", (done) => {
const onEvaluateMock = jest.fn((job: AcpJob) => {
expect(job).toBeInstanceOf(AcpJob);
done();
});
const clientWithCallback = new AcpClient({
acpContractClient: contractClient,
onEvaluate: onEvaluateMock,
});
expect(clientWithCallback).toBeDefined();
setTimeout(() => {
if (onEvaluateMock.mock.calls.length === 0) {
done();
}
}, 5000);
}, 10000);
});
describe("Agent Browsing (browseAgents)", () => {
it("should browse agents with keyword", async () => {
const keyword = "trading";
const options = {
topK: 5,
};
const result = await acpClient.browseAgents(keyword, options);
expect(Array.isArray(result)).toBe(true);
console.log(`Found ${result.length} agents for keyword: ${keyword}`);
}, 30000);
it("should return agents with correct structure", async () => {
const keyword = "agent";
const options = {
topK: 3,
};
const result = await acpClient.browseAgents(keyword, options);
if (result.length > 0) {
const firstAgent = result[0];
expect(firstAgent).toHaveProperty("id");
expect(firstAgent).toHaveProperty("name");
expect(firstAgent).toHaveProperty("description");
expect(firstAgent).toHaveProperty("walletAddress");
expect(firstAgent).toHaveProperty("contractAddress");
expect(firstAgent).toHaveProperty("jobOfferings");
expect(firstAgent).toHaveProperty("twitterHandle");
expect(typeof firstAgent.id).toBe("string");
expect(typeof firstAgent.name).toBe("string");
expect(typeof firstAgent.walletAddress).toBe("string");
expect(Array.isArray(firstAgent.jobOfferings)).toBe(true);
console.log("First agent:", {
id: firstAgent.id,
name: firstAgent.name,
jobCount: firstAgent.jobOfferings.length,
});
}
}, 30000);
it("should return job offerings as AcpJobOffering instances", async () => {
const keyword = "agent";
const options = {
topK: 5,
};
const result = await acpClient.browseAgents(keyword, options);
const agentWithJobs = result.find(
(agent) => agent.jobOfferings.length > 0,
);
if (agentWithJobs) {
const jobOffering = agentWithJobs.jobOfferings[0];
expect(jobOffering).toBeInstanceOf(AcpJobOffering);
expect(typeof jobOffering.initiateJob).toBe("function");
console.log("Job offering:", {
name: jobOffering.name,
price: jobOffering.price,
});
} else {
console.log("No agents with job offerings found");
}
}, 30000);
it("should filter out own wallet address", async () => {
const keyword = "agent";
const options = {
topK: 10,
};
const result = await acpClient.browseAgents(keyword, options);
// Verify own wallet is not in results
const ownWalletInResults = result.some(
(agent) =>
agent.walletAddress.toLowerCase() ===
BUYER_AGENT_WALLET_ADDRESS.toLowerCase(),
);
expect(ownWalletInResults).toBe(false);
}, 30000);
it("should filter by contract address", async () => {
const keyword = "agent";
const options = {
topK: 10,
};
const result = await acpClient.browseAgents(keyword, options);
if (result.length > 0) {
// All returned agents should have matching contract address
const allHaveMatchingContract = result.every(
(agent) =>
agent.contractAddress.toLowerCase() ===
contractClient.contractAddress.toLowerCase(),
);
expect(allHaveMatchingContract).toBe(true);
}
}, 30000);
it("should respect topK parameter", async () => {
const keyword = "agent";
const k = 3;
const options = {
topK: k,
};
const result = await acpClient.browseAgents(keyword, options);
expect(result.length).toBeLessThanOrEqual(k);
}, 30000);
it("should handle search with sort options", async () => {
const keyword = "trading";
const options = {
topK: 5,
sortBy: [AcpAgentSort.SUCCESSFUL_JOB_COUNT],
};
const result = await acpClient.browseAgents(keyword, options);
expect(Array.isArray(result)).toBe(true);
console.log(`Found ${result.length} agents sorted by successfulJobCount`);
}, 30000);
it("should handle search with graduation status filter", async () => {
const keyword = "agent";
const options = {
topK: 5,
graduationStatus: AcpGraduationStatus.GRADUATED,
};
const result = await acpClient.browseAgents(keyword, options);
expect(Array.isArray(result)).toBe(true);
console.log(`Found ${result.length} graduated agents`);
}, 30000);
it("should handle search with online status filter", async () => {
const keyword = "agent";
const options = {
topK: 5,
onlineStatus: AcpOnlineStatus.ONLINE,
};
const result = await acpClient.browseAgents(keyword, options);
expect(Array.isArray(result)).toBe(true);
console.log(`Found ${result.length} online agents`);
}, 30000);
it("should return empty or minimal results for non-existent keyword", async () => {
const keyword = "thiskeywordisnotakeyworddonotreturnanyagents";
const options = {
topK: 5,
};
const result = await acpClient.browseAgents(keyword, options);
expect(Array.isArray(result)).toBe(true);
// May or may not be empty depending on API behavior
console.log(`Found ${result.length} agents for non-existent keyword`);
}, 30000);
});
});