mod scheduler_flaw_test {
use std::sync::Arc;
use chrono::{Utc, Duration};
use crate::memory::embeddings::EmbeddingService;
use crate::state::SqliteStateStore;
use crate::traits::{Goal, GoalSchedule, StateStore};
#[tokio::test]
async fn test_scheduler_ignores_utc_timezone() {
let db_file = tempfile::NamedTempFile::new().unwrap();
let embedding_service = Arc::new(EmbeddingService::new().unwrap());
let state: Arc<dyn StateStore> = Arc::new(
SqliteStateStore::new(
db_file.path().to_str().unwrap(),
100,
None,
embedding_service,
)
.await
.unwrap(),
);
let goal = Goal::new_continuous("UTC Test Goal", "test-session", None, None);
state.create_goal(&goal).await.unwrap();
let now = Utc::now();
let now_ts = now.to_rfc3339();
let due_ts = (now - Duration::minutes(5)).to_rfc3339();
let schedule = GoalSchedule {
id: uuid::Uuid::new_v4().to_string(),
goal_id: goal.id.clone(),
cron_expr: "* * * * *".to_string(),
tz: "UTC".to_string(), original_schedule: Some("every minute".to_string()),
fire_policy: "always_fire".to_string(),
is_one_shot: false,
is_paused: false,
last_run_at: None,
next_run_at: due_ts,
created_at: now_ts.clone(),
updated_at: now_ts,
};
let result = state.create_goal_schedule(&schedule).await;
assert!(
result.is_err(),
"UTC timezone should be rejected at schedule creation time"
);
let err_msg = result.unwrap_err().to_string();
assert!(
err_msg.contains("tz='local'"),
"Error message should mention tz='local' requirement, got: {}",
err_msg
);
}
}