use crate::config::profile::with_home_override_async;
use crate::cron::scheduler::cron_session_title_suffix;
use crate::db::{Database, models::CronJob};
use crate::services::{ServiceContext, SessionService};
use uuid::Uuid;
async fn test_ctx() -> ServiceContext {
let db = Database::connect_in_memory().await.unwrap();
db.run_migrations().await.unwrap();
ServiceContext::new(db.pool().clone())
}
fn make_job(name: &str) -> CronJob {
CronJob::new(
name.to_string(),
"0 9 * * *".to_string(),
"UTC".to_string(),
"do things".to_string(),
None,
None,
"off".to_string(),
true,
None,
None,
)
}
#[tokio::test]
async fn different_jobs_get_different_sessions() {
let dir = tempfile::tempdir().expect("tempdir");
let home = dir.path().join(".opencrabs");
std::fs::create_dir_all(&home).expect("create home");
with_home_override_async(home, async {
let ctx = test_ctx().await;
let job_a = make_job("job-a");
let job_b = make_job("job-b");
let sid_a = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job_a)
.await
.expect("resolve session for job-a");
let sid_b = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job_b)
.await
.expect("resolve session for job-b");
assert_ne!(
sid_a, sid_b,
"two different jobs resolved the SAME session — #149 cross-pollination is back"
);
})
.await;
}
#[tokio::test]
async fn same_job_reuses_its_session() {
let dir = tempfile::tempdir().expect("tempdir");
let home = dir.path().join(".opencrabs");
std::fs::create_dir_all(&home).expect("create home");
with_home_override_async(home, async {
let ctx = test_ctx().await;
let job = make_job("recurring-job");
let first = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job)
.await
.expect("first resolve");
let second = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job)
.await
.expect("second resolve");
assert_eq!(first, second, "same job must reuse its own session");
})
.await;
}
#[tokio::test]
async fn renamed_session_still_resolves_by_suffix() {
let dir = tempfile::tempdir().expect("tempdir");
let home = dir.path().join(".opencrabs");
std::fs::create_dir_all(&home).expect("create home");
with_home_override_async(home, async {
let ctx = test_ctx().await;
let job = make_job("renamed-job");
let original = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job)
.await
.expect("initial resolve");
let session_svc = SessionService::new(ctx.clone());
let mut session = session_svc
.get_session(original)
.await
.expect("get session")
.expect("session exists");
session.title = Some(format!(
"Renamed by user {}",
cron_session_title_suffix(&job)
));
session_svc
.update_session(&session)
.await
.expect("rename session");
let resolved = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job)
.await
.expect("resolve after rename");
assert_eq!(
resolved, original,
"renaming the title part must not orphan the job's session"
);
})
.await;
}
#[tokio::test]
async fn same_name_different_ids_get_different_sessions() {
let dir = tempfile::tempdir().expect("tempdir");
let home = dir.path().join(".opencrabs");
std::fs::create_dir_all(&home).expect("create home");
with_home_override_async(home, async {
let ctx = test_ctx().await;
let job_a = make_job("twin");
let mut job_b = make_job("twin");
job_b.id = Uuid::new_v4();
assert_ne!(job_a.id, job_b.id, "test setup: ids must differ");
let sid_a = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job_a)
.await
.expect("resolve twin-a");
let sid_b = crate::cron::scheduler::resolve_or_create_cron_session(&ctx, &job_b)
.await
.expect("resolve twin-b");
assert_ne!(sid_a, sid_b, "same-name jobs must not share a session");
})
.await;
}