use anyhow::Result;
use ralph::contracts::TaskStatus;
mod test_support;
#[test]
fn task_edit_lists_archived_task_ids_in_output() -> Result<()> {
let dir = test_support::temp_dir_outside_repo();
test_support::git_init(dir.path())?;
test_support::seed_ralph_dir(dir.path())?;
let config = r#"{
"version": 2,
"queue": {
"auto_archive_terminal_after_days": 0
}
}"#;
std::fs::write(dir.path().join(".ralph/config.jsonc"), config)?;
let todo_task = test_support::make_test_task("RQ-0001", "Todo task", TaskStatus::Todo);
let mut done_task = test_support::make_test_task("RQ-0002", "Done task", TaskStatus::Done);
let mut rejected_task =
test_support::make_test_task("RQ-0003", "Rejected task", TaskStatus::Rejected);
done_task.completed_at = Some("2026-01-01T00:00:00Z".to_string());
rejected_task.completed_at = Some("2026-01-02T00:00:00Z".to_string());
test_support::write_queue(dir.path(), &[todo_task, done_task, rejected_task])?;
test_support::write_done(dir.path(), &[])?;
let (status, stdout, stderr) = test_support::run_in_dir(
dir.path(),
&["task", "edit", "title", "Updated title", "RQ-0001"],
);
anyhow::ensure!(
status.success(),
"task edit failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
let output = format!("{}\n{}", stdout, stderr);
anyhow::ensure!(
output.contains("Auto-archived"),
"expected 'Auto-archived' in output, got:\n{output}"
);
anyhow::ensure!(
output.contains("RQ-0002"),
"expected 'RQ-0002' in output, got:\n{output}"
);
anyhow::ensure!(
output.contains("RQ-0003"),
"expected 'RQ-0003' in output, got:\n{output}"
);
let queue = test_support::read_queue(dir.path())?;
let done = test_support::read_done(dir.path())?;
anyhow::ensure!(
queue.tasks.len() == 1 && queue.tasks[0].id == "RQ-0001",
"expected only RQ-0001 in queue, got: {:?}",
queue.tasks.iter().map(|t| &t.id).collect::<Vec<_>>()
);
anyhow::ensure!(
done.tasks.iter().any(|t| t.id == "RQ-0002"),
"RQ-0002 should be in done.json"
);
anyhow::ensure!(
done.tasks.iter().any(|t| t.id == "RQ-0003"),
"RQ-0003 should be in done.json"
);
Ok(())
}
#[test]
fn task_edit_no_auto_archive_flag_prevents_archiving() -> Result<()> {
let dir = test_support::temp_dir_outside_repo();
test_support::git_init(dir.path())?;
test_support::seed_ralph_dir(dir.path())?;
let config = r#"{
"version": 2,
"queue": {
"auto_archive_terminal_after_days": 0
}
}"#;
std::fs::write(dir.path().join(".ralph/config.jsonc"), config)?;
let todo_task = test_support::make_test_task("RQ-0001", "Todo task", TaskStatus::Todo);
let mut done_task = test_support::make_test_task("RQ-0002", "Done task", TaskStatus::Done);
let mut rejected_task =
test_support::make_test_task("RQ-0003", "Rejected task", TaskStatus::Rejected);
done_task.completed_at = Some("2026-01-01T00:00:00Z".to_string());
rejected_task.completed_at = Some("2026-01-02T00:00:00Z".to_string());
test_support::write_queue(dir.path(), &[todo_task, done_task, rejected_task])?;
test_support::write_done(dir.path(), &[])?;
let (status, stdout, stderr) = test_support::run_in_dir(
dir.path(),
&[
"task",
"edit",
"--no-auto-archive",
"title",
"Updated title",
"RQ-0001",
],
);
anyhow::ensure!(
status.success(),
"task edit with --no-auto-archive failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
let output = format!("{}\n{}", stdout, stderr);
anyhow::ensure!(
!output.contains("Auto-archived"),
"expected no 'Auto-archived' in output when using --no-auto-archive, got:\n{output}"
);
let queue = test_support::read_queue(dir.path())?;
let done = test_support::read_done(dir.path())?;
anyhow::ensure!(
queue.tasks.len() == 3,
"expected 3 tasks in queue with --no-auto-archive, got: {}",
queue.tasks.len()
);
anyhow::ensure!(
done.tasks.is_empty(),
"expected done.json to be empty with --no-auto-archive, got: {:?}",
done.tasks.iter().map(|t| &t.id).collect::<Vec<_>>()
);
Ok(())
}
#[test]
fn task_edit_no_archive_message_when_no_terminal_tasks() -> Result<()> {
let dir = test_support::temp_dir_outside_repo();
test_support::git_init(dir.path())?;
test_support::seed_ralph_dir(dir.path())?;
let config = r#"{
"version": 2,
"queue": {
"auto_archive_terminal_after_days": 0
}
}"#;
std::fs::write(dir.path().join(".ralph/config.jsonc"), config)?;
let todo_task = test_support::make_test_task("RQ-0001", "Todo task", TaskStatus::Todo);
let doing_task = test_support::make_test_task("RQ-0002", "Doing task", TaskStatus::Doing);
test_support::write_queue(dir.path(), &[todo_task, doing_task])?;
test_support::write_done(dir.path(), &[])?;
let (status, stdout, stderr) = test_support::run_in_dir(
dir.path(),
&["task", "edit", "title", "Updated title", "RQ-0001"],
);
anyhow::ensure!(
status.success(),
"task edit failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
let output = format!("{}\n{}", stdout, stderr);
anyhow::ensure!(
!output.contains("Auto-archived"),
"expected no 'Auto-archived' when no terminal tasks, got:\n{output}"
);
Ok(())
}
#[test]
fn task_edit_help_includes_no_auto_archive_flag() -> Result<()> {
let dir = test_support::temp_dir_outside_repo();
test_support::git_init(dir.path())?;
test_support::seed_ralph_dir(dir.path())?;
let (status, stdout, stderr) =
test_support::run_in_dir(dir.path(), &["task", "edit", "--help"]);
anyhow::ensure!(
status.success(),
"task edit --help failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
let output = format!("{}\n{}", stdout, stderr);
anyhow::ensure!(
output.contains("--no-auto-archive"),
"expected --no-auto-archive in help output, got:\n{output}"
);
anyhow::ensure!(
output.contains("auto-archive") || output.contains("auto_archive"),
"expected auto-archive mention in help output, got:\n{output}"
);
Ok(())
}