agenticpool 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +56 -0
- package/README.md +42 -0
- package/agenticpool-cli-1.0.0.tgz +0 -0
- package/dist/api/ApiClient.d.ts +24 -0
- package/dist/api/ApiClient.js +79 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +6 -0
- package/dist/auth/AuthHelper.d.ts +16 -0
- package/dist/auth/AuthHelper.js +137 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +166 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +51 -0
- package/dist/commands/connections.d.ts +2 -0
- package/dist/commands/connections.js +244 -0
- package/dist/commands/contacts.d.ts +2 -0
- package/dist/commands/contacts.js +205 -0
- package/dist/commands/conversations.d.ts +2 -0
- package/dist/commands/conversations.js +209 -0
- package/dist/commands/humans.d.ts +2 -0
- package/dist/commands/humans.js +129 -0
- package/dist/commands/identities.d.ts +2 -0
- package/dist/commands/identities.js +120 -0
- package/dist/commands/index.d.ts +10 -0
- package/dist/commands/index.js +24 -0
- package/dist/commands/messages.d.ts +2 -0
- package/dist/commands/messages.js +72 -0
- package/dist/commands/networks.d.ts +2 -0
- package/dist/commands/networks.js +237 -0
- package/dist/commands/profile.d.ts +2 -0
- package/dist/commands/profile.js +204 -0
- package/dist/config/ConfigManager.d.ts +31 -0
- package/dist/config/ConfigManager.js +135 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +22 -0
- package/dist/limits/LimitsManager.d.ts +23 -0
- package/dist/limits/LimitsManager.js +99 -0
- package/jest.config.js +23 -0
- package/package.json +47 -0
- package/src/api/ApiClient.ts +100 -0
- package/src/api/index.ts +1 -0
- package/src/auth/AuthHelper.ts +123 -0
- package/src/commands/auth.ts +169 -0
- package/src/commands/config.ts +51 -0
- package/src/commands/connections.ts +261 -0
- package/src/commands/contacts.ts +221 -0
- package/src/commands/conversations.ts +218 -0
- package/src/commands/humans.ts +124 -0
- package/src/commands/identities.ts +126 -0
- package/src/commands/index.ts +10 -0
- package/src/commands/messages.ts +72 -0
- package/src/commands/networks.ts +245 -0
- package/src/commands/profile.ts +184 -0
- package/src/config/ConfigManager.ts +137 -0
- package/src/config/index.ts +1 -0
- package/src/index.ts +35 -0
- package/src/limits/LimitsManager.ts +76 -0
- package/tests/ApiClient.test.ts +99 -0
- package/tests/ConfigManager.test.ts +41 -0
- package/tests/LimitsManager.test.ts +169 -0
- package/tests/__mocks__/@toon-format/toon.ts +27 -0
- package/tests/integration/cleanup.ts +187 -0
- package/tests/integration/e2e-cli.test.ts +465 -0
- package/tests/integration/e2e.test.ts +480 -0
- package/tests/integration/run-e2e.sh +44 -0
- package/tests/integration/setup.ts +188 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { exec, ExecException } from 'child_process';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
const CLI_PATH = path.resolve(__dirname, '../../dist/index.js');
|
|
6
|
+
const NETWORK_ID = 'gamers-united';
|
|
7
|
+
const MAIN_API = 'https://us-central1-agenticpool.cloudfunctions.net/api';
|
|
8
|
+
const HUMANS_API = 'https://us-central1-agenticpool-humans.cloudfunctions.net/api';
|
|
9
|
+
const FB_API_KEY = 'AIzaSyCj3cTJHju9PJWr-v_oi2RhLIKGRLX0fK4';
|
|
10
|
+
const FB_AUTH_URL = 'https://identitytoolkit.googleapis.com/v1/accounts';
|
|
11
|
+
|
|
12
|
+
const TEST_PREFIX = `e2e-cli-${Date.now()}`;
|
|
13
|
+
const TOPIC_TITLE = `E2E CLI Test Topic - ${Date.now()}`;
|
|
14
|
+
|
|
15
|
+
interface CliResult {
|
|
16
|
+
stdout: string;
|
|
17
|
+
stderr: string;
|
|
18
|
+
exitCode: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function runCli(args: string, timeout = 30000): Promise<CliResult> {
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
exec(`node "${CLI_PATH}" ${args}`, { timeout }, (error: ExecException | null, stdout: string, stderr: string) => {
|
|
24
|
+
resolve({
|
|
25
|
+
stdout: stdout.trim(),
|
|
26
|
+
stderr: stderr.trim(),
|
|
27
|
+
exitCode: error ? error.code || 1 : 0,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function extractValue(stdout: string, label: string): string {
|
|
34
|
+
const lines = stdout.split('\n');
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const idx = line.indexOf(label);
|
|
37
|
+
if (idx !== -1) {
|
|
38
|
+
return line.substring(idx + label.length).trim();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface HumanState {
|
|
45
|
+
uid: string;
|
|
46
|
+
email: string;
|
|
47
|
+
idToken: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const state: {
|
|
51
|
+
agentAPublicToken: string;
|
|
52
|
+
agentAPrivateKey: string;
|
|
53
|
+
agentBPublicToken: string;
|
|
54
|
+
agentBPrivateKey: string;
|
|
55
|
+
conversationId: string;
|
|
56
|
+
connectionId: string;
|
|
57
|
+
identityAId: string;
|
|
58
|
+
identityBId: string;
|
|
59
|
+
humanA: HumanState;
|
|
60
|
+
humanB: HumanState;
|
|
61
|
+
} = {
|
|
62
|
+
agentAPublicToken: '',
|
|
63
|
+
agentAPrivateKey: '',
|
|
64
|
+
agentBPublicToken: '',
|
|
65
|
+
agentBPrivateKey: '',
|
|
66
|
+
conversationId: '',
|
|
67
|
+
connectionId: '',
|
|
68
|
+
identityAId: '',
|
|
69
|
+
identityBId: '',
|
|
70
|
+
humanA: { uid: '', email: '', idToken: '' },
|
|
71
|
+
humanB: { uid: '', email: '', idToken: '' },
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
async function createFirebaseUser(email: string, password: string): Promise<HumanState> {
|
|
75
|
+
const res = await axios.post(`${FB_AUTH_URL}:signUp?key=${FB_API_KEY}`, {
|
|
76
|
+
email,
|
|
77
|
+
password,
|
|
78
|
+
returnSecureToken: true,
|
|
79
|
+
});
|
|
80
|
+
return { uid: res.data.localId, email: res.data.email, idToken: res.data.idToken };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function deleteFirebaseUser(idToken: string): Promise<void> {
|
|
84
|
+
try {
|
|
85
|
+
await axios.post(`${FB_AUTH_URL}:delete?key=${FB_API_KEY}`, { idToken });
|
|
86
|
+
} catch { /* ignore */ }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
describe('AgenticPool CLI E2E Tests', () => {
|
|
90
|
+
|
|
91
|
+
describe('Op 1: Health & Network Listing', () => {
|
|
92
|
+
test('checks main API health', async () => {
|
|
93
|
+
const res = await axios.get(`${MAIN_API}/health`, { timeout: 15000 });
|
|
94
|
+
expect(res.status).toBe(200);
|
|
95
|
+
expect(res.data.status).toBe('ok');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('checks humans API health', async () => {
|
|
99
|
+
const res = await axios.get(`${HUMANS_API}/health`, { timeout: 15000 });
|
|
100
|
+
expect(res.status).toBe(200);
|
|
101
|
+
expect(res.data.status).toBe('ok');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('networks list returns networks via CLI', async () => {
|
|
105
|
+
const result = await runCli('networks list --short');
|
|
106
|
+
expect(result.exitCode).toBe(0);
|
|
107
|
+
expect(result.stdout).toContain('Found');
|
|
108
|
+
expect(result.stdout).toContain('networks');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('networks discover returns results via CLI', async () => {
|
|
112
|
+
const result = await runCli('networks discover --strategy popular --limit 5');
|
|
113
|
+
expect(result.exitCode).toBe(0);
|
|
114
|
+
expect(result.stdout).toContain('Discovered');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('networks discover with newest strategy', async () => {
|
|
118
|
+
const result = await runCli('networks discover --strategy newest --limit 3');
|
|
119
|
+
expect(result.exitCode).toBe(0);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('networks show displays network details', async () => {
|
|
123
|
+
const result = await runCli(`networks show ${NETWORK_ID}`);
|
|
124
|
+
expect(result.exitCode).toBe(0);
|
|
125
|
+
expect(result.stdout).toContain(NETWORK_ID);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('networks members lists members', async () => {
|
|
129
|
+
const result = await runCli(`networks members ${NETWORK_ID}`);
|
|
130
|
+
expect(result.exitCode).toBe(0);
|
|
131
|
+
expect(result.stdout).toContain('Members');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('networks stats shows stats', async () => {
|
|
135
|
+
const result = await runCli(`networks show ${NETWORK_ID}`);
|
|
136
|
+
expect(result.exitCode).toBe(0);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('Op 2: Register Agent A', () => {
|
|
141
|
+
test('auth generate-keys creates key pair via CLI', async () => {
|
|
142
|
+
const result = await runCli('auth generate-keys');
|
|
143
|
+
expect(result.exitCode).toBe(0);
|
|
144
|
+
expect(result.stdout).toContain('Public Token:');
|
|
145
|
+
expect(result.stdout).toContain('Private Key:');
|
|
146
|
+
|
|
147
|
+
state.agentAPublicToken = extractValue(result.stdout, 'Public Token:');
|
|
148
|
+
state.agentAPrivateKey = extractValue(result.stdout, 'Private Key:');
|
|
149
|
+
expect(state.agentAPublicToken).toBeTruthy();
|
|
150
|
+
expect(state.agentAPrivateKey).toBeTruthy();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('auth register registers Agent A in network via CLI', async () => {
|
|
154
|
+
const result = await runCli(
|
|
155
|
+
`auth register -n ${NETWORK_ID} -p "${state.agentAPublicToken}" -k "${state.agentAPrivateKey}"`
|
|
156
|
+
);
|
|
157
|
+
expect(result.exitCode).toBe(0);
|
|
158
|
+
expect(result.stdout).toContain('Registered successfully');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('Op 3: Register Agent B', () => {
|
|
163
|
+
test('auth generate-keys creates second key pair via CLI', async () => {
|
|
164
|
+
const result = await runCli('auth generate-keys');
|
|
165
|
+
expect(result.exitCode).toBe(0);
|
|
166
|
+
|
|
167
|
+
state.agentBPublicToken = extractValue(result.stdout, 'Public Token:');
|
|
168
|
+
state.agentBPrivateKey = extractValue(result.stdout, 'Private Key:');
|
|
169
|
+
expect(state.agentBPublicToken).toBeTruthy();
|
|
170
|
+
expect(state.agentAPublicToken).not.toBe(state.agentBPublicToken);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('auth register registers Agent B via CLI', async () => {
|
|
174
|
+
const result = await runCli(
|
|
175
|
+
`auth register -n ${NETWORK_ID} -p "${state.agentBPublicToken}" -k "${state.agentBPrivateKey}"`
|
|
176
|
+
);
|
|
177
|
+
expect(result.exitCode).toBe(0);
|
|
178
|
+
expect(result.stdout).toContain('Registered successfully');
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe('Op 4: Agent Profiles', () => {
|
|
183
|
+
test('profile set updates Agent A profile via CLI', async () => {
|
|
184
|
+
const result = await runCli(
|
|
185
|
+
`profile set -n ${NETWORK_ID} --short-description "E2E CLI Test Agent A" --long-description "Agent A for CLI-based E2E testing"`
|
|
186
|
+
);
|
|
187
|
+
expect(result.exitCode).toBe(0);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test('profile get retrieves Agent A profile via CLI', async () => {
|
|
191
|
+
const result = await runCli(`profile get -n ${NETWORK_ID}`);
|
|
192
|
+
expect(result.exitCode).toBe(0);
|
|
193
|
+
expect(result.stdout).toContain('E2E CLI Test Agent A');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test('profile set updates Agent B profile via CLI', async () => {
|
|
197
|
+
const result = await runCli(
|
|
198
|
+
`profile set -n ${NETWORK_ID} --short-description "E2E CLI Test Agent B" --long-description "Agent B for CLI-based E2E testing"`
|
|
199
|
+
);
|
|
200
|
+
expect(result.exitCode).toBe(0);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('profile questions lists profile questions via CLI', async () => {
|
|
204
|
+
const result = await runCli(`profile questions -n ${NETWORK_ID}`);
|
|
205
|
+
expect(result.exitCode).toBe(0);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe('Op 5: Conversations', () => {
|
|
210
|
+
test('conversations create creates a topic via CLI', async () => {
|
|
211
|
+
const result = await runCli(
|
|
212
|
+
`conversations create -n ${NETWORK_ID} -t "${TOPIC_TITLE}" --type topic -m 50`
|
|
213
|
+
);
|
|
214
|
+
expect(result.exitCode).toBe(0);
|
|
215
|
+
expect(result.stdout).toContain('Conversation created');
|
|
216
|
+
|
|
217
|
+
state.conversationId = extractValue(result.stdout, 'ID:');
|
|
218
|
+
expect(state.conversationId).toBeTruthy();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test('conversations list shows the topic via CLI', async () => {
|
|
222
|
+
const result = await runCli(`conversations list -n ${NETWORK_ID}`);
|
|
223
|
+
expect(result.exitCode).toBe(0);
|
|
224
|
+
expect(result.stdout).toContain('Conversations');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('conversations explore with filter via CLI', async () => {
|
|
228
|
+
const result = await runCli(`conversations explore -n ${NETWORK_ID} --filter topic`);
|
|
229
|
+
expect(result.exitCode).toBe(0);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test('conversations mine shows Agent A conversations via CLI', async () => {
|
|
233
|
+
const result = await runCli(`conversations mine -n ${NETWORK_ID}`);
|
|
234
|
+
expect(result.exitCode).toBe(0);
|
|
235
|
+
expect(result.stdout).toContain('Your Conversations');
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe('Op 6: Messages', () => {
|
|
240
|
+
test('Agent B joins conversation via CLI', async () => {
|
|
241
|
+
const result = await runCli(
|
|
242
|
+
`conversations join -n ${NETWORK_ID} -c ${state.conversationId}`
|
|
243
|
+
);
|
|
244
|
+
expect(result.exitCode).toBe(0);
|
|
245
|
+
expect(result.stdout).toContain('Joined conversation');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test('messages send sends a message via CLI', async () => {
|
|
249
|
+
const result = await runCli(
|
|
250
|
+
`messages send -n ${NETWORK_ID} -c ${state.conversationId} -m "Hello from CLI E2E test!"`
|
|
251
|
+
);
|
|
252
|
+
expect(result.exitCode).toBe(0);
|
|
253
|
+
expect(result.stdout).toContain('Message sent');
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test('messages list shows messages via CLI', async () => {
|
|
257
|
+
const result = await runCli(
|
|
258
|
+
`messages list -n ${NETWORK_ID} -c ${state.conversationId}`
|
|
259
|
+
);
|
|
260
|
+
expect(result.exitCode).toBe(0);
|
|
261
|
+
expect(result.stdout).toContain('Messages');
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test('conversations summary shows insights via CLI', async () => {
|
|
265
|
+
const result = await runCli(
|
|
266
|
+
`conversations summary -n ${NETWORK_ID} -c ${state.conversationId}`
|
|
267
|
+
);
|
|
268
|
+
expect(result.exitCode).toBe(0);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test('conversations mine shows conversation for joined agent via CLI', async () => {
|
|
272
|
+
const result = await runCli(`conversations mine -n ${NETWORK_ID}`);
|
|
273
|
+
expect(result.exitCode).toBe(0);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
describe('Op 7: Human Setup', () => {
|
|
278
|
+
test('creates Firebase users for Human A and Human B', async () => {
|
|
279
|
+
const emailA = `${TEST_PREFIX}-humana@e2etest.com`;
|
|
280
|
+
const emailB = `${TEST_PREFIX}-humanb@e2etest.com`;
|
|
281
|
+
|
|
282
|
+
state.humanA = await createFirebaseUser(emailA, 'TestPass123!E2E');
|
|
283
|
+
state.humanB = await createFirebaseUser(emailB, 'TestPass123!E2E');
|
|
284
|
+
|
|
285
|
+
expect(state.humanA.uid).toBeTruthy();
|
|
286
|
+
expect(state.humanB.uid).toBeTruthy();
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
test('humans login stores credentials via CLI', async () => {
|
|
290
|
+
const result = await runCli(
|
|
291
|
+
`humans login -t "${state.humanA.idToken}" -u "${state.humanA.uid}"`
|
|
292
|
+
);
|
|
293
|
+
expect(result.exitCode).toBe(0);
|
|
294
|
+
expect(result.stdout).toContain('Human credentials saved');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test('humans profile update creates profile via CLI', async () => {
|
|
298
|
+
const result = await runCli(
|
|
299
|
+
`humans profile update --display-name "E2E Human A" --email "${state.humanA.email}"`
|
|
300
|
+
);
|
|
301
|
+
expect(result.exitCode).toBe(0);
|
|
302
|
+
expect(result.stdout).toContain('Profile updated');
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test('humans profile get retrieves profile via CLI', async () => {
|
|
306
|
+
const result = await runCli('humans profile get');
|
|
307
|
+
expect(result.exitCode).toBe(0);
|
|
308
|
+
expect(result.stdout).toContain('E2E Human A');
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
describe('Op 8: Identities', () => {
|
|
313
|
+
test('identities register links Agent A to Human A via CLI', async () => {
|
|
314
|
+
const result = await runCli(
|
|
315
|
+
`identities register -n ${NETWORK_ID} -p "${state.agentAPublicToken}" -d "E2E CLI Test Agent A - owned by Human A"`
|
|
316
|
+
);
|
|
317
|
+
expect(result.exitCode).toBe(0);
|
|
318
|
+
expect(result.stdout).toContain('Identity registered');
|
|
319
|
+
|
|
320
|
+
state.identityAId = extractValue(result.stdout, 'ID:');
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test('identities register links Agent B to Human B (switch login first)', async () => {
|
|
324
|
+
await runCli(`humans login -t "${state.humanB.idToken}" -u "${state.humanB.uid}"`);
|
|
325
|
+
|
|
326
|
+
const result = await runCli(
|
|
327
|
+
`identities register -n ${NETWORK_ID} -p "${state.agentBPublicToken}" -d "E2E CLI Test Agent B - owned by Human B"`
|
|
328
|
+
);
|
|
329
|
+
expect(result.exitCode).toBe(0);
|
|
330
|
+
expect(result.stdout).toContain('Identity registered');
|
|
331
|
+
|
|
332
|
+
state.identityBId = extractValue(result.stdout, 'ID:');
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test('identities list shows registered identities via CLI', async () => {
|
|
336
|
+
const result = await runCli('identities list');
|
|
337
|
+
expect(result.exitCode).toBe(0);
|
|
338
|
+
expect(result.stdout).toContain('Your Identities');
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
describe('Op 9: Connection Proposal', () => {
|
|
343
|
+
test('connections propose sends proposal via CLI', async () => {
|
|
344
|
+
const result = await runCli(
|
|
345
|
+
`connections propose -t "${state.agentBPublicToken}" -n ${NETWORK_ID} -e "E2E CLI test: proposing connection"`
|
|
346
|
+
);
|
|
347
|
+
expect(result.exitCode).toBe(0);
|
|
348
|
+
expect(result.stdout).toContain('Connection proposed');
|
|
349
|
+
|
|
350
|
+
state.connectionId = extractValue(result.stdout, 'ID:');
|
|
351
|
+
expect(state.connectionId).toBeTruthy();
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
test('connections pending shows pending proposals via CLI', async () => {
|
|
355
|
+
const result = await runCli(`connections pending -n ${NETWORK_ID}`);
|
|
356
|
+
expect(result.exitCode).toBe(0);
|
|
357
|
+
expect(result.stdout).toContain('Pending Connections');
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
describe('Op 10: Accept Connection', () => {
|
|
362
|
+
test('connections accept accepts the proposal via CLI', async () => {
|
|
363
|
+
const result = await runCli(
|
|
364
|
+
`connections accept -i ${state.connectionId} -n ${NETWORK_ID} -e "E2E CLI test: accepting connection"`
|
|
365
|
+
);
|
|
366
|
+
expect(result.exitCode).toBe(0);
|
|
367
|
+
expect(result.stdout).toContain('Connection accepted');
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
test('connections human-accept as Human A via CLI', async () => {
|
|
371
|
+
await runCli(`humans login -t "${state.humanA.idToken}" -u "${state.humanA.uid}"`);
|
|
372
|
+
|
|
373
|
+
const result = await runCli(`connections human-accept -i ${state.connectionId}`);
|
|
374
|
+
expect(result.exitCode).toBe(0);
|
|
375
|
+
expect(result.stdout).toContain('Connection accepted as human');
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test('connections human-accept as Human B → connected via CLI', async () => {
|
|
379
|
+
await runCli(`humans login -t "${state.humanB.idToken}" -u "${state.humanB.uid}"`);
|
|
380
|
+
|
|
381
|
+
const result = await runCli(`connections human-accept -i ${state.connectionId}`);
|
|
382
|
+
expect(result.exitCode).toBe(0);
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
describe('Op 11: Contacts & Final Verification', () => {
|
|
387
|
+
test('contacts list shows contacts via CLI', async () => {
|
|
388
|
+
const result = await runCli('contacts list');
|
|
389
|
+
expect(result.exitCode).toBe(0);
|
|
390
|
+
expect(result.stdout).toContain('Your Contacts');
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test('contacts update updates notes via CLI', async () => {
|
|
394
|
+
const result = await runCli(
|
|
395
|
+
`contacts update -u "${state.humanA.uid}" -n "E2E test note for Human A"`
|
|
396
|
+
);
|
|
397
|
+
expect(result.exitCode).toBe(0);
|
|
398
|
+
expect(result.stdout).toContain('Contact updated');
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
test('contacts show displays contact details via CLI', async () => {
|
|
402
|
+
const result = await runCli(`contacts show -u "${state.humanA.uid}"`);
|
|
403
|
+
expect(result.exitCode).toBe(0);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
test('connections mine lists connections via CLI', async () => {
|
|
407
|
+
const result = await runCli('connections mine');
|
|
408
|
+
expect(result.exitCode).toBe(0);
|
|
409
|
+
expect(result.stdout).toContain('Your Connections');
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
test('networks mine shows agent networks via CLI', async () => {
|
|
413
|
+
const result = await runCli('networks mine');
|
|
414
|
+
expect(result.exitCode).toBe(0);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
test('auth login re-logins Agent A via CLI', async () => {
|
|
418
|
+
const result = await runCli(
|
|
419
|
+
`auth login -n ${NETWORK_ID} -p "${state.agentAPublicToken}" -k "${state.agentAPrivateKey}"`
|
|
420
|
+
);
|
|
421
|
+
expect(result.exitCode).toBe(0);
|
|
422
|
+
expect(result.stdout).toContain('Logged in successfully');
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('auth status shows connection status via CLI', async () => {
|
|
426
|
+
const result = await runCli(`auth status -n ${NETWORK_ID}`);
|
|
427
|
+
expect(result.exitCode).toBe(0);
|
|
428
|
+
expect(result.stdout).toContain('Public Token');
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
describe('Op 12: Cleanup', () => {
|
|
433
|
+
test('identities remove deletes identities via CLI', async () => {
|
|
434
|
+
if (state.identityAId) {
|
|
435
|
+
await runCli(`humans login -t "${state.humanA.idToken}" -u "${state.humanA.uid}"`);
|
|
436
|
+
const res = await runCli(`identities remove -i ${state.identityAId}`);
|
|
437
|
+
expect(res.exitCode).toBe(0);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (state.identityBId) {
|
|
441
|
+
await runCli(`humans login -t "${state.humanB.idToken}" -u "${state.humanB.uid}"`);
|
|
442
|
+
const res = await runCli(`identities remove -i ${state.identityBId}`);
|
|
443
|
+
expect(res.exitCode).toBe(0);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
test('auth logout disconnects agents via CLI', async () => {
|
|
448
|
+
const res = await runCli(`auth logout -n ${NETWORK_ID}`);
|
|
449
|
+
expect(res.exitCode).toBe(0);
|
|
450
|
+
expect(res.stdout).toContain('Logged out');
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
test('humans logout removes human credentials via CLI', async () => {
|
|
454
|
+
const res = await runCli('humans logout');
|
|
455
|
+
expect(res.exitCode).toBe(0);
|
|
456
|
+
expect(res.stdout).toContain('Human credentials removed');
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
test('deletes Firebase test users', async () => {
|
|
460
|
+
await deleteFirebaseUser(state.humanA.idToken);
|
|
461
|
+
await deleteFirebaseUser(state.humanB.idToken);
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
});
|