crates/monetize-server/src/estate_order/tests/lifecycle_words.rs
//! ★ **An order is told in its product's OWN words** (owner 2026-10-17: nothing Gunnar in
//! the core): the buyer's view of every phase speaks of the product as its lifecycle names it,
//! and Gunnar's view is the sentence it always was.
use super::*;
#[test]
fn the_buyer_reads_an_order_in_its_products_own_words() {
let r = rig("own-words");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
let solo = lifecycle::ProductWords {
name: "solo".into(),
title: "Solo".into(),
account_home: "solo.example".into(),
};
let gunnar = crate::testing::lifecycles::gunnar_words();
let (state, words, _) = run.customer_view_as("gunnar.rs", &solo);
assert_eq!(state, "ready");
assert!(
words.starts_with("Your Solo is ready at https://acme.gunnar.rs"),
"{words}"
);
assert!(
run.customer_view_as("gunnar.rs", &gunnar)
.1
.starts_with("Your Gunnar is ready"),
"Gunnar's sentence as it always was"
);
for p in [
phase::HELD,
phase::INSTALLING,
phase::GRACE,
phase::SUSPENDED,
phase::TERMINATING,
phase::TERMINATED,
phase::DELETED,
phase::OWED,
phase::FAILED,
] {
let at = EstateRun {
phase: p.to_string(),
..run.clone()
};
let (_, said, _) = at.customer_view_as("gunnar.rs", &solo);
assert!(
said.contains("Solo") && !said.contains("Gunnar"),
"{p}: {said}"
);
let (_, op, _) = at.operator_view_as("gunnar.rs", &solo);
assert!(!op.contains("Gunnar"), "{p}: {op}");
}
}
/// ★ **The buyer's view of every phase says buyer words only** (lane BUYFLOW-4: the paid page and
/// the renew page show these sentences): never the operator's machinery — lay, estate, guest,
/// operator, cap, monetize (monetize-site-buy `rules::OPERATOR_WORDS`).
#[test]
fn the_buyers_view_of_every_phase_names_no_operator_machinery() {
const OPERATOR_WORDS: &[&str] = &[
"lay",
"lays",
"laid",
"laying",
"estate",
"estates",
"guest",
"guests",
"operator",
"operators",
"cap",
"caps",
"monetize",
"tenant",
"tenants",
"appliance",
"vendor",
"vendors",
"ignalina",
];
let r = rig("buyer-words");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
let run = r.state.estates.get("acme").unwrap();
let words = crate::testing::lifecycles::gunnar_words();
let phases = [
phase::ORDERED,
phase::HELD,
phase::WAITING_DNS,
phase::LAYING,
phase::INSTALLING,
phase::PAIRED,
phase::CAPTURED,
phase::FAILED,
phase::RELEASED,
phase::GRACE,
phase::SUSPENDED,
phase::DELETING,
phase::DELETED,
phase::OWED,
phase::REFUNDED,
phase::TERMINATING,
phase::TERMINATED,
];
for p in phases {
for (captured_at_ms, delete_on_ms) in [(0, 0), (1, 0), (1, 1_800_000_000_000)] {
let at = EstateRun {
phase: p.to_string(),
captured_at_ms,
delete_on_ms,
..run.clone()
};
let (_, said, _) = at.customer_view_as("gunnar.rs", &words);
let lower = said.to_lowercase();
let named: Vec<&str> = lower
.split(|c: char| !c.is_alphanumeric())
.filter(|w| OPERATOR_WORDS.contains(w))
.collect();
assert!(
named.is_empty() && !lower.contains("one box"),
"{p}: a buyer reads {named:?}: {said}"
);
}
}
}