72 lines
2.7 KiB
Rust
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");
|
|
} |