#[cfg(test)]
mod tests {
use chrono::Local;
use kasl::db::workdays::Workdays;
use kasl::libs::config::MonitorConfig;
use kasl::libs::monitor::Monitor;
use std::error::Error;
use tempfile::TempDir;
use test_context::{test_context, AsyncTestContext};
use tokio::time::{self, Duration, Instant};
struct MonitorTestContext {
_temp_dir: TempDir,
}
impl AsyncTestContext for MonitorTestContext {
async fn setup() -> Self {
let temp_dir = tempfile::tempdir().unwrap();
std::env::set_var("HOME", temp_dir.path());
std::env::set_var("LOCALAPPDATA", temp_dir.path());
MonitorTestContext { _temp_dir: temp_dir }
}
}
async fn simulate_monitor_cycle(monitor: &mut Monitor) -> Result<(), Box<dyn Error>> {
if monitor.detect_activity() {
monitor.ensure_workday_started(Local::now().date_naive())?;
}
Ok(())
}
#[test_context(MonitorTestContext)]
#[tokio::test]
async fn test_workday_start_after_sustained_activity(_ctx: &mut MonitorTestContext) {
let config = MonitorConfig {
activity_threshold: 1, poll_interval: 100, ..Default::default()
};
let mut monitor = Monitor::new(config).unwrap();
let today = Local::now().date_naive();
let mut workdays_db = Workdays::new().unwrap();
assert!(workdays_db.fetch(today).unwrap().is_none(), "Workday should not exist at the start of the test");
*monitor.activity_start.lock().unwrap() = Some(Instant::now());
let simulation_duration = Duration::from_millis(1500);
let start_time = Instant::now();
while start_time.elapsed() < simulation_duration {
*monitor.last_activity.lock().unwrap() = Instant::now();
simulate_monitor_cycle(&mut monitor).await.unwrap();
time::sleep(Duration::from_millis(monitor.config.poll_interval)).await;
}
let workday = workdays_db.fetch(today).unwrap();
assert!(workday.is_some(), "Workday should be created after sustained activity");
assert_eq!(workday.unwrap().date, today);
}
#[test_context(MonitorTestContext)]
#[tokio::test]
async fn test_no_workday_start_on_brief_activity(_ctx: &mut MonitorTestContext) {
let config = MonitorConfig {
activity_threshold: 5, ..Default::default()
};
let mut monitor = Monitor::new(config).unwrap();
let today = Local::now().date_naive();
let mut workdays_db = Workdays::new().unwrap();
*monitor.activity_start.lock().unwrap() = Some(Instant::now());
*monitor.last_activity.lock().unwrap() = Instant::now();
time::sleep(Duration::from_secs(1)).await;
simulate_monitor_cycle(&mut monitor).await.unwrap();
assert!(
workdays_db.fetch(today).unwrap().is_none(),
"Workday should not be created after brief activity"
);
}
}