// Fake TDLib client for testing use std::collections::HashMap; use tele_tui::tdlib::{ChatInfo, FolderInfo, MessageInfo, NetworkState}; use tele_tui::types::MessageId; /// Упрощённый mock TDLib клиента для тестов #[derive(Clone)] pub struct FakeTdClient { pub chats: Vec, pub messages: HashMap>, pub folders: Vec, pub user_names: HashMap, pub network_state: NetworkState, pub typing_chat_id: Option, pub sent_messages: Vec, pub edited_messages: Vec, pub deleted_messages: Vec, pub reactions: HashMap>, // message_id -> emojis } #[derive(Debug, Clone)] pub struct SentMessage { pub chat_id: i64, pub text: String, pub reply_to: Option, } #[derive(Debug, Clone)] pub struct EditedMessage { pub message_id: i64, pub new_text: String, } impl Default for FakeTdClient { fn default() -> Self { Self::new() } } impl FakeTdClient { pub fn new() -> Self { Self { chats: vec![], messages: HashMap::new(), folders: vec![FolderInfo { id: 0, name: "All".to_string() }], user_names: HashMap::new(), network_state: NetworkState::Ready, typing_chat_id: None, sent_messages: vec![], edited_messages: vec![], deleted_messages: vec![], reactions: HashMap::new(), } } /// Добавить чат pub fn with_chat(mut self, chat: ChatInfo) -> Self { self.chats.push(chat); self } /// Добавить несколько чатов pub fn with_chats(mut self, chats: Vec) -> Self { self.chats.extend(chats); self } /// Добавить сообщение в чат pub fn with_message(mut self, chat_id: i64, message: MessageInfo) -> Self { self.messages .entry(chat_id) .or_insert_with(Vec::new) .push(message); self } /// Добавить несколько сообщений в чат pub fn with_messages(mut self, chat_id: i64, messages: Vec) -> Self { self.messages .entry(chat_id) .or_insert_with(Vec::new) .extend(messages); self } /// Добавить папку pub fn with_folder(mut self, id: i32, name: &str) -> Self { self.folders.push(FolderInfo { id, name: name.to_string() }); self } /// Добавить пользователя pub fn with_user(mut self, id: i64, name: &str) -> Self { self.user_names.insert(id, name.to_string()); self } /// Установить состояние сети pub fn with_network_state(mut self, state: NetworkState) -> Self { self.network_state = state; self } /// Получить чаты pub fn get_chats(&self) -> &[ChatInfo] { &self.chats } /// Получить сообщения для чата pub fn get_messages(&self, chat_id: i64) -> Vec { self.messages.get(&chat_id).cloned().unwrap_or_default() } /// Получить папки pub fn get_folders(&self) -> &[FolderInfo] { &self.folders } /// Отправить сообщение (мок) pub fn send_message(&mut self, chat_id: i64, text: String, reply_to: Option) -> i64 { let message_id = (self.sent_messages.len() as i64) + 1000; self.sent_messages .push(SentMessage { chat_id, text: text.clone(), reply_to }); // Добавляем сообщение в список сообщений чата let message = MessageInfo::new( MessageId::new(message_id), "You".to_string(), true, // is_outgoing text, vec![], // entities 1640000000, // date 0, // edit_date true, // is_read true, // can_be_edited true, // can_be_deleted_only_for_self true, // can_be_deleted_for_all_users None, // reply_to None, // forward_from vec![], // reactions ); self.messages .entry(chat_id) .or_insert_with(Vec::new) .push(message); message_id } /// Редактировать сообщение (мок) pub fn edit_message(&mut self, chat_id: i64, message_id: i64, new_text: String) { self.edited_messages .push(EditedMessage { message_id, new_text: new_text.clone() }); // Обновляем сообщение в списке if let Some(messages) = self.messages.get_mut(&chat_id) { if let Some(msg) = messages.iter_mut().find(|m| m.id().as_i64() == message_id) { msg.content.text = new_text; msg.metadata.edit_date = msg.metadata.date + 60; } } } /// Удалить сообщение (мок) pub fn delete_message(&mut self, chat_id: i64, message_id: i64) { self.deleted_messages.push(message_id); // Удаляем сообщение из списка if let Some(messages) = self.messages.get_mut(&chat_id) { messages.retain(|m| m.id().as_i64() != message_id); } } /// Добавить реакцию (мок) pub fn add_reaction(&mut self, message_id: i64, emoji: String) { self.reactions .entry(message_id) .or_insert_with(Vec::new) .push(emoji); } /// Установить статус "печатает" pub fn set_typing(&mut self, chat_id: Option) { self.typing_chat_id = chat_id; } /// Получить список отправленных сообщений pub fn sent_messages(&self) -> &[SentMessage] { &self.sent_messages } /// Получить список отредактированных сообщений pub fn edited_messages(&self) -> &[EditedMessage] { &self.edited_messages } /// Получить список удалённых сообщений pub fn deleted_messages(&self) -> &[i64] { &self.deleted_messages } /// Очистить историю действий pub fn clear_history(&mut self) { self.sent_messages.clear(); self.edited_messages.clear(); self.deleted_messages.clear(); } } #[cfg(test)] mod tests { use super::*; use crate::helpers::test_data::create_test_chat; #[test] fn test_fake_client_creation() { let client = FakeTdClient::new(); assert_eq!(client.chats.len(), 0); assert_eq!(client.folders.len(), 1); // Default "All" folder } #[test] fn test_fake_client_with_chat() { let chat = create_test_chat("Mom", 123); let client = FakeTdClient::new().with_chat(chat); assert_eq!(client.chats.len(), 1); assert_eq!(client.chats[0].title, "Mom"); } #[test] fn test_send_message() { let mut client = FakeTdClient::new(); let msg_id = client.send_message(123, "Hello".to_string(), None); assert_eq!(client.sent_messages().len(), 1); assert_eq!(client.sent_messages()[0].text, "Hello"); assert_eq!(client.get_messages(123).len(), 1); assert_eq!(client.get_messages(123)[0].id().as_i64(), msg_id); } #[test] fn test_edit_message() { let mut client = FakeTdClient::new(); let msg_id = client.send_message(123, "Hello".to_string(), None); client.edit_message(123, msg_id, "Hello World".to_string()); assert_eq!(client.edited_messages().len(), 1); assert_eq!(client.get_messages(123)[0].content.text, "Hello World"); assert!(client.get_messages(123)[0].edit_date() > 0); } #[test] fn test_delete_message() { let mut client = FakeTdClient::new(); let msg_id = client.send_message(123, "Hello".to_string(), None); client.delete_message(123, msg_id); assert_eq!(client.deleted_messages().len(), 1); assert_eq!(client.get_messages(123).len(), 0); } }