//! `HIVE_FORGE_URL` has no default: unset or empty is a clear error naming //! the variable, and a set value is the URL the client dials. use std::process::{Command, Output}; const UNSET_MSG: &str = "HIVE_FORGE_URL is unset or empty"; fn scratch_state_dir(tag: &str) -> std::path::PathBuf { let ts = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .map_or(0, |d| d.as_nanos()); let dir = std::env::temp_dir().join(format!("hive-forge-url-required-{tag}-{ts}")); std::fs::create_dir_all(&dir).expect("create scratch state dir"); std::fs::write(dir.join("forge-token"), "test-token\n").expect("seed forge-token"); dir } fn run(tag: &str, url: Option<&str>) -> Output { let mut cmd = Command::new(env!("CARGO_BIN_EXE_hive-forge")); cmd.args(["-r", "o/r", "pr", "edit", "7", "--title", "t"]) .env("HYPERHIVE_STATE_DIR", scratch_state_dir(tag)) .env_remove("HIVE_FORGE_TOKEN_FILE") .env_remove("HIVE_LABEL"); match url { Some(u) => cmd.env("HIVE_FORGE_URL", u), None => cmd.env_remove("HIVE_FORGE_URL"), }; cmd.output().expect("run hive-forge") } #[test] fn unset_url_is_a_clear_error() { let out = run("unset", None); let stderr = String::from_utf8_lossy(&out.stderr); assert!(!out.status.success()); assert!(stderr.contains(UNSET_MSG), "stderr: {stderr}"); assert!(!stderr.contains("localhost"), "stderr: {stderr}"); } #[test] fn empty_url_is_a_clear_error() { let out = run("empty", Some("")); let stderr = String::from_utf8_lossy(&out.stderr); assert!(!out.status.success()); assert!(stderr.contains(UNSET_MSG), "stderr: {stderr}"); } /// Presence control: a set value passes the URL check and the client dials it /// (nothing listens on port 1, so the failure is a connection error). #[test] fn set_url_is_used_as_is() { let out = run("set", Some("http://127.0.0.1:1")); let stderr = String::from_utf8_lossy(&out.stderr); assert!(!out.status.success()); assert!(!stderr.contains(UNSET_MSG), "stderr: {stderr}"); assert!(stderr.contains("127.0.0.1"), "stderr: {stderr}"); }