use super::*;
use chrono::{DateTime, Duration, Utc};
#[test]
fn test_is_stale_when_never_synced() {
let cache = Cache::new();
assert!(cache.last_sync.is_none());
let last_sync: Option<DateTime<Utc>> = None;
let now = Utc::now();
let threshold = Duration::minutes(5);
let is_stale = match last_sync {
None => true,
Some(ls) => now.signed_duration_since(ls) > threshold,
};
assert!(is_stale);
}
#[test]
fn test_is_stale_when_recently_synced() {
let now = Utc::now();
let last_sync = Some(now - Duration::minutes(2)); let threshold = Duration::minutes(5);
let is_stale = match last_sync {
None => true,
Some(ls) => now.signed_duration_since(ls) > threshold,
};
assert!(!is_stale);
}
#[test]
fn test_is_stale_when_old_sync() {
let now = Utc::now();
let last_sync = Some(now - Duration::minutes(10)); let threshold = Duration::minutes(5);
let is_stale = match last_sync {
None => true,
Some(ls) => now.signed_duration_since(ls) > threshold,
};
assert!(is_stale);
}
#[test]
fn test_is_stale_at_threshold_boundary() {
let now = Utc::now();
let last_sync = Some(now - Duration::minutes(5));
let threshold = Duration::minutes(5);
let is_stale = match last_sync {
None => true,
Some(ls) => now.signed_duration_since(ls) > threshold,
};
assert!(!is_stale);
}
#[test]
fn test_is_stale_just_over_threshold() {
let now = Utc::now();
let last_sync = Some(now - Duration::minutes(5) - Duration::seconds(1));
let threshold = Duration::minutes(5);
let is_stale = match last_sync {
None => true,
Some(ls) => now.signed_duration_since(ls) > threshold,
};
assert!(is_stale);
}
#[test]
fn test_needs_sync_when_full_sync_needed() {
let cache = Cache::new();
assert!(cache.needs_full_sync());
}
#[test]
fn test_needs_sync_when_stale() {
let mut cache = Cache::new();
cache.sync_token = "some_token".to_string(); cache.last_sync = Some(Utc::now() - Duration::minutes(10));
assert!(!cache.needs_full_sync());
}
#[test]
fn test_needs_sync_when_fresh() {
let mut cache = Cache::new();
cache.sync_token = "some_token".to_string(); cache.last_sync = Some(Utc::now());
assert!(!cache.needs_full_sync());
}
#[test]
fn test_find_similar_name_exact_match_returns_none() {
let candidates = ["Work", "Personal", "Shopping"];
let result = find_similar_name("Work", candidates.iter().copied());
assert!(result.is_none());
}
#[test]
fn test_find_similar_name_case_insensitive_exact_match_returns_none() {
let candidates = ["Work", "Personal", "Shopping"];
let result = find_similar_name("work", candidates.iter().copied());
assert!(result.is_none());
}
#[test]
fn test_find_similar_name_single_typo() {
let candidates = ["Work", "Personal", "Shopping"];
let result = find_similar_name("Wrok", candidates.iter().copied());
assert_eq!(result, Some("Work".to_string()));
}
#[test]
fn test_find_similar_name_missing_letter() {
let candidates = ["Inbox", "Personal", "Shopping"];
let result = find_similar_name("inbx", candidates.iter().copied());
assert_eq!(result, Some("Inbox".to_string()));
}
#[test]
fn test_find_similar_name_extra_letter() {
let candidates = ["Work", "Personal", "Shopping"];
let result = find_similar_name("Workk", candidates.iter().copied());
assert_eq!(result, Some("Work".to_string()));
}
#[test]
fn test_find_similar_name_too_different() {
let candidates = ["Work", "Personal", "Shopping"];
let result = find_similar_name("Completely Different", candidates.iter().copied());
assert!(result.is_none());
}
#[test]
fn test_find_similar_name_empty_candidates() {
let candidates: Vec<&str> = vec![];
let result = find_similar_name("Work", candidates.iter().copied());
assert!(result.is_none());
}
#[test]
fn test_find_similar_name_best_match_selected() {
let candidates = ["Workshop", "Work", "Working"];
let result = find_similar_name("Wok", candidates.iter().copied());
assert_eq!(result, Some("Work".to_string()));
}
#[test]
fn test_format_not_found_error_without_suggestion() {
let msg = format_not_found_error("Project", "inbox", None);
assert_eq!(
msg,
"Project 'inbox' not found. Try running 'td sync' to refresh your cache."
);
}
#[test]
fn test_format_not_found_error_with_suggestion() {
let msg = format_not_found_error("Project", "inbox", Some("Inbox"));
assert_eq!(
msg,
"Project 'inbox' not found. Try running 'td sync' to refresh your cache. Did you mean 'Inbox'?"
);
}
#[test]
fn test_format_not_found_error_label_with_suggestion() {
let msg = format_not_found_error("Label", "urgnt", Some("urgent"));
assert_eq!(
msg,
"Label 'urgnt' not found. Try running 'td sync' to refresh your cache. Did you mean 'urgent'?"
);
}