use std::path::PathBuf;
use crate::caldir::TimeFormat;
use crate::diff::{CalendarDiff, EventChange};
use crate::provider::mock_provider::MockProvider;
use crate::{
Caldir, CaldirConfig, Calendar, CalendarConfig, CalendarEvent, Event, EventTime, Provider,
ProviderRegistry, ProviderSlug, Remote, RemoteConfig, RemoteConfigParams,
};
use chrono::NaiveDate;
use icalendar::{Component, EventLike};
use tempfile::TempDir;
pub fn test_caldir() -> (TempDir, Caldir) {
let (tmp_data_dir, test_caldir_config) = test_caldir_config();
let caldir = Caldir::new(test_caldir_config, ProviderRegistry::new());
(tmp_data_dir, caldir)
}
pub fn test_caldir_config() -> (TempDir, CaldirConfig) {
let tmp = TempDir::new().unwrap();
let data_dir = tmp.path().join("test-caldir");
let config = CaldirConfig::new(data_dir, TimeFormat::default(), None, None);
(tmp, config)
}
pub fn test_calendar_path() -> (TempDir, PathBuf) {
let tmp = TempDir::new().unwrap();
let calendar_path = tmp.path().to_path_buf().join("test-calendar");
(tmp, calendar_path)
}
pub fn test_calendar() -> (TempDir, Calendar) {
let (tmp, caldir) = test_caldir();
let calendar = caldir.create_calendar("test-calendar", None).unwrap();
(tmp, calendar)
}
pub fn test_calendar_event() -> (TempDir, CalendarEvent) {
let (tmp, calendar) = test_calendar();
let event = test_event();
let calendar_event = calendar.create_event(event.clone()).unwrap();
(tmp, calendar_event)
}
pub fn test_event_time() -> EventTime {
EventTime::DateTimeFloating(
NaiveDate::from_ymd_opt(2026, 1, 1)
.unwrap()
.and_hms_opt(12, 0, 0)
.unwrap(),
)
}
pub fn test_event() -> Event {
Event::new("Test Event", test_event_time())
}
pub fn test_icalendar_event() -> icalendar::Event {
icalendar::Event::new()
.uid("test-uid@caldir")
.starts(icalendar::DatePerhapsTime::Date(
chrono::NaiveDate::from_ymd_opt(2026, 1, 1).unwrap(),
))
.clone()
}
pub fn test_calendar_config() -> CalendarConfig {
CalendarConfig::new(
Some("Test Calendar".to_string()),
Some("#ff0000".to_string()),
Some(false),
None,
)
}
pub fn test_remote_config(provider_slug: &str) -> RemoteConfig {
let params = RemoteConfigParams::new();
RemoteConfig::new(ProviderSlug::from(provider_slug), params)
}
pub fn test_mock_provider() -> MockProvider {
MockProvider::new("test-provider")
}
pub fn test_remote_params() -> RemoteConfigParams {
let mut params = RemoteConfigParams::new();
params.insert(
"test_account".to_string(),
toml::Value::String("user@example.com".to_string()),
);
params
}
pub fn test_remote() -> (MockProvider, Remote) {
let mock = test_mock_provider();
let remote = Remote::new(mock.provider(), test_remote_params());
(mock, remote)
}
pub fn outgoing_create_diff(event: Event) -> CalendarDiff {
CalendarDiff::from_changes(vec![EventChange::Create(event)], vec![])
}
pub fn outgoing_update_diff(from: Event, to: Event) -> CalendarDiff {
CalendarDiff::from_changes(vec![EventChange::Update { from, to }], vec![])
}
pub fn outgoing_delete_diff(event: Event) -> CalendarDiff {
CalendarDiff::from_changes(vec![EventChange::Delete(event)], vec![])
}
pub fn incoming_create_diff(event: Event) -> CalendarDiff {
CalendarDiff::from_changes(vec![], vec![EventChange::Create(event)])
}
pub fn incoming_update_diff(from: Event, to: Event) -> CalendarDiff {
CalendarDiff::from_changes(vec![], vec![EventChange::Update { from, to }])
}
pub fn incoming_delete_diff(event: Event) -> CalendarDiff {
CalendarDiff::from_changes(vec![], vec![EventChange::Delete(event)])
}
pub fn test_provider(slug: &str) -> (TempDir, Provider) {
let (tmp, bin_path) = test_binary(&format!("caldir-provider-{slug}"));
let provider = Provider::from_binary_path(bin_path).unwrap();
(tmp, provider)
}
pub fn test_binary(filename: &str) -> (TempDir, PathBuf) {
let tmp = TempDir::new().unwrap();
let path = tmp
.path()
.join(format!("{}{}", filename, std::env::consts::EXE_SUFFIX));
std::fs::write(&path, b"").unwrap();
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = std::fs::metadata(&path).unwrap().permissions();
perms.set_mode(0o755);
std::fs::set_permissions(&path, perms).unwrap();
}
(tmp, path)
}