Files
ares-next/server/tests/tracker_ws.rs

72 lines
2.7 KiB
Rust

use ares_server::config::Config;
use ares_server::{build_app, router};
use futures_util::{SinkExt, StreamExt};
use serde_json::json;
use tempfile::tempdir;
async fn spawn_server() -> (String, ares_server::state::SharedState) {
let dir = tempdir().unwrap();
let cfg = Config {
db_path: dir.path().join("t.db").to_string_lossy().into(),
..Default::default()
};
let state = build_app(cfg).await;
let app = router(state.clone());
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
tokio::spawn(async move {
let _ = axum::serve(listener, app).await;
});
(format!("http://{addr}"), state)
}
fn ws_url(base: &str) -> String {
base.replace("http", "ws")
}
async fn connect_ws(base: &str, peer_id: &str, file_id: &str) -> tokio_tungstenite::WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>> {
let (mut socket, _) =
tokio_tungstenite::connect_async(&format!("{}/api/v1/tracker/ws", ws_url(base))).await.unwrap();
socket
.send(tokio_tungstenite::tungstenite::Message::Text(
json!({"peer_id": peer_id, "file_id": file_id}).to_string(),
)).await.unwrap();
socket
}
#[tokio::test]
async fn ws_registers_and_http_peers_lists_it() {
let (base, _state) = spawn_server().await;
let _socket = connect_ws(&base, "peerA", "abc123").await;
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
let client = reqwest::Client::new();
let res = client
.get(format!("{base}/api/v1/peers/abc123"))
.send().await.unwrap();
let body: serde_json::Value = res.json().await.unwrap();
assert_eq!(body["file_id"], "abc123");
assert!(body["peers"].as_array().unwrap().contains(&serde_json::Value::String("peerA".into())));
}
#[tokio::test]
async fn ws_broadcasts_peer_online() {
let (base, _state) = spawn_server().await;
let mut a = connect_ws(&base, "peerA", "f1").await;
tokio::time::sleep(std::time::Duration::from_millis(150)).await;
let _b = connect_ws(&base, "peerB", "f1").await;
// peerA deve receber a notificação de que peerB ficou online
let timeout = tokio::time::timeout(std::time::Duration::from_secs(2), a.next());
let got = timeout.await.unwrap().expect("peerA fechou").expect("erro ws");
let text = match got {
tokio_tungstenite::tungstenite::Message::Text(t) => t.to_string(),
other => panic!("esperado Text, recebido: {other:?}"),
};
let parsed: serde_json::Value = serde_json::from_str(&text).unwrap();
eprintln!("received: {parsed}");
assert_eq!(parsed["type"], "peer_online");
assert_eq!(parsed["peer_id"], "peerB");
}