feat(server): announce com validacao e persistencia + files por id

This commit is contained in:
2026-08-05 20:28:09 -03:00
parent 9c7cb1c9b8
commit 2564c33748
9 changed files with 319 additions and 2 deletions
+107
View File
@@ -0,0 +1,107 @@
mod common;
use common::test_server;
use serde_json::json;
#[tokio::test]
async fn announce_valid_ok() {
let server = test_server();
let res = server.post("/api/v1/announce")
.json(&json!({
"peer_id": "peer123",
"name": "minha-musica.ogg",
"description": "minha composicao",
"type": "audio",
"extension": "ogg",
"size_bytes": 1024,
"hash": "ab".repeat(32),
"license": "authored",
"tags": ["musica"]
}))
.await;
assert_eq!(res.status_code(), 200);
assert_eq!(res.json::<serde_json::Value>()["ok"], true);
}
#[tokio::test]
async fn announce_invalid_name_rejected() {
let server = test_server();
let res = server.post("/api/v1/announce")
.json(&json!({
"peer_id": "peer123",
"name": "",
"description": "",
"type": "audio",
"extension": "ogg",
"size_bytes": 10,
"hash": "ab".repeat(32),
"license": "authored"
}))
.await;
assert_eq!(res.status_code(), 400);
}
#[tokio::test]
async fn announce_bad_hash_rejected() {
let server = test_server();
let res = server.post("/api/v1/announce")
.json(&json!({
"peer_id": "peer123",
"name": "arquivo.ogg",
"description": "",
"type": "audio",
"extension": "ogg",
"size_bytes": 10,
"hash": "ab",
"license": "authored"
}))
.await;
assert_eq!(res.status_code(), 400);
}
#[tokio::test]
async fn announce_duplicate_hash_rejected() {
let server = test_server();
let body = json!({
"peer_id": "peer123",
"name": "musica.ogg",
"description": "",
"type": "audio",
"extension": "ogg",
"size_bytes": 100,
"hash": "ab".repeat(32),
"license": "authored"
});
server.post("/api/v1/announce").json(&body).await;
let res = server.post("/api/v1/announce").json(&body).await;
assert_eq!(res.status_code(), 400);
}
#[tokio::test]
async fn get_file_roundtrip() {
let server = test_server();
let hash = "cd".repeat(32);
server.post("/api/v1/announce")
.json(&json!({
"peer_id": "peer1",
"name": "doc.pdf",
"description": "",
"type": "document",
"extension": "pdf",
"size_bytes": 100,
"hash": hash,
"license": "authored"
}))
.await;
let file_id = format!("peer1::{}", &hash[..12]);
let res = server.get(&format!("/api/v1/files/{file_id}")).await;
assert_eq!(res.status_code(), 200);
assert_eq!(res.json::<serde_json::Value>()["name"], "doc.pdf");
}
#[tokio::test]
async fn get_file_missing_returns_404() {
let server = test_server();
let res = server.get("/api/v1/files/nao-existe").await;
assert_eq!(res.status_code(), 404);
}
+34
View File
@@ -0,0 +1,34 @@
use axum_test::TestServer;
use ares_server::config::Config;
use ares_server::state::AppState;
use ares_server::store;
use ares_server::router;
static TEST_DB_COUNTER: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);
pub fn test_server() -> TestServer {
let n = TEST_DB_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let db_path = std::env::temp_dir()
.join(format!("ares_test_{}_{}.db", std::process::id(), n))
.to_string_lossy()
.into_owned();
let cfg = Config { db_path, ..Default::default() };
let conn = store::open(&cfg).unwrap();
let state = AppState::new(cfg, conn);
TestServer::new(router(state))
}
pub async fn announce_test_file(server: &TestServer, name: &str, ftype: &str, hash: &str) {
server.post("/api/v1/announce")
.json(&serde_json::json!({
"peer_id": "peer9",
"name": name,
"description": "",
"type": ftype,
"extension": name.rsplit('.').next().unwrap_or("bin"),
"size_bytes": 100,
"hash": hash,
"license": "authored"
}))
.await;
}