use agy_bridge_test_support::*;
#[test]
fn chat_text_returns_predefined_text_verbatim() {
let rt = multi_thread_rt();
rt.block_on(async {
let expected = "The capital of France is Paris.";
let server = MockGeminiServer::start(vec![MockResponse::Text(expected.into())]).await;
let agent = BRIDGE
.agent(agent_config(&server.base_url(), "geo"))
.await
.expect("agent");
let text = agent.chat_text("capital of France?").await.expect("chat");
assert_eq!(
text.trim(),
expected,
"Caller should receive the proxy's pre-defined text verbatim"
);
assert_eq!(
server.post_count(),
1,
"Plain chat should issue exactly 1 POST"
);
agent.shutdown().await.expect("shutdown");
});
}
#[test]
fn predefined_unicode_text_round_trip() {
let rt = multi_thread_rt();
rt.block_on(async {
let expected = "café ☕ 日本語 🚀 — ok";
let server = MockGeminiServer::start(vec![MockResponse::Text(expected.into())]).await;
let agent = BRIDGE
.agent(agent_config(&server.base_url(), "unicode"))
.await
.expect("agent");
let text = agent.chat_text("say it").await.expect("chat");
assert_eq!(
text.trim(),
expected,
"Unicode content must be preserved byte-for-byte"
);
agent.shutdown().await.expect("shutdown");
});
}
#[test]
fn system_instruction_and_prompt_forwarded_to_backend() {
let rt = multi_thread_rt();
rt.block_on(async {
let server = MockGeminiServer::start(vec![MockResponse::Text("ack".into())]).await;
let agent = BRIDGE
.agent(agent_config(&server.base_url(), "SYSTEM_MARKER_XYZ"))
.await
.expect("agent");
agent.chat_text("PROMPT_MARKER_ABC").await.expect("chat");
let posts = server.recorded_posts().await;
assert!(!posts.is_empty(), "Expected at least one recorded POST");
let body = &posts[0].body;
assert!(
body.contains("SYSTEM_MARKER_XYZ"),
"System instruction should be forwarded, got body: {body}"
);
assert!(
body.contains("PROMPT_MARKER_ABC"),
"User prompt should be forwarded, got body: {body}"
);
agent.shutdown().await.expect("shutdown");
});
}
#[test]
fn multi_turn_conversation_forwards_history() {
let rt = multi_thread_rt();
rt.block_on(async {
let server = MockGeminiServer::start(vec![
MockResponse::Text("First answer.".into()),
MockResponse::Text("Second answer.".into()),
])
.await;
let agent = BRIDGE
.agent(agent_config(&server.base_url(), "chat_history"))
.await
.expect("agent");
let t1 = agent
.chat_text("Remember the token APPLE_MARKER_T1")
.await
.expect("turn 1");
assert_eq!(t1.trim(), "First answer.");
let t2 = agent.chat_text("What did I say?").await.expect("turn 2");
assert_eq!(t2.trim(), "Second answer.");
assert_eq!(server.post_count(), 2, "Two turns should issue two POSTs");
let posts = server.recorded_posts().await;
assert!(
posts[1].body.contains("APPLE_MARKER_T1"),
"Second turn's request must include first turn's content as history, \
got body: {}",
posts[1].body
);
agent.shutdown().await.expect("shutdown");
});
}
#[test]
fn streaming_text_chunks_assemble_to_predefined_text() {
let rt = multi_thread_rt();
rt.block_on(async {
let expected = "Streamed hello world.";
let server = MockGeminiServer::start(vec![MockResponse::Text(expected.into())]).await;
let agent = BRIDGE
.agent(agent_config(&server.base_url(), "streaming"))
.await
.expect("agent");
let mut handle = agent.chat("stream please").await.expect("chat handle");
let mut stream = handle.take_text_stream().expect("text stream");
let mut assembled = String::new();
while let Some(chunk) = stream.recv().await {
assembled.push_str(&chunk);
}
assert_eq!(
assembled.trim(),
expected,
"Streamed chunks should reassemble into the pre-defined text"
);
agent.shutdown().await.expect("shutdown");
});
}
#[test]
fn usage_metadata_surfaced_from_predefined_response() {
let rt = multi_thread_rt();
rt.block_on(async {
let server = MockGeminiServer::start(vec![MockResponse::Text("counted".into())]).await;
let agent = BRIDGE
.agent(agent_config(&server.base_url(), "usage"))
.await
.expect("agent");
let handle = agent.chat("count tokens").await.expect("chat handle");
let result = handle.text().await.expect("text result");
let usage = result
.usage()
.expect("usage metadata should be populated from the mock response");
assert_eq!(
usage.total_token_count,
Some(25),
"Total token count should reflect the proxy's pre-defined usageMetadata"
);
agent.shutdown().await.expect("shutdown");
});
}
#[test]
fn two_agents_receive_independent_predefined_text() {
let rt = multi_thread_rt();
rt.block_on(async {
let server_a =
MockGeminiServer::start(vec![MockResponse::Text("ALPHA_RESPONSE".into())]).await;
let server_b =
MockGeminiServer::start(vec![MockResponse::Text("BETA_RESPONSE".into())]).await;
let agent_a = BRIDGE
.agent(agent_config(&server_a.base_url(), "agent_a"))
.await
.expect("agent a");
let agent_b = BRIDGE
.agent(agent_config(&server_b.base_url(), "agent_b"))
.await
.expect("agent b");
let (r_a, r_b) = tokio::join!(agent_a.chat_text("hi a"), agent_b.chat_text("hi b"));
assert_eq!(r_a.expect("chat a").trim(), "ALPHA_RESPONSE");
assert_eq!(r_b.expect("chat b").trim(), "BETA_RESPONSE");
agent_a.shutdown().await.expect("shutdown a");
agent_b.shutdown().await.expect("shutdown b");
});
}