feat(server): busca FTS5 com filtros e paginacao
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
mod common;
|
||||
|
||||
use common::{announce_test_file, test_server};
|
||||
use serde_json::json;
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_by_name_filters() {
|
||||
let server = test_server();
|
||||
for (name, ty, hash) in [
|
||||
("musica-bossa.ogg", "audio", "a1".repeat(32)),
|
||||
("musica-rock.mp3", "audio", "a2".repeat(32)),
|
||||
("ebook-p2p.pdf", "document", "a3".repeat(32)),
|
||||
] {
|
||||
announce_test_file(&server, name, ty, &hash).await;
|
||||
}
|
||||
let res = server.get("/api/v1/search?q=musica").await;
|
||||
assert_eq!(res.status_code(), 200);
|
||||
let items = res.json::<Vec<serde_json::Value>>();
|
||||
assert_eq!(items.len(), 2);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_filter_by_type() {
|
||||
let server = test_server();
|
||||
for (name, ty, hash) in [
|
||||
("musica-bossa.ogg", "audio", "a1".repeat(32)),
|
||||
("musica-rock.mp3", "audio", "a2".repeat(32)),
|
||||
("ebook-p2p.pdf", "document", "a3".repeat(32)),
|
||||
] {
|
||||
announce_test_file(&server, name, ty, &hash).await;
|
||||
}
|
||||
let res = server.get("/api/v1/search?q=musica&ftype=audio").await;
|
||||
let items = res.json::<Vec<serde_json::Value>>();
|
||||
assert_eq!(items.len(), 2);
|
||||
assert_eq!(items[0]["ftype"], "audio");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_pagination() {
|
||||
let server = test_server();
|
||||
for (name, ty, hash) in [
|
||||
("musica-bossa.ogg", "audio", "a1".repeat(32)),
|
||||
("musica-rock.mp3", "audio", "a2".repeat(32)),
|
||||
("ebook-p2p.pdf", "document", "a3".repeat(32)),
|
||||
] {
|
||||
announce_test_file(&server, name, ty, &hash).await;
|
||||
}
|
||||
let res = server.get("/api/v1/search?q=&limit=1&offset=0").await;
|
||||
let items = res.json::<Vec<serde_json::Value>>();
|
||||
assert_eq!(items.len(), 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn search_empty_results() {
|
||||
let server = test_server();
|
||||
let res = server.get("/api/v1/search?q=inexistente").await;
|
||||
assert_eq!(res.status_code(), 200);
|
||||
let items = res.json::<Vec<serde_json::Value>>();
|
||||
assert_eq!(items.len(), 0);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
use ares_server::search::fts_query;
|
||||
|
||||
#[test]
|
||||
fn empty_query_returns_none() {
|
||||
assert_eq!(fts_query(""), None);
|
||||
assert_eq!(fts_query(" "), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_term_wrapped_in_quotes() {
|
||||
assert_eq!(fts_query("musica").unwrap(), "\"musica\"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_terms_are_and() {
|
||||
assert_eq!(fts_query("bossa nova").unwrap(), "\"bossa\" AND \"nova\"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_whitespace_tokens_split_kept() {
|
||||
// tokens are split by whitespace; edge chars (like *) are stripped
|
||||
assert_eq!(fts_query("*ideal* fluido*").unwrap(), "\"ideal\" AND \"fluido\"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fts_special_single_char_stripped_at_edges() {
|
||||
assert_eq!(fts_query("album' rock").unwrap(), "\"album\" AND \"rock\"");
|
||||
}
|
||||
Reference in New Issue
Block a user