Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/monetize

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}"
            );
        }
    }
}