crates/monetize-admin/tests/front_certs_cli.rs
//! ★ **A product front's REAL certificate report, said by `monetize front certs`** (A7).
//! Holger's front (`/front/certs`) and Gunnar's (`/api/front/certs`) answer with edda
//! estate-front's `web::status::report_json` (Gunnar's front a port of it); the CLI prints each
//! certificate's host, its names and every line the front wrote, and decides nothing. Here
//! the report is estate-front's own, over a data root where one name failed a validation, one
//! is waiting on DNS-free ACME, and one was never tried; the CLI's own test
//! (monetize-cli `tests/front_certs.rs`) drives the binary over TLS at both doors.
use std::time::SystemTime;
#[test]
fn the_fronts_real_report_is_said_by_the_cli_line_by_line() {
let dir = tempfile::tempdir().unwrap();
let now = SystemTime::now();
estate_front::web::acme::failed_as(
dir.path(),
"holger.example",
now,
estate_front::web::acme::FailKind::Validation,
);
estate_front::web::acme::failed_as(
dir.path(),
"gunnar.example",
now,
estate_front::web::acme::FailKind::Acme,
);
let report = estate_front::web::status::report_json(dir.path(), now);
let certs = report["certificates"]
.as_array()
.expect("the report lists certificates")
.clone();
assert!(certs.len() >= 2, "{report}");
let out =
monetize_cli::said(monetize_cli::What::BoxCerts, 200, &report.to_string()).expect("said");
for c in &certs {
let host = c["host"].as_str().unwrap();
assert!(
out.lines().any(|l| l.starts_with(host)),
"{host} heads its block: {out}"
);
for l in c["lines"]
.as_array()
.into_iter()
.flatten()
.filter_map(|l| l.as_str())
{
assert!(
out.contains(&format!(" {l}\n")),
"the front's line {l:?} is said as it wrote it: {out}"
);
}
}
let none = estate_front::web::status::report_json(tempfile::tempdir().unwrap().path(), now);
assert!(
monetize_cli::said(monetize_cli::What::BoxCerts, 200, &none.to_string())
.unwrap()
.contains("no certificate is known"),
"{none}"
);
}
/// ★ **tls-alert** (owner 2026-11-03, the test2 ONE box console, Sites → Certificates): the
/// box's name before its first feed (`monetize-admin`) stayed in the list after the feed and
/// alerted `tls.no-certificate` beside a valid certificate for test2.monetize.ignalina.dk. A
/// fed box with a valid certificate for its real host and a stale placeholder lists only the
/// real host and raises no alert — on the page, in the CLI, or in the alert mail.
#[test]
fn a_fed_box_with_a_valid_cert_and_a_stale_placeholder_raises_no_alert() {
use estate_front::web::{certs, status};
let dir = tempfile::tempdir().unwrap();
let root = dir.path();
let now = SystemTime::now();
let secs = now.duration_since(std::time::UNIX_EPOCH).unwrap().as_secs();
// The placeholder as the front wrote it before the first feed, its clock five hours old.
let mut pre = status::Record {
hosts: vec!["monetize-admin".into()],
..Default::default()
};
pre.said(Some(status::KIND_UNFED), Some("tls: nothing valid to serve yet, and the installer has fed nothing — ACME is not asked before the first feed (it names the directory and the hosts)".into()));
pre.no_certificate_since = Some(secs - 5 * 3600);
pre.save(root, "monetize-admin").unwrap();
let waiting = status::report_json(root, now);
assert_eq!(
waiting["certificates"][0]["alert"],
serde_json::Value::Null,
"before the first feed: no alert {waiting}"
);
assert_eq!(
waiting["certificates"][0]["lines"],
serde_json::json!(["waiting for the first feed"]),
"one plain state"
);
// Fed: the real host's certificate is valid.
let host = "test2.monetize.example";
let (chain, key) = certs::self_signed(&[host], 90);
let c = certs::Cert::parse(host, &chain, &key, now).unwrap();
certs::keep(root, host, &c).unwrap();
status::Record {
hosts: vec![host.into()],
..Default::default()
}
.save(root, host)
.unwrap();
let report = status::report_json(root, now);
let hosts: Vec<&str> = report["certificates"]
.as_array()
.unwrap()
.iter()
.filter_map(|c| c["host"].as_str())
.collect();
assert_eq!(hosts, vec![host], "the placeholder left the list: {report}");
assert!(
report["certificates"]
.as_array()
.unwrap()
.iter()
.all(|c| c["alert"].is_null()),
"{report}"
);
let out = monetize_cli::said(monetize_cli::What::BoxCerts, 200, &report.to_string()).unwrap();
assert!(
!out.contains("ALERT") && !out.contains("monetize-admin") && !out.contains("unix "),
"{out}"
);
}