#[cfg(test)]
mod tests {
use kasl::db::db::Db;
use kasl::libs::config::Config;
use serial_test::serial;
use tempfile::TempDir;
use test_context::{TestContext, test_context};
struct BasicTestContext {
_temp_dir: TempDir,
}
impl TestContext for BasicTestContext {
fn setup() -> Self {
let temp_dir = tempfile::tempdir().unwrap();
unsafe {
std::env::set_var("HOME", temp_dir.path());
}
unsafe {
std::env::set_var("LOCALAPPDATA", temp_dir.path());
}
BasicTestContext { _temp_dir: temp_dir }
}
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_database_initialization(_ctx: &mut BasicTestContext) {
let db_result = Db::new();
assert!(db_result.is_ok());
let _db1 = Db::new().unwrap();
let _db2 = Db::new().unwrap();
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_config_default_creation(_ctx: &mut BasicTestContext) {
let config = Config::default();
assert!(config.monitor.is_none());
assert!(config.server.is_none());
assert!(config.si.is_none());
assert!(config.gitlab.is_none());
assert!(config.jira.is_none());
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_config_save_and_read(_ctx: &mut BasicTestContext) {
let config = Config {
monitor: Some(kasl::libs::config::MonitorConfig {
min_pause_duration: 30,
pause_threshold: 60,
poll_interval: 1000,
activity_threshold: 30,
min_work_interval: 10,
..Default::default()
}),
server: Some(kasl::libs::config::ServerConfig {
api_url: "https://test.example.com".to_string(),
auth_token: "test_token_123".to_string(),
}),
si: None,
gitlab: None,
jira: None,
jira_inbox: None,
productivity: None,
report: None,
task_discovery: None,
};
let save_result = config.save();
assert!(save_result.is_ok());
let loaded_config = Config::read();
assert!(loaded_config.is_ok());
let loaded = loaded_config.unwrap();
if loaded.monitor.is_some() && loaded.server.is_some() {
let monitor = loaded.monitor.unwrap();
assert_eq!(monitor.min_pause_duration, 30);
assert_eq!(monitor.pause_threshold, 60);
let server = loaded.server.unwrap();
assert_eq!(server.api_url, "https://test.example.com");
assert_eq!(server.auth_token, "test_token_123");
} else {
}
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_data_storage_functionality(_ctx: &mut BasicTestContext) {
use kasl::libs::data_storage::DataStorage;
let storage = DataStorage::new();
let test_path = storage.get_path("test_file.txt");
assert!(test_path.is_ok());
let path = test_path.unwrap();
assert!(path.to_string_lossy().contains("test_file.txt"));
if let Some(parent) = path.parent() {
let create_result = std::fs::create_dir_all(parent);
assert!(create_result.is_ok());
}
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_task_struct_creation(_ctx: &mut BasicTestContext) {
use kasl::libs::task::Task;
let task1 = Task::new("Test Task", "Description", Some(50));
assert_eq!(task1.name, "Test Task");
assert_eq!(task1.comment, "Description");
assert_eq!(task1.completeness, Some(50));
assert!(task1.id.is_none());
let task2 = Task::new("Another Task", "", None);
assert_eq!(task2.name, "Another Task");
assert_eq!(task2.comment, "");
assert_eq!(task2.completeness, None);
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_formatter_functionality(_ctx: &mut BasicTestContext) {
use chrono::Duration;
use kasl::libs::formatter::{FormattedEvent, format_duration};
let duration1 = Duration::hours(2) + Duration::minutes(30);
let formatted1 = format_duration(&duration1);
assert_eq!(formatted1, "02:30");
let duration2 = Duration::minutes(45);
let formatted2 = format_duration(&duration2);
assert_eq!(formatted2, "00:45");
let zero_duration = Duration::zero();
let formatted_zero = format_duration(&zero_duration);
assert_eq!(formatted_zero, "00:00");
let negative_duration = Duration::minutes(-30);
let formatted_negative = format_duration(&negative_duration);
assert_eq!(formatted_negative, "00:00");
let event = FormattedEvent {
id: 1,
start: "09:00".to_string(),
end: "17:00".to_string(),
duration: "08:00".to_string(),
};
assert_eq!(event.id, 1);
assert_eq!(event.start, "09:00");
assert_eq!(event.end, "17:00");
assert_eq!(event.duration, "08:00");
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_autostart_status_query(_ctx: &mut BasicTestContext) {
use kasl::libs::autostart;
let status_result = autostart::status();
assert!(status_result.is_ok());
let status = status_result.unwrap();
assert!(status == "enabled" || status == "disabled");
let enabled_result = autostart::is_enabled();
assert!(enabled_result.is_ok());
let _is_enabled = enabled_result.unwrap();
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_daemon_operations_dont_panic(_ctx: &mut BasicTestContext) {
use kasl::libs::daemon;
let stop_result = std::panic::catch_unwind(|| {
let _ = daemon::stop();
});
assert!(stop_result.is_ok());
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_message_types(_ctx: &mut BasicTestContext) {
use kasl::libs::messages::Message;
let message1 = Message::NoIdSet;
let message_str = message1.to_string();
assert!(!message_str.is_empty());
let message2 = Message::WatcherNotRunning;
let message2_str = message2.to_string();
assert!(!message2_str.is_empty());
assert_ne!(message_str, message2_str); }
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_data_persistence(_ctx: &mut BasicTestContext) {
use kasl::libs::data_storage::DataStorage;
use std::fs;
let storage = DataStorage::new();
let test_file_path = storage.get_path("persistence_test.txt").unwrap();
if let Some(parent) = test_file_path.parent() {
let _ = fs::create_dir_all(parent);
}
let test_content = "This is test data for persistence";
let write_result = fs::write(&test_file_path, test_content);
assert!(write_result.is_ok());
let read_result = fs::read_to_string(&test_file_path);
assert!(read_result.is_ok());
let read_content = read_result.unwrap();
assert_eq!(read_content, test_content);
let _ = fs::remove_file(&test_file_path);
}
#[test_context(BasicTestContext)]
#[serial]
#[test]
fn test_error_handling_patterns(_ctx: &mut BasicTestContext) {
use kasl::libs::config::Config;
use kasl::libs::data_storage::DataStorage;
let storage = DataStorage::new();
let _invalid_path = storage.get_path("");
let config_result = Config::read();
assert!(config_result.is_ok());
let db_result = Db::new();
assert!(db_result.is_ok()); }
}