Split core and TUI crates

This commit is contained in:
Mikhail Kilin
2026-05-20 00:31:18 +03:00
parent 91a8700b8e
commit eefac431e5
238 changed files with 624 additions and 191 deletions

View File

@@ -0,0 +1,231 @@
// Integration tests for config flow
use tele_tui::config::{
AudioConfig, ColorsConfig, Config, ImagesConfig, Keybindings, NotificationsConfig,
};
/// Test: Дефолтные значения конфигурации
#[test]
fn test_config_default_values() {
let config = Config::default();
// Проверяем дефолтные цвета
assert_eq!(config.colors.incoming_message, "white");
assert_eq!(config.colors.outgoing_message, "green");
assert_eq!(config.colors.selected_message, "yellow");
assert_eq!(config.colors.reaction_chosen, "yellow");
assert_eq!(config.colors.reaction_other, "gray");
}
/// Test: Создание конфига с кастомными значениями
#[test]
fn test_config_custom_values() {
let config = Config {
colors: ColorsConfig {
incoming_message: "cyan".to_string(),
outgoing_message: "blue".to_string(),
selected_message: "red".to_string(),
reaction_chosen: "green".to_string(),
reaction_other: "white".to_string(),
},
keybindings: Keybindings::default(),
notifications: NotificationsConfig::default(),
images: ImagesConfig::default(),
audio: AudioConfig::default(),
};
assert_eq!(config.colors.incoming_message, "cyan");
assert_eq!(config.colors.outgoing_message, "blue");
}
/// Test: Парсинг валидных цветов
#[test]
fn test_parse_valid_colors() {
use ratatui::style::Color;
let config = Config::default();
assert_eq!(config.parse_color("red"), Color::Red);
assert_eq!(config.parse_color("green"), Color::Green);
assert_eq!(config.parse_color("blue"), Color::Blue);
assert_eq!(config.parse_color("yellow"), Color::Yellow);
assert_eq!(config.parse_color("cyan"), Color::Cyan);
assert_eq!(config.parse_color("magenta"), Color::Magenta);
assert_eq!(config.parse_color("white"), Color::White);
assert_eq!(config.parse_color("black"), Color::Black);
assert_eq!(config.parse_color("gray"), Color::Gray);
assert_eq!(config.parse_color("grey"), Color::Gray);
}
/// Test: Парсинг light цветов
#[test]
fn test_parse_light_colors() {
use ratatui::style::Color;
let config = Config::default();
assert_eq!(config.parse_color("lightred"), Color::LightRed);
assert_eq!(config.parse_color("lightgreen"), Color::LightGreen);
assert_eq!(config.parse_color("lightblue"), Color::LightBlue);
assert_eq!(config.parse_color("lightyellow"), Color::LightYellow);
assert_eq!(config.parse_color("lightcyan"), Color::LightCyan);
assert_eq!(config.parse_color("lightmagenta"), Color::LightMagenta);
}
/// Test: Парсинг невалидного цвета использует fallback (White)
#[test]
fn test_parse_invalid_color_fallback() {
use ratatui::style::Color;
let config = Config::default();
// Невалидные цвета должны возвращать White
assert_eq!(config.parse_color("invalid_color"), Color::White);
assert_eq!(config.parse_color(""), Color::White);
assert_eq!(config.parse_color("purple"), Color::White); // purple не поддерживается
assert_eq!(config.parse_color("Orange"), Color::White); // orange не поддерживается
}
/// Test: Case-insensitive парсинг цветов
#[test]
fn test_parse_color_case_insensitive() {
use ratatui::style::Color;
let config = Config::default();
assert_eq!(config.parse_color("RED"), Color::Red);
assert_eq!(config.parse_color("Green"), Color::Green);
assert_eq!(config.parse_color("BLUE"), Color::Blue);
assert_eq!(config.parse_color("YeLLoW"), Color::Yellow);
}
/// Test: Сериализация и десериализация TOML
#[test]
fn test_config_toml_serialization() {
let original_config = Config {
colors: ColorsConfig {
incoming_message: "cyan".to_string(),
outgoing_message: "blue".to_string(),
selected_message: "red".to_string(),
reaction_chosen: "green".to_string(),
reaction_other: "white".to_string(),
},
keybindings: Keybindings::default(),
notifications: NotificationsConfig::default(),
images: ImagesConfig::default(),
audio: AudioConfig::default(),
};
// Сериализуем в TOML
let toml_string = toml::to_string(&original_config).expect("Failed to serialize config");
// Десериализуем обратно
let deserialized: Config = toml::from_str(&toml_string).expect("Failed to deserialize config");
// Проверяем что всё совпадает
assert_eq!(deserialized.colors.incoming_message, "cyan");
assert_eq!(deserialized.colors.outgoing_message, "blue");
assert_eq!(deserialized.colors.selected_message, "red");
}
/// Test: Парсинг TOML с частичными данными использует дефолты
#[test]
fn test_config_partial_toml_uses_defaults() {
// TOML только с colors.incoming_message
let toml_str = r#"
[colors]
incoming_message = "cyan"
"#;
let config: Config = toml::from_str(toml_str).expect("Failed to parse partial TOML");
// Кастомный цвет должен примениться
assert_eq!(config.colors.incoming_message, "cyan");
// Остальные colors должны быть дефолтными
assert_eq!(config.colors.outgoing_message, "green");
assert_eq!(config.colors.selected_message, "yellow");
}
#[cfg(test)]
mod credentials_tests {
use super::*;
use std::env;
/// Test: Загрузка credentials из переменных окружения
#[test]
fn test_load_credentials_from_env() {
// Устанавливаем env переменные для теста
unsafe {
env::set_var("API_ID", "12345");
env::set_var("API_HASH", "test_hash_from_env");
}
// Загружаем credentials
let result = Config::load_credentials();
// Проверяем что загрузилось из env
// Примечание: этот тест может зафейлиться если есть credentials файл,
// так как он имеет приоритет. Для полноценного тестирования нужно
// моковать файловую систему или использовать временные директории.
if let Ok((api_id, api_hash)) = result {
// Может быть либо из файла, либо из env
assert!(api_id > 0);
assert!(!api_hash.is_empty());
}
// Очищаем env переменные после теста
unsafe {
env::remove_var("API_ID");
env::remove_var("API_HASH");
}
}
/// Test: Проверка формата ошибки когда credentials не найдены
#[test]
fn test_load_credentials_error_message() {
// Проверяем есть ли credentials файл в системе
let has_credentials_file = Config::credentials_path()
.map(|p| p.exists())
.unwrap_or(false);
// Если есть credentials файл, тест не может проверить ошибку
if has_credentials_file {
// Просто проверяем что credentials загружаются
let result = Config::load_credentials();
assert!(result.is_ok(), "Credentials file exists but loading failed");
return;
}
// Временно сохраняем и удаляем env переменные
let original_api_id = env::var("API_ID").ok();
let original_api_hash = env::var("API_HASH").ok();
unsafe {
env::remove_var("API_ID");
env::remove_var("API_HASH");
}
// Пытаемся загрузить credentials без файла и без env
let result = Config::load_credentials();
// Должна быть ошибка
if let Err(err_msg) = result {
// Проверяем формат ошибки
assert!(!err_msg.is_empty(), "Error message should not be empty");
} else {
// Возможно env переменные установлены глобально и не удаляются
// Тест пропускается
eprintln!("Warning: credentials loaded despite removing env vars");
}
// Восстанавливаем env переменные
unsafe {
if let Some(api_id) = original_api_id {
env::set_var("API_ID", api_id);
}
if let Some(api_hash) = original_api_hash {
env::set_var("API_HASH", api_hash);
}
}
}
}