123
}
124
}
125
}
126
+
127
+ /// Send `text` as a prompt and return the agent message text it streamed
128
+ /// before the turn ended.
129
+ fn prompt_text(&mut self, session_id: &str, text: &str) -> String {
130
+ let id = self.request(
131
+ "session/prompt",
132
+ json!({"sessionId": session_id, "prompt": [{"type": "text", "text": text}]}),
133
+ );
134
+ let deadline = Instant::now() + TIMEOUT;
135
+ let mut reply = String::new();
136
+ loop {
137
+ let remaining = deadline.saturating_duration_since(Instant::now());
138
+ let Ok(message) = self.incoming.recv_timeout(remaining) else {
139
+ panic!("timed out waiting for the response to prompt {id}");
140
+ };
141
+ if message["method"] == "session/update"
142
+ && message["params"]["update"]["sessionUpdate"] == "agent_message_chunk"
143
+ && let Some(chunk) = message["params"]["update"]["content"]["text"].as_str()
144
+ {
145
+ reply.push_str(chunk);
146
+ }
147
+ if message["id"] == id && message.get("method").is_none() {
148
+ return reply;
149
+ }
150
+ }
151
+ }
152
}
153
154
impl Drop for AgentUnderTest {
203
204
std::fs::remove_dir_all(&scratch).ok();
205
}
206
+
207
+/// `/whoami` asks `/api/v1/user`, the endpoint that accepts the OAuth tokens
208
+/// browser sign-in stores. The deprecated `/api/v1/me` answers them with a 403.
209
+#[test]
210
+fn whoami_checks_the_session_against_the_user_endpoint() {
211
+ let scratch = std::env::temp_dir().join(format!("sigit_acp_whoami_{}", std::process::id()));
212
+ let config_dir = scratch.join("config");
213
+ std::fs::create_dir_all(&config_dir).unwrap();
214
+ std::fs::write(
215
+ config_dir.join("credentials.toml"),
216
+ "access_token = \"token-under-test\"\nemail = \"dev@example.com\"\n",
217
+ )
218
+ .unwrap();
219
+
220
+ let (api_port, api_requests) = start_fake_account_api();
221
+ let mut agent = spawn_agent(api_port, &config_dir);
222
+
223
+ let id = agent.request(
224
+ "initialize",
225
+ json!({"protocolVersion": 1, "clientCapabilities": {}}),
226
+ );
227
+ agent.wait_for_response(id);
228
+ let id = agent.request("session/new", json!({"cwd": scratch, "mcpServers": []}));
229
+ let session_id = agent.wait_for_response(id)["result"]["sessionId"]
230
+ .as_str()
231
+ .expect("session id")
232
+ .to_string();
233
+
234
+ let reply = agent.prompt_text(&session_id, "/whoami");
235
+ assert!(
236
+ reply.contains("Signed in to siGit Code Cloud as dev@example.com"),
237
+ "{reply}"
238
+ );
239
+
240
+ let head = api_requests
241
+ .recv_timeout(TIMEOUT)
242
+ .expect("/whoami should ask the account API");
243
+ assert!(head.starts_with("get /api/v1/user "), "{head}");
244
+ assert!(
245
+ head.contains("authorization: bearer token-under-test"),
246
+ "{head}"
247
+ );
248
+
249
+ std::fs::remove_dir_all(&scratch).ok();
250
+}