Files
telegram-tui/tests/search.rs
Mikhail Kilin 126c7482af
Some checks failed
CI / Check (pull_request) Has been cancelled
CI / Format (pull_request) Has been cancelled
CI / Clippy (pull_request) Has been cancelled
CI / Build (macos-latest) (pull_request) Has been cancelled
CI / Build (ubuntu-latest) (pull_request) Has been cancelled
CI / Build (windows-latest) (pull_request) Has been cancelled
fixes
2026-01-29 01:22:57 +03:00

242 lines
7.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Integration tests for search flow
mod helpers;
use helpers::fake_tdclient::FakeTdClient;
use helpers::test_data::{create_test_chat, TestChatBuilder, TestMessageBuilder};
/// Test: Поиск по чатам фильтрует по названию
#[test]
fn test_search_chats_by_title() {
let mut client = FakeTdClient::new();
let chat1 = create_test_chat("Mom", 123);
let chat2 = create_test_chat("Boss", 456);
let chat3 = create_test_chat("Mom's Work", 789);
client = client.with_chats(vec![chat1, chat2, chat3]);
// Ищем "mom" - должно найти "Mom" и "Mom's Work"
let query = "mom".to_lowercase();
let filtered: Vec<_> = client
.get_chats()
.iter()
.filter(|c| c.title.to_lowercase().contains(&query))
.collect();
assert_eq!(filtered.len(), 2);
assert_eq!(filtered[0].title, "Mom");
assert_eq!(filtered[1].title, "Mom's Work");
}
/// Test: Поиск по чатам фильтрует по @username
#[test]
fn test_search_chats_by_username() {
let mut client = FakeTdClient::new();
let chat1 = TestChatBuilder::new("Alice", 123)
.username("alice")
.build();
let chat2 = TestChatBuilder::new("Bob", 456)
.username("bobby")
.build();
let chat3 = TestChatBuilder::new("Charlie", 789).build(); // Без username
client = client.with_chats(vec![chat1, chat2, chat3]);
// Ищем "bob" - должно найти "Bob" (@bobby)
let query = "bob".to_lowercase();
let filtered: Vec<_> = client
.get_chats()
.iter()
.filter(|c| {
c.title.to_lowercase().contains(&query)
|| c.username
.as_ref()
.map(|u| u.to_lowercase().contains(&query))
.unwrap_or(false)
})
.collect();
assert_eq!(filtered.len(), 1);
assert_eq!(filtered[0].title, "Bob");
}
/// Test: Пустой поисковый запрос возвращает все чаты
#[test]
fn test_search_empty_query_returns_all() {
let mut client = FakeTdClient::new();
let chat1 = create_test_chat("Mom", 123);
let chat2 = create_test_chat("Boss", 456);
let chat3 = create_test_chat("Friend", 789);
client = client.with_chats(vec![chat1, chat2, chat3]);
// Пустой запрос
let query = "";
let filtered: Vec<_> = client
.get_chats()
.iter()
.filter(|c| c.title.to_lowercase().contains(query))
.collect();
// Все чаты проходят фильтр (пустая строка содержится в любой строке)
assert_eq!(filtered.len(), 3);
}
/// Test: Поиск внутри чата по тексту сообщений
#[test]
fn test_search_messages_in_chat() {
let mut client = FakeTdClient::new();
let msg1 = TestMessageBuilder::new("Hello world", 100).build();
let msg2 = TestMessageBuilder::new("How are you?", 101).build();
let msg3 = TestMessageBuilder::new("Hello again", 102).build();
client = client.with_messages(123, vec![msg1, msg2, msg3]);
// Ищем "hello"
let query = "hello".to_lowercase();
let messages = client.get_messages(123);
let found: Vec<_> = messages
.iter()
.filter(|m| m.content.to_lowercase().contains(&query))
.collect();
assert_eq!(found.len(), 2);
assert_eq!(found[0].content, "Hello world");
assert_eq!(found[1].content, "Hello again");
}
/// Test: Навигация по результатам поиска (n/N)
#[test]
fn test_navigate_search_results() {
let mut client = FakeTdClient::new();
let msg1 = TestMessageBuilder::new("First match", 100).build();
let msg2 = TestMessageBuilder::new("Second match", 101).build();
let msg3 = TestMessageBuilder::new("Third match", 102).build();
client = client.with_messages(123, vec![msg1, msg2, msg3]);
// Ищем "match"
let query = "match".to_lowercase();
let messages = client.get_messages(123);
let results: Vec<_> = messages
.iter()
.enumerate()
.filter(|(_, m)| m.content.to_lowercase().contains(&query))
.collect();
assert_eq!(results.len(), 3);
// Навигация: начинаем с индекса 0
let mut current_index = 0;
// n - следующий результат
current_index = (current_index + 1) % results.len();
assert_eq!(current_index, 1);
assert_eq!(results[current_index].1.content, "Second match");
// n - ещё один
current_index = (current_index + 1) % results.len();
assert_eq!(current_index, 2);
assert_eq!(results[current_index].1.content, "Third match");
// n - wrap around к первому
current_index = (current_index + 1) % results.len();
assert_eq!(current_index, 0);
assert_eq!(results[current_index].1.content, "First match");
// N - предыдущий (wrap to last)
current_index = if current_index == 0 {
results.len() - 1
} else {
current_index - 1
};
assert_eq!(current_index, 2);
assert_eq!(results[current_index].1.content, "Third match");
}
/// Test: Поиск с учётом регистра (case-insensitive)
#[test]
fn test_search_case_insensitive() {
let mut client = FakeTdClient::new();
let msg1 = TestMessageBuilder::new("HELLO", 100).build();
let msg2 = TestMessageBuilder::new("hello", 101).build();
let msg3 = TestMessageBuilder::new("HeLLo", 102).build();
client = client.with_messages(123, vec![msg1, msg2, msg3]);
// Ищем "hello" (lowercase)
let query = "hello".to_lowercase();
let messages = client.get_messages(123);
let found: Vec<_> = messages
.iter()
.filter(|m| m.content.to_lowercase().contains(&query))
.collect();
// Все 3 варианта должны найтись
assert_eq!(found.len(), 3);
}
/// Test: Поиск не находит ничего
#[test]
fn test_search_no_results() {
let mut client = FakeTdClient::new();
let msg1 = TestMessageBuilder::new("Hello", 100).build();
let msg2 = TestMessageBuilder::new("World", 101).build();
client = client.with_messages(123, vec![msg1, msg2]);
// Ищем "xyz" - не должно найтись
let query = "xyz".to_lowercase();
let messages = client.get_messages(123);
let found: Vec<_> = messages
.iter()
.filter(|m| m.content.to_lowercase().contains(&query))
.collect();
assert_eq!(found.len(), 0);
}
/// Test: Отмена поиска (Esc) восстанавливает обычный режим
#[test]
fn test_cancel_search_restores_normal_mode() {
let mut client = FakeTdClient::new();
let chat1 = create_test_chat("Mom", 123);
let chat2 = create_test_chat("Boss", 456);
client = client.with_chats(vec![chat1, chat2]);
// Симулируем: пользователь начал поиск
let mut is_searching = true;
let mut search_query = "mom".to_string();
// Фильтруем
let query = search_query.to_lowercase();
let filtered: Vec<_> = client
.get_chats()
.iter()
.filter(|c| c.title.to_lowercase().contains(&query))
.collect();
assert_eq!(filtered.len(), 1);
// Пользователь нажал Esc
is_searching = false;
search_query.clear();
// После отмены видим все чаты
let all_chats = client.get_chats();
assert_eq!(all_chats.len(), 2);
assert!(!is_searching);
assert_eq!(search_query, "");
}