crates/monetize-server/src/estate_order/tests/update_offer.rs
//! ★ **The Sites page's update offer** (owner 2026-10-17, test2 live): an estate that runs the
//! release sold now is UP TO DATE and offered no button; the button is offered only for a newer
//! release that carries a way to update every box (a keep medium, or a live app while live is
//! on), and when not, why — in plain words, no internal names; each box has a line, the front
//! that never asked for an update says so; a release is named by its note, not its hash.
use super::*;
#[test]
fn an_estate_on_the_release_sold_is_up_to_date_and_offered_nothing() {
let r = delivered("offer-current", release_cfg("02", true));
let cfg = r.state.estates.cfg.clone().unwrap();
let run = r.state.estates.get("acme").unwrap();
let o = update::offer(&run, &cfg);
assert!(o.up_to_date && !o.offered, "{o:?}");
assert_eq!(
o.boxes
.iter()
.map(|b| (b.role.as_str(), b.state.as_str()))
.collect::<Vec<_>>(),
vec![
("twin", "current"),
("main", "current"),
("front", "current")
],
"{o:?}"
);
// The refusal a press would get says it plainly.
let e = update::start(&r.state, "acme", "", "operator").unwrap_err();
assert!(
matches!(&e, sold::SoldRefusal::Refused(w) if w.contains("up to date") && !w.contains('`')),
"{e:?}"
);
}
#[test]
fn a_newer_release_is_offered_only_when_it_carries_a_way_for_every_box() {
let r = delivered("offer-newer", release_cfg("02", true));
laid_older(&r);
let mut cfg = r.state.estates.cfg.clone().unwrap();
let run = r.state.estates.get("acme").unwrap();
let o = update::offer(&run, &cfg);
assert!(!o.up_to_date && o.offered && o.why_not.is_empty(), "{o:?}");
assert!(
o.boxes
.iter()
.all(|b| b.state == "behind" && b.words.contains("00-old")),
"{o:?}"
);
// No keep medium and no live app: nothing offered, said plainly.
cfg.media.remove(KEEP_MEDIUM);
cfg.live_apps.clear();
let o = update::offer(&run, &cfg);
assert!(!o.up_to_date && !o.offered, "{o:?}");
assert!(
o.why_not
.starts_with("No newer release with update media is published yet")
&& !o.why_not.contains('`')
&& !o.why_not.contains("gunnar-keep"),
"{}",
o.why_not
);
}
#[test]
fn a_box_that_never_reported_says_so_and_the_front_says_the_update_starts_with_it() {
let r = delivered("offer-unreported", release_cfg("02", true));
let cfg = r.state.estates.cfg.clone().unwrap();
let mut run = r.state.estates.get("acme").unwrap();
run.release_of.remove("front");
run.update_taken_at_ms = 0;
let o = update::offer(&run, &cfg);
let front = o
.boxes
.iter()
.find(|b| b.role == "front")
.expect("every role has a line");
assert_eq!(front.state, "not-reported");
assert_eq!(
front.words,
"not reported yet — the front has no update taker yet; the update starts with the front"
);
run.release_of.remove("twin");
let o = update::offer(&run, &cfg);
assert_eq!(
o.boxes.iter().find(|b| b.role == "twin").unwrap().words,
"not reported yet"
);
}
#[test]
fn a_release_is_named_by_its_note() {
let mut cfg = release_cfg("02", true);
assert_eq!(
update::release_name(&cfg, "02-gunnar"),
"",
"no note: the page shows the short id"
);
cfg.release_notes.insert(
"02-gunnar".into(),
update::ReleaseNote {
label: "r5.4".into(),
built: "2026-10-17".into(),
carries: [
("gunnar".to_string(), "aa14357b1234".to_string()),
("gunnar-ui".to_string(), "f4b5d44abc".to_string()),
]
.into(),
},
);
assert_eq!(
update::release_name(&cfg, "02-gunnar"),
"r5.4 · 2026-10-17 · gunnar aa14357 · gunnar-ui f4b5d44"
);
}
/// ★ **A release fed after the start is named** (owner 2026-10-18: test2's page said only
/// "e7fad415b19a"): a site's `[estates.<site>.orders]` carries `release_notes` beside its media
/// (read live; the shop's `[estate_orders]` is read only at a start), and the site's terms name
/// the release by them; the site's terms, media and notes go over the shop's.
#[test]
fn a_sites_own_release_notes_name_the_release_its_terms_sell() {
let o: crate::config::SiteOrders = toml::from_str(&format!("term_days = 1\n[media_objects.gunnar]\nurl = \"https://objsto.example/release/gunnar/e7.iso\"\nsha256 = \"{a}\"\nbytes = 9\n[release_notes.\"{a}\"]\nlabel = \"r5.4 N\"\nbuilt = \"2026-10-17\"\ncarries = {{ gunnar = \"f16173ef\" }}\n", a = "e".repeat(64))).expect("a site's orders take release notes");
let mut c = release_cfg("02", true);
apply_site_orders(&mut c, &o);
assert_eq!(c.term_days, 1);
assert_eq!(
super::release_id(&c, "gunnar"),
"e".repeat(64),
"the site's media"
);
assert_eq!(
update::release_name(&c, &"e".repeat(64)),
"r5.4 N · 2026-10-17 · gunnar f16173e"
);
}