use super::stop_common::{git_run, lernie_bin, repo_git, scaffold_repo, write_global_models};
use std::fs;
use std::process::{Command, Stdio};
use tempfile::TempDir;
fn stale_agent(dest: &std::path::Path, id: &str) {
let repo = repo_git(dest);
let wt = dest.join("agents").join(id);
let wt_str = wt.to_string_lossy().to_string();
let branch = format!("agents/{id}");
git_run(
&repo,
&[
"worktree",
"add",
"-b",
branch.as_str(),
wt_str.as_str(),
"config/default",
],
);
fs::write(wt.join("goal.md"), "g").unwrap();
git_run(&wt, &["add", "goal.md"]);
git_run(
&wt,
&[
"-c",
"user.email=t@e",
"-c",
"user.name=T",
"commit",
"-m",
"dispatch",
],
);
git_run(&repo, &["worktree", "remove", "--force", wt_str.as_str()]);
}
#[test]
fn stop_on_branch_with_no_live_writer_is_idempotent_success() {
let holder = TempDir::new().unwrap();
let harness = holder.path().join("harness");
fs::create_dir_all(&harness).unwrap();
write_global_models(&harness);
let dest = holder.path().join("conv");
scaffold_repo(&dest, &harness);
stale_agent(&dest, "20260101-st22");
let stop_out = Command::new(lernie_bin())
.arg("stop")
.arg(&dest)
.arg("20260101-st22")
.stderr(Stdio::piped())
.output()
.expect("spawn lernie stop");
assert!(
stop_out.status.success(),
"lernie stop must succeed idempotently: {}",
String::from_utf8_lossy(&stop_out.stderr)
);
}
#[test]
fn stop_stop_children_flag_parses_and_is_idempotent() {
let holder = TempDir::new().unwrap();
let harness = holder.path().join("harness");
fs::create_dir_all(&harness).unwrap();
write_global_models(&harness);
let dest = holder.path().join("conv");
scaffold_repo(&dest, &harness);
stale_agent(&dest, "20260101-st77");
let stop_out = Command::new(lernie_bin())
.arg("stop")
.arg(&dest)
.arg("20260101-st77")
.arg("--stop-children")
.stderr(Stdio::piped())
.output()
.expect("spawn lernie stop --stop-children");
assert!(
stop_out.status.success(),
"lernie stop --stop-children must succeed idempotently: {}",
String::from_utf8_lossy(&stop_out.stderr)
);
}
#[test]
fn stop_on_missing_branch_errors() {
let holder = TempDir::new().unwrap();
let harness = holder.path().join("harness");
fs::create_dir_all(&harness).unwrap();
write_global_models(&harness);
let dest = holder.path().join("conv");
scaffold_repo(&dest, &harness);
let out = Command::new(lernie_bin())
.arg("stop")
.arg(&dest)
.arg("does-not-exist")
.stderr(Stdio::piped())
.output()
.expect("spawn lernie stop");
assert!(!out.status.success(), "expected nonzero exit");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
stderr.contains("does-not-exist") && stderr.contains("does not exist"),
"got: {stderr}"
);
}
#[test]
fn stop_refuses_the_retired_per_conversation_layout() {
let holder = TempDir::new().unwrap();
let dest = holder.path().join("old-conv");
fs::create_dir_all(dest.join("root/.git")).unwrap();
fs::write(dest.join("providers.yaml"), "roles: {}\n").unwrap();
let out = Command::new(lernie_bin())
.arg("stop")
.arg(&dest)
.arg("20260101-x1")
.stderr(Stdio::piped())
.output()
.expect("spawn lernie stop");
assert!(!out.status.success(), "expected nonzero exit");
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(
stderr.contains("retired per-conversation layout") && stderr.contains("lernie new"),
"got: {stderr}"
);
}