use serde::{Deserialize, Serialize};
use std::time::Duration;
use tokio::time::timeout;
use webex_message_handler::{Config, HandlerEvent, WebexMessageHandler};
const TIMEOUT_SECONDS: u64 = 30;
#[derive(Debug, Deserialize)]
struct WebexPerson {
#[allow(dead_code)]
id: String,
emails: Vec<String>,
#[serde(rename = "displayName")]
display_name: String,
}
#[derive(Debug, Deserialize)]
struct WebexMessage {
id: String,
}
#[derive(Debug, Serialize)]
struct SendMessageRequest {
#[serde(rename = "toPersonEmail")]
to_person_email: String,
text: String,
}
#[tokio::test]
#[ignore] async fn test_live_integration_send_and_receive() {
let receiver_token = match std::env::var("WEBEX_BOT_TOKEN") {
Ok(t) => t,
Err(_) => {
println!("⏭️ Skipping integration test: WEBEX_BOT_TOKEN not set (bot that receives messages)");
return;
}
};
let sender_token = match std::env::var("WEBEX_BOT_TOKEN_TEST") {
Ok(t) => t,
Err(_) => {
println!("⏭️ Skipping integration test: WEBEX_BOT_TOKEN_TEST not set (bot that sends test message)");
return;
}
};
println!("\n🚀 Starting integration test...\n");
let handler = WebexMessageHandler::new(Config {
token: receiver_token.clone(),
..Default::default()
})
.expect("Failed to create handler");
let test_message = format!(
"Integration test {}",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis()
);
let mut event_rx = handler
.take_event_rx()
.await
.expect("Failed to get event receiver");
println!("1️⃣ Connecting to Mercury...");
handler.connect().await.expect("Failed to connect");
println!("2️⃣ Fetching bot identities...");
let client = reqwest::Client::new();
let receiver: WebexPerson = client
.get("https://webexapis.com/v1/people/me")
.header("Authorization", format!("Bearer {}", receiver_token))
.send()
.await
.expect("Failed to fetch receiver bot identity")
.json()
.await
.expect("Failed to parse receiver bot identity");
let sender: WebexPerson = client
.get("https://webexapis.com/v1/people/me")
.header("Authorization", format!("Bearer {}", sender_token))
.send()
.await
.expect("Failed to fetch sender bot identity")
.json()
.await
.expect("Failed to parse sender bot identity");
println!(" Receiver: {} ({})", receiver.display_name, receiver.emails[0]);
println!(" Sender: {} ({})", sender.display_name, sender.emails[0]);
println!("3️⃣ Sending test message: \"{}\"", test_message);
let sent_msg: WebexMessage = client
.post("https://webexapis.com/v1/messages")
.header("Authorization", format!("Bearer {}", sender_token))
.header("Content-Type", "application/json")
.json(&SendMessageRequest {
to_person_email: receiver.emails[0].clone(),
text: test_message.clone(),
})
.send()
.await
.expect("Failed to send message")
.json()
.await
.expect("Failed to parse sent message");
println!(" Message sent (ID: {})", sent_msg.id);
println!("4️⃣ Waiting for message to arrive via Mercury...");
let result = timeout(Duration::from_secs(TIMEOUT_SECONDS), async {
while let Some(event) = event_rx.recv().await {
match event {
HandlerEvent::MessageCreated(msg) => {
println!("📨 Received message: \"{}\" from {}", msg.text, msg.person_email);
if msg.text == test_message {
return Some(msg.text);
}
}
HandlerEvent::Connected => {
println!("✅ Connected to Mercury");
}
HandlerEvent::Error(err) => {
println!("❌ Handler error: {}", err);
}
_ => {}
}
}
None
})
.await;
println!("\n📊 Test Results:");
match result {
Ok(Some(received_text)) => {
println!("✅ PASSED - Message received and decrypted successfully");
println!(" Expected: \"{}\"", test_message);
println!(" Received: \"{}\"", received_text);
assert_eq!(received_text, test_message);
}
Ok(None) => {
println!("❌ FAILED - Event stream ended without receiving message");
panic!("Integration test failed: event stream ended");
}
Err(_) => {
println!("❌ FAILED - Message not received within timeout");
panic!("Integration test failed: timeout");
}
}
println!("\n🧹 Cleaning up...");
handler.disconnect().await;
println!("✅ Disconnected");
}