#![cfg(feature = "ws")]
use churust_core::ws::{Message, WebSocketUpgrade};
use churust_core::Churust;
use futures_util::{SinkExt, StreamExt};
use std::time::Duration;
#[tokio::test]
async fn websocket_echo_round_trip() {
let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap();
drop(listener);
let app = Churust::server()
.host(addr.ip().to_string())
.port(addr.port())
.routing(|r| {
r.get("/echo", |ws: WebSocketUpgrade| async move {
ws.on_upgrade(|mut sock| async move {
while let Some(Ok(msg)) = sock.recv().await {
match msg {
Message::Close => break,
other => {
if sock.send(other).await.is_err() {
break;
}
}
}
}
})
});
})
.build();
let (tx, rx) = tokio::sync::oneshot::channel::<()>();
let server = tokio::spawn(async move {
app.start_with_shutdown(async move {
let _ = rx.await;
})
.await
.unwrap();
});
tokio::time::sleep(Duration::from_millis(150)).await;
use tokio_tungstenite::tungstenite::Message as TM;
let url = format!("ws://{addr}/echo");
let (mut client, _resp) = tokio_tungstenite::connect_async(url)
.await
.expect("connect");
client.send(TM::Text("hello".into())).await.unwrap();
let got = client.next().await.unwrap().unwrap();
assert_eq!(got.to_text().unwrap(), "hello");
client.send(TM::Binary(vec![1, 2, 3].into())).await.unwrap();
let got = client.next().await.unwrap().unwrap();
assert_eq!(got.into_data().to_vec(), vec![1, 2, 3]);
client.close(None).await.unwrap();
let _ = tx.send(());
let _ = tokio::time::timeout(Duration::from_secs(2), server).await;
}