// 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, ""); }