Сгруппированы 16 плоских полей MessageInfo в 4 логические структуры для улучшения организации кода и maintainability. Новые структуры: - MessageMetadata: id, sender_name, date, edit_date - MessageContent: text, entities - MessageState: is_outgoing, is_read, can_be_edited, can_be_deleted_* - MessageInteractions: reply_to, forward_from, reactions Изменения: - Добавлены 4 новые структуры в tdlib/types.rs - Обновлена MessageInfo для использования новых структур - Добавлен конструктор MessageInfo::new() для удобного создания - Добавлены getter методы (id(), text(), sender_name() и др.) для удобного доступа - Обновлены все места создания MessageInfo (convert_message) - Обновлены все места использования (~200+ обращений): * ui/messages.rs: рендеринг сообщений * app/mod.rs: логика приложения * input/main_input.rs: обработка ввода и копирование * tdlib/client.rs: обработка updates * Все тестовые файлы (14 файлов) Преимущества: - Логическая группировка данных - Проще понимать структуру сообщения - Легче добавлять новые поля в будущем - Улучшенная читаемость кода Статус: Priority 2 теперь 80% (4/5 задач) - ✅ Error enum - ✅ Config validation - ✅ Newtype для ID - ✅ MessageInfo реструктуризация - ⏳ MessageBuilder pattern Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
265 lines
8.1 KiB
Rust
265 lines
8.1 KiB
Rust
// Fake TDLib client for testing
|
|
|
|
use std::collections::HashMap;
|
|
use tele_tui::tdlib::{ChatInfo, FolderInfo, MessageInfo, NetworkState};
|
|
|
|
/// Упрощённый mock TDLib клиента для тестов
|
|
#[derive(Clone)]
|
|
pub struct FakeTdClient {
|
|
pub chats: Vec<ChatInfo>,
|
|
pub messages: HashMap<i64, Vec<MessageInfo>>,
|
|
pub folders: Vec<FolderInfo>,
|
|
pub user_names: HashMap<i64, String>,
|
|
pub network_state: NetworkState,
|
|
pub typing_chat_id: Option<i64>,
|
|
pub sent_messages: Vec<SentMessage>,
|
|
pub edited_messages: Vec<EditedMessage>,
|
|
pub deleted_messages: Vec<i64>,
|
|
pub reactions: HashMap<i64, Vec<String>>, // message_id -> emojis
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct SentMessage {
|
|
pub chat_id: i64,
|
|
pub text: String,
|
|
pub reply_to: Option<i64>,
|
|
}
|
|
|
|
#[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<ChatInfo>) -> 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<MessageInfo>) -> 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<MessageInfo> {
|
|
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>) -> 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 {
|
|
id: message_id,
|
|
sender_name: "You".to_string(),
|
|
is_outgoing: true,
|
|
content: text,
|
|
entities: vec![],
|
|
date: 1640000000,
|
|
edit_date: 0,
|
|
is_read: true,
|
|
can_be_edited: true,
|
|
can_be_deleted_only_for_self: true,
|
|
can_be_deleted_for_all_users: true,
|
|
reply_to: None,
|
|
forward_from: None,
|
|
reactions: vec![],
|
|
};
|
|
|
|
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() == 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 != 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<i64>) {
|
|
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, 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, "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);
|
|
}
|
|
}
|