holger-cli/tests/b1_prepare_has_no_default_verdict.rs
//! B1, the producer half: `holger-cli bundle prepare` has no default verdict.
//!
//! Before the fix `--verdict` defaulted to "pass", so a candidate nobody reviewed
//! was recorded as passed. Now the operator must state the verdict, and a
//! candidate prepared without one is never written.
use std::process::Command;
const BIN: &str = env!("CARGO_BIN_EXE_holger-cli");
fn prepare(dir: &std::path::Path, verdict: Option<&str>) -> std::process::Output {
let payload = dir.join("fw.bin");
std::fs::write(&payload, b"firmware").unwrap();
let mut cmd = Command::new(BIN);
cmd.args(["bundle", "prepare"])
.arg("--candidate")
.arg(dir.join("cand"))
.args(["--bundle-id", "b-1", "--sequence", "1"])
.args([
"--supplier",
"ACME",
"--product",
"Drive",
"--release-version",
"1.0.0",
])
.arg("--payload")
.arg(&payload);
if let Some(v) = verdict {
cmd.args(["--verdict", v]);
}
cmd.output().unwrap()
}
#[test]
fn prepare_without_a_verdict_is_refused_and_writes_nothing() {
let dir = tempfile_dir();
let out = prepare(&dir, None);
let err = String::from_utf8_lossy(&out.stderr);
assert!(
!out.status.success(),
"prepare must not invent a verdict; it succeeded:\n{err}"
);
assert!(
err.contains("--verdict"),
"the refusal must name --verdict:\n{err}"
);
assert!(
!dir.join("cand").exists(),
"a refused prepare wrote a candidate"
);
}
#[test]
fn prepare_with_a_stated_verdict_records_it() {
let dir = tempfile_dir();
let out = prepare(&dir, Some("block"));
assert!(
out.status.success(),
"{}",
String::from_utf8_lossy(&out.stderr)
);
let core = std::fs::read_to_string(dir.join("cand").join("core.json")).unwrap();
assert!(
core.contains("\"verdict\": \"block\"") || core.contains("\"verdict\":\"block\""),
"{core}"
);
}
/// A fresh directory under the target dir (no tempfile dev-dependency here).
fn tempfile_dir() -> std::path::PathBuf {
use std::sync::atomic::{AtomicU32, Ordering};
static N: AtomicU32 = AtomicU32::new(0);
let d = std::env::temp_dir().join(format!(
"holger-b1-{}-{}",
std::process::id(),
N.fetch_add(1, Ordering::SeqCst)
));
let _ = std::fs::remove_dir_all(&d);
std::fs::create_dir_all(&d).unwrap();
d
}