fix: implement chunked message loading to fill screen on chat open

Проблема:
- get_chat_history() загружала только один чанк (50 сообщений max)
- При запросе 100 сообщений возвращалось только 50
- Экран не заполнялся полностью при открытии чата

Решение:
- Добавлена чанковая загрузка по TDLIB_MESSAGE_LIMIT (50) сообщений
- Автоматическая подгрузка пока не достигнут запрошенный limit
- Правильная сборка сообщений (старые чанки вставляются в начало)
- Retry логика для каждого чанка (до 3 попыток)

Изменения в src/tdlib/messages.rs:
- get_chat_history(): цикл загрузки чанков вместо одного запроса
- Вставка более старых чанков в начало списка (splice)
- Обработка edge cases (пустые результаты, ошибки, конец истории)

Тесты:
- test_chat_history_chunked_loading: проверка загрузки 100, 120, 200 сообщений
- Проверка правильного порядка сообщений (от старых к новым)
- Проверка границы между чанками (messages 50/51)

Все тесты пройдены: 343/343 

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-02-04 02:48:30 +03:00
parent c881f74ecb
commit 222a21770c
2 changed files with 155 additions and 42 deletions

View File

@@ -4,7 +4,7 @@ mod helpers;
use helpers::app_builder::TestAppBuilder;
use helpers::snapshot_utils::{buffer_to_string, render_to_buffer};
use helpers::test_data::{create_test_chat, TestChatBuilder};
use helpers::test_data::{create_test_chat, TestChatBuilder, TestMessageBuilder};
use insta::assert_snapshot;
#[test]
@@ -217,6 +217,71 @@ async fn test_opening_chat_loads_many_messages() {
assert_eq!(loaded_messages[49].text(), "Message 50");
}
#[tokio::test]
async fn test_chat_history_chunked_loading() {
use tele_tui::tdlib::TdClientTrait;
use tele_tui::types::ChatId;
// Создаём чат с 120 сообщениями (больше чем TDLIB_MESSAGE_LIMIT = 50)
let chat = TestChatBuilder::new("Long History Chat", 999)
.last_message("Message 120")
.build();
// Создаём 120 сообщений
let messages: Vec<_> = (1..=120)
.map(|i| {
TestMessageBuilder::new(&format!("Message {}", i), i)
.sender("Friend")
.build()
})
.collect();
let mut app = TestAppBuilder::new()
.with_chat(chat)
.with_messages(999, messages)
.build();
// Тест 1: Загружаем 100 сообщений (больше чем 50, меньше чем 120)
let chat_id = ChatId::new(999);
let loaded_messages = app.td_client.get_chat_history(chat_id, 100).await.unwrap();
assert_eq!(
loaded_messages.len(),
100,
"Should load 100 messages with chunked loading. Got: {}",
loaded_messages.len()
);
// Проверяем что сообщения в правильном порядке (от старых к новым)
assert_eq!(loaded_messages[0].text(), "Message 1");
assert_eq!(loaded_messages[49].text(), "Message 50"); // Граница первого чанка
assert_eq!(loaded_messages[50].text(), "Message 51"); // Начало второго чанка
assert_eq!(loaded_messages[99].text(), "Message 100");
// Тест 2: Загружаем все 120 сообщений
let all_messages = app.td_client.get_chat_history(chat_id, 120).await.unwrap();
assert_eq!(
all_messages.len(),
120,
"Should load all 120 messages. Got: {}",
all_messages.len()
);
assert_eq!(all_messages[0].text(), "Message 1");
assert_eq!(all_messages[119].text(), "Message 120");
// Тест 3: Запрашиваем 200 сообщений, но есть только 120
let limited_messages = app.td_client.get_chat_history(chat_id, 200).await.unwrap();
assert_eq!(
limited_messages.len(),
120,
"Should load only available 120 messages when requesting 200. Got: {}",
limited_messages.len()
);
}
#[test]
fn snapshot_chat_with_pinned() {
let chat = TestChatBuilder::new("Important Chat", 123)