refactor: restructure MessageInfo with logical field grouping (P2.6)
Сгруппированы 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>
This commit is contained in:
@@ -106,7 +106,7 @@ fn format_message_for_test(msg: &tele_tui::tdlib::MessageInfo) -> String {
|
||||
}
|
||||
|
||||
// Добавляем основной текст
|
||||
result.push_str(&msg.content);
|
||||
result.push_str(msg.text());
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ fn test_delete_multiple_messages() {
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 1);
|
||||
assert_eq!(messages[0].id, msg2_id);
|
||||
assert_eq!(messages[0].content, "Message 2");
|
||||
assert_eq!(messages[0].content.text(), "Message 2");
|
||||
}
|
||||
|
||||
/// Test: Удаление только своих сообщений (проверка через can_be_deleted_for_all_users)
|
||||
@@ -145,5 +145,5 @@ fn test_cancel_delete_keeps_message() {
|
||||
// Сообщение на месте
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages[0].id, msg_id);
|
||||
assert_eq!(messages[0].content, "Keep me");
|
||||
assert_eq!(messages[0].content.text(), "Keep me");
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ fn test_edit_message_changes_text() {
|
||||
// Проверяем что текст сообщения изменился
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 1);
|
||||
assert_eq!(messages[0].content, "Edited text");
|
||||
assert_eq!(messages[0].content.text(), "Edited text");
|
||||
}
|
||||
|
||||
/// Test: Редактирование устанавливает edit_date
|
||||
@@ -97,7 +97,7 @@ fn test_multiple_edits_of_same_message() {
|
||||
// Проверяем что сообщение содержит последнюю версию
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 1);
|
||||
assert_eq!(messages[0].content, "Final version");
|
||||
assert_eq!(messages[0].content.text(), "Final version");
|
||||
}
|
||||
|
||||
/// Test: Редактирование несуществующего сообщения (ничего не происходит)
|
||||
@@ -129,21 +129,21 @@ fn test_edit_history_tracking() {
|
||||
|
||||
// Сохраняем original
|
||||
let messages_before = client.get_messages(123);
|
||||
let original = messages_before[0].content.clone();
|
||||
let original = messages_before[0].text().to_string();
|
||||
|
||||
// Редактируем
|
||||
client.edit_message(123, msg_id, "Edited".to_string());
|
||||
|
||||
// Проверяем что изменилось
|
||||
let messages_edited = client.get_messages(123);
|
||||
assert_eq!(messages_edited[0].content, "Edited");
|
||||
assert_eq!(messages_edited[0].content.text(), "Edited");
|
||||
|
||||
// Можем "отменить" редактирование вернув original
|
||||
client.edit_message(123, msg_id, original);
|
||||
|
||||
// Проверяем что вернулось
|
||||
let messages_restored = client.get_messages(123);
|
||||
assert_eq!(messages_restored[0].content, "Original");
|
||||
assert_eq!(messages_restored[0].content.text(), "Original");
|
||||
|
||||
// История показывает 2 редактирования
|
||||
assert_eq!(client.edited_messages().len(), 2);
|
||||
|
||||
@@ -156,9 +156,9 @@ impl FakeTdClient {
|
||||
|
||||
// Обновляем сообщение в списке
|
||||
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 = new_text;
|
||||
msg.edit_date = msg.date + 60;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,22 +188,22 @@ impl TestMessageBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> MessageInfo {
|
||||
MessageInfo {
|
||||
id: MessageId::new(self.id),
|
||||
sender_name: self.sender_name,
|
||||
is_outgoing: self.is_outgoing,
|
||||
content: self.content,
|
||||
entities: self.entities,
|
||||
date: self.date,
|
||||
edit_date: self.edit_date,
|
||||
is_read: self.is_read,
|
||||
can_be_edited: self.can_be_edited,
|
||||
can_be_deleted_only_for_self: self.can_be_deleted_only_for_self,
|
||||
can_be_deleted_for_all_users: self.can_be_deleted_for_all_users,
|
||||
reply_to: self.reply_to,
|
||||
forward_from: self.forward_from,
|
||||
reactions: self.reactions,
|
||||
}
|
||||
MessageInfo::new(
|
||||
MessageId::new(self.id),
|
||||
self.sender_name,
|
||||
self.is_outgoing,
|
||||
self.content,
|
||||
self.entities,
|
||||
self.date,
|
||||
self.edit_date,
|
||||
self.is_read,
|
||||
self.can_be_edited,
|
||||
self.can_be_deleted_only_for_self,
|
||||
self.can_be_deleted_for_all_users,
|
||||
self.reply_to,
|
||||
self.forward_from,
|
||||
self.reactions,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -223,6 +223,6 @@ fn test_load_older_messages_on_scroll_up() {
|
||||
|
||||
// Теперь должно быть 15 сообщений
|
||||
assert_eq!(client.get_messages(123).len(), 15);
|
||||
assert_eq!(client.get_messages(123)[0].content, "Msg 81");
|
||||
assert_eq!(client.get_messages(123)[14].content, "Msg 100");
|
||||
assert_eq!(client.get_messages(123)[0].content.text(), "Msg 81");
|
||||
assert_eq!(client.get_messages(123)[14].content.text(), "Msg 100");
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ fn test_reply_creates_message_with_reply_to() {
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 2);
|
||||
assert_eq!(messages[1].id, reply_id);
|
||||
assert_eq!(messages[1].content, "Answer!");
|
||||
assert_eq!(messages[1].content.text(), "Answer!");
|
||||
}
|
||||
|
||||
/// Test: Reply отображает превью оригинального сообщения
|
||||
@@ -76,7 +76,7 @@ fn test_cancel_reply_sends_without_reply_to() {
|
||||
assert_eq!(client.sent_messages()[0].reply_to, None);
|
||||
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages[1].content, "Regular message");
|
||||
assert_eq!(messages[1].content.text(), "Regular message");
|
||||
}
|
||||
|
||||
/// Test: Forward создаёт сообщение с forward_from
|
||||
|
||||
@@ -99,12 +99,12 @@ fn test_search_messages_in_chat() {
|
||||
let messages = client.get_messages(123);
|
||||
let found: Vec<_> = messages
|
||||
.iter()
|
||||
.filter(|m| m.content.to_lowercase().contains(&query))
|
||||
.filter(|m| m.text().to_lowercase().contains(&query))
|
||||
.collect();
|
||||
|
||||
assert_eq!(found.len(), 2);
|
||||
assert_eq!(found[0].content, "Hello world");
|
||||
assert_eq!(found[1].content, "Hello again");
|
||||
assert_eq!(found[0].text(), "Hello world");
|
||||
assert_eq!(found[1].text(), "Hello again");
|
||||
}
|
||||
|
||||
/// Test: Навигация по результатам поиска (n/N)
|
||||
@@ -124,7 +124,7 @@ fn test_navigate_search_results() {
|
||||
let results: Vec<_> = messages
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, m)| m.content.to_lowercase().contains(&query))
|
||||
.filter(|(_, m)| m.text().to_lowercase().contains(&query))
|
||||
.collect();
|
||||
|
||||
assert_eq!(results.len(), 3);
|
||||
@@ -135,17 +135,17 @@ fn test_navigate_search_results() {
|
||||
// n - следующий результат
|
||||
current_index = (current_index + 1) % results.len();
|
||||
assert_eq!(current_index, 1);
|
||||
assert_eq!(results[current_index].1.content, "Second match");
|
||||
assert_eq!(results[current_index].1.text(), "Second match");
|
||||
|
||||
// n - ещё один
|
||||
current_index = (current_index + 1) % results.len();
|
||||
assert_eq!(current_index, 2);
|
||||
assert_eq!(results[current_index].1.content, "Third match");
|
||||
assert_eq!(results[current_index].1.text(), "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");
|
||||
assert_eq!(results[current_index].1.text(), "First match");
|
||||
|
||||
// N - предыдущий (wrap to last)
|
||||
current_index = if current_index == 0 {
|
||||
@@ -154,7 +154,7 @@ fn test_navigate_search_results() {
|
||||
current_index - 1
|
||||
};
|
||||
assert_eq!(current_index, 2);
|
||||
assert_eq!(results[current_index].1.content, "Third match");
|
||||
assert_eq!(results[current_index].1.text(), "Third match");
|
||||
}
|
||||
|
||||
/// Test: Поиск с учётом регистра (case-insensitive)
|
||||
@@ -173,7 +173,7 @@ fn test_search_case_insensitive() {
|
||||
let messages = client.get_messages(123);
|
||||
let found: Vec<_> = messages
|
||||
.iter()
|
||||
.filter(|m| m.content.to_lowercase().contains(&query))
|
||||
.filter(|m| m.text().to_lowercase().contains(&query))
|
||||
.collect();
|
||||
|
||||
// Все 3 варианта должны найтись
|
||||
@@ -195,7 +195,7 @@ fn test_search_no_results() {
|
||||
let messages = client.get_messages(123);
|
||||
let found: Vec<_> = messages
|
||||
.iter()
|
||||
.filter(|m| m.content.to_lowercase().contains(&query))
|
||||
.filter(|m| m.text().to_lowercase().contains(&query))
|
||||
.collect();
|
||||
|
||||
assert_eq!(found.len(), 0);
|
||||
|
||||
@@ -25,7 +25,7 @@ fn test_send_text_message() {
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 1);
|
||||
assert_eq!(messages[0].id, msg_id);
|
||||
assert_eq!(messages[0].content, "Hello, Mom!");
|
||||
assert_eq!(messages.text(), "Hello, Mom!");
|
||||
assert_eq!(messages[0].is_outgoing, true);
|
||||
}
|
||||
|
||||
@@ -52,9 +52,9 @@ fn test_send_multiple_messages_updates_list() {
|
||||
assert_eq!(messages[0].id, msg1_id);
|
||||
assert_eq!(messages[1].id, msg2_id);
|
||||
assert_eq!(messages[2].id, msg3_id);
|
||||
assert_eq!(messages[0].content, "Message 1");
|
||||
assert_eq!(messages[1].content, "Message 2");
|
||||
assert_eq!(messages[2].content, "Message 3");
|
||||
assert_eq!(messages.text(), "Message 1");
|
||||
assert_eq!(messages.text(), "Message 2");
|
||||
assert_eq!(messages.text(), "Message 3");
|
||||
}
|
||||
|
||||
/// Test: Отправка пустого сообщения (должно быть игнорировано на уровне App)
|
||||
@@ -74,7 +74,7 @@ fn test_send_empty_message_technical() {
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 1);
|
||||
assert_eq!(messages[0].id, msg_id);
|
||||
assert_eq!(messages[0].content, "");
|
||||
assert_eq!(messages.text(), "");
|
||||
}
|
||||
|
||||
/// Test: Отправка сообщения с форматированием (markdown сущности)
|
||||
@@ -89,7 +89,7 @@ fn test_send_message_with_markdown() {
|
||||
// Проверяем что текст сохранился как есть (парсинг markdown - отдельная логика)
|
||||
let messages = client.get_messages(123);
|
||||
assert_eq!(messages.len(), 1);
|
||||
assert_eq!(messages[0].content, text);
|
||||
assert_eq!(messages.text(), text);
|
||||
}
|
||||
|
||||
/// Test: Отправка сообщения в разные чаты
|
||||
@@ -112,12 +112,12 @@ fn test_send_messages_to_different_chats() {
|
||||
// Проверяем что сообщения распределены по чатам
|
||||
let chat123_messages = client.get_messages(123);
|
||||
assert_eq!(chat123_messages.len(), 2);
|
||||
assert_eq!(chat123_messages[0].content, "Hello Mom");
|
||||
assert_eq!(chat123_messages[1].content, "How are you?");
|
||||
assert_eq!(chat123_messages.text(), "Hello Mom");
|
||||
assert_eq!(chat123_messages.text(), "How are you?");
|
||||
|
||||
let chat456_messages = client.get_messages(456);
|
||||
assert_eq!(chat456_messages.len(), 1);
|
||||
assert_eq!(chat456_messages[0].content, "Hello Boss");
|
||||
assert_eq!(chat456_messages.text(), "Hello Boss");
|
||||
}
|
||||
|
||||
/// Test: Новое сообщение появляется в реальном времени (симуляция)
|
||||
@@ -141,6 +141,6 @@ fn test_receive_incoming_message() {
|
||||
assert_eq!(messages.len(), 2);
|
||||
assert_eq!(messages[0].is_outgoing, true); // Наше сообщение
|
||||
assert_eq!(messages[1].is_outgoing, false); // Входящее
|
||||
assert_eq!(messages[1].content, "Hey there!");
|
||||
assert_eq!(messages.text(), "Hey there!");
|
||||
assert_eq!(messages[1].sender_name, "Alice");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user