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/tests/paid_signup.rs

//! **The paid-signup seam over its real wires**: the vendor's HTTP webhook into
//! `POST /callback/mockpay`, and the return page's `Signup.Status` over gRPC
//! with a bearer, against the same in-memory store.
//!
//! The unit half — the store's idempotency, each named refusal, the retry and
//! the 24 h ceiling — is in `monetize_server::signup::tests`. This file proves
//! the two ends meet: that a verified signup never touches the ledger, that the
//! vendor is answered **200 in every verified case** (a 5xx buys days of Stripe
//! retries and then a disabled endpoint), and that a page polling before the
//! webhook lands gets `UNKNOWN` rather than an error it would have to
//! special-case.

use std::sync::Arc;

use monetize_pay::{Currency, Money, PaidSignup};
use monetize_proto::signup_admin_client::SignupAdminClient;
use monetize_proto::signup_client::SignupClient;
use monetize_proto::signup_status_response::State;
use monetize_proto::{self as pb};
use monetize_server::config::SignupPlan;
use monetize_server::registry::Registry;
use monetize_server::state::AppState;
use monetize_server::testing::{http_post, CallbackPay, TestServer};
use tonic::metadata::MetadataValue;
use tonic::transport::Channel;
use tonic::{Code, Request};

const BEARER: &str = "test-bearer-token-of-sufficient-length";
const SECRET: &str = "mockpay-shared-secret";
const PLAN: &str = "gunnar/10gb-1m";

struct Rig {
    pay: CallbackPay,
    state: Arc<AppState>,
    server: TestServer,
    channel: Channel,
    /// The selling rigs' sink, for the mail it was handed.
    sink: Option<Arc<HoldingSink>>,
}

impl Rig {
    async fn up() -> Rig {
        let pay = CallbackPay::new(SECRET);
        let mut state = AppState::in_memory(Registry::new().sells("gunnar", pay.clone()));
        // The plan table an operator wrote in `monetize.toml`. The open build's
        // `LoudSink` is the default sink and stays: this file is about the
        // wires, and the sink's own answers are the unit tests' business.
        state.signup_plans = [(
            PLAN.to_string(),
            SignupPlan { amount_minor: 10_000, currency: Currency::Sek, cap_bytes: 10_737_418_240, period_days: 30 },
        )]
        .into();
        let state = Arc::new(state);
        let server = TestServer::spawn(state.clone(), BEARER).await;
        let channel = Channel::from_shared(server.endpoint()).unwrap().connect().await.expect("connect");
        Rig { pay, state, server, channel, sink: None }
    }

    fn signup_client(&self) -> SignupClient<tonic::service::interceptor::InterceptedService<Channel, impl tonic::service::Interceptor>> {
        let bearer: MetadataValue<_> = format!("Bearer {BEARER}").parse().unwrap();
        SignupClient::with_interceptor(self.channel.clone(), move |mut r: Request<()>| {
            r.metadata_mut().insert("authorization", bearer.clone());
            Ok(r)
        })
    }

    fn admin_client(&self) -> SignupAdminClient<tonic::service::interceptor::InterceptedService<Channel, impl tonic::service::Interceptor>> {
        let bearer: MetadataValue<_> = format!("Bearer {BEARER}").parse().unwrap();
        SignupAdminClient::with_interceptor(self.channel.clone(), move |mut r: Request<()>| {
            r.metadata_mut().insert("authorization", bearer.clone());
            Ok(r)
        })
    }

    /// The vendor POSTs a verified signup for a checkout THIS box minted (`Signup.Start`
    /// keeps it, ST-7). Returns `(status, body)`.
    fn deliver(&self, s: &PaidSignup) -> (u16, String) {
        self.state.signups.record_minted(&s.vendor, &s.session, None).expect("minted");
        self.deliver_unminted(s)
    }

    /// The vendor POSTs a verified signup this box never minted.
    fn deliver_unminted(&self, s: &PaidSignup) -> (u16, String) {
        http_post(self.server.addr, "/callback/mockpay", &self.pay.signed_headers(), &CallbackPay::signup_body(s)).expect("the webhook answers")
    }
}

fn a_signup(session: &str, username: &str) -> PaidSignup {
    PaidSignup {
        vendor: "mockpay".into(),
        session: session.into(),
        reference: "pi_1".into(),
        email: "bob@example.com".into(),
        username: username.into(),
        product: "gunnar".into(),
        plan: PLAN.into(),
        amount: Money { minor: 10_000, currency: Currency::Sek },
        // No tax registration when this fixture was written: the vendor took the
        // plan price and nothing on top, so gross and net are the same number.
        tax: Money { minor: 0, currency: Currency::Sek },
        paid_at_unix_ms: 1_788_436_800_000,
        customer_country: None,
    }
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_verified_signup_webhook_creates_the_customer_and_the_return_page_reads_it() {
    let rig = Rig::up().await;
    let s = a_signup("cs_live", "bob");

    // The page polls FIRST — the redirect regularly beats the webhook.
    let early = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_live".into() }).await.expect("UNKNOWN is not an error");
    assert_eq!(early.into_inner().state(), State::Unknown);

    let (code, body) = rig.deliver(&s);
    assert_eq!(code, 200, "{body}");
    assert!(body.contains("\"state\":\"CREATED\""), "{body}");

    let out = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_live".into() }).await.unwrap().into_inner();
    assert_eq!(out.state(), State::Created);
    assert_eq!(out.username, "bob");
    assert_eq!(out.namespace, "bob");
    assert_eq!(out.plan, PLAN);
    assert_eq!(out.product, "gunnar");
    assert_eq!(out.paid_at_unix_ms, 1_788_436_800_000);
    assert!(out.reason.is_empty(), "a created signup carries no reason");

    // **The ledger was never touched.** A signup holds no reference and opens
    // no attempt; if it ever did, this is where it would show.
    assert!(rig.state.ledger.unfinished().unwrap().is_empty() && rig.state.ledger.recent(10).unwrap().is_empty());
    rig.server.stop().await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn the_same_session_delivered_twice_is_one_customer_and_two_200s() {
    let rig = Rig::up().await;
    let s = a_signup("cs_twice", "bob");
    let (first, _) = rig.deliver(&s);
    let (second, body) = rig.deliver(&s);
    assert_eq!((first, second), (200, 200), "a retry must never be a 5xx: {body}");
    assert!(body.contains("\"state\":\"CREATED\""), "{body}");
    assert_eq!(rig.state.signups.list(0).unwrap().len(), 1, "one payment, one row");
    rig.server.stop().await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_refused_signup_is_answered_200_and_the_reason_reaches_the_page() {
    let rig = Rig::up().await;
    let (code, body) = rig.deliver(&a_signup("cs_bad", "Bob!"));
    // 200, deliberately: the delivery succeeded and the answer is "no". A 5xx
    // here is how a Stripe endpoint gets retried for days and then disabled.
    assert_eq!(code, 200, "{body}");
    assert!(body.contains("\"state\":\"REFUSED\""), "{body}");

    let out = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_bad".into() }).await.unwrap().into_inner();
    assert_eq!(out.state(), State::Refused);
    assert!(out.reason.contains("Bob!"), "{}", out.reason);
    assert!(out.username.is_empty(), "a refused signup names no user on the return page");
    rig.server.stop().await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_plan_the_config_never_named_is_refused_over_the_wire() {
    let rig = Rig::up().await;
    let mut s = a_signup("cs_plan", "bob");
    s.plan = "gunnar/1tb-forever".into();
    let (code, _) = rig.deliver(&s);
    assert_eq!(code, 200);
    let out = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_plan".into() }).await.unwrap().into_inner();
    assert_eq!(out.state(), State::Refused);
    assert!(out.reason.contains("gunnar/1tb-forever") && out.reason.contains(PLAN), "{}", out.reason);
    rig.server.stop().await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn the_operator_sees_every_signup_and_every_refusal_and_whom_to_write_to() {
    let rig = Rig::up().await;
    rig.deliver(&a_signup("cs_ok", "bob"));
    rig.deliver(&a_signup("cs_no", "Bob!"));

    let rows = rig.admin_client().list(pb::ListSignupsRequest { limit: 0 }).await.unwrap().into_inner().signups;
    assert_eq!(rows.len(), 2);
    let refused = rows.iter().find(|r| r.session == "cs_no").expect("the refusal is listed");
    assert_eq!(refused.state(), State::Refused);
    // The console keeps the name the customer ASKED for: "the name was
    // rejected" is unreadable without the name.
    assert_eq!(refused.username, "Bob!");
    assert!(refused.namespace.is_empty());
    let created = rows.iter().find(|r| r.session == "cs_ok").expect("the sale is listed");
    assert_eq!(created.state(), State::Created);
    assert_eq!(created.amount, Some(pb::Money { minor: 10_000, currency: pb::Currency::Sek as i32 }));
    assert!(created.decided_at_unix_ms > 0);

    // The contact address rides with the account on the OPERATOR's wire…
    assert_eq!(created.email, "bob@example.com", "an account nobody can write to cannot be run");
    // …and never on the customer's unauthenticated poll.
    let polled = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_ok".into() }).await.unwrap().into_inner();
    assert!(!format!("{polled:?}").contains("bob@example.com"), "Signup.Status carried the e-mail");
    rig.server.stop().await;
}

/// **The resend door over the wire**: a session the store never saw is
/// NOT_FOUND; a created one on a sink that sends no mail (the open LoudSink) is
/// FAILED_PRECONDITION with the sink's own words — never a quiet "sent".
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn resend_welcome_names_why_it_sent_nothing() {
    let rig = Rig::up().await;
    rig.deliver(&a_signup("cs_ok", "bob"));
    let mut admin = rig.admin_client();
    let unknown = admin.resend_welcome(pb::ResendWelcomeRequest { vendor: "mockpay".into(), session: "cs_nobody".into(), force: false }).await.unwrap_err();
    assert_eq!(unknown.code(), Code::NotFound, "{unknown:?}");
    let no_mailer = admin.resend_welcome(pb::ResendWelcomeRequest { vendor: "mockpay".into(), session: "cs_ok".into(), force: false }).await.unwrap_err();
    assert_eq!(no_mailer.code(), Code::FailedPrecondition, "{no_mailer:?}");
    assert!(no_mailer.message().contains("sends no welcome mail"), "{}", no_mailer.message());
    rig.server.stop().await;
}

#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn signup_status_is_behind_the_same_bearer_as_every_other_service() {
    let rig = Rig::up().await;
    let mut naked = SignupClient::new(rig.channel.clone());
    let refused = naked.status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_live".into() }).await.expect_err("no bearer, no answer");
    assert_eq!(refused.code(), Code::Unauthenticated);
    rig.server.stop().await;
}

// ---------------------------------------------------------------------------
// Picking the name BEFORE the card, and renaming after it when the race bites.
// ---------------------------------------------------------------------------

/// **A sink that already has some customers.** The open `LoudSink` holds
/// nothing and can therefore never answer "taken", which is exactly the answer
/// these three verbs exist for.
struct HoldingSink {
    taken: std::sync::Mutex<Vec<String>>,
    /// Every notice it was handed to mail, in order.
    mailed: std::sync::Mutex<Vec<monetize_pay::CustomerNotice>>,
    /// Set: the relay does not take any mail.
    relay_down: std::sync::atomic::AtomicBool,
}

impl HoldingSink {
    fn with(names: &[&str]) -> std::sync::Arc<HoldingSink> {
        std::sync::Arc::new(HoldingSink { taken: std::sync::Mutex::new(names.iter().map(|n| (*n).to_owned()).collect()), mailed: Default::default(), relay_down: Default::default() })
    }
    fn holds(&self, name: &str) -> bool {
        self.taken.lock().unwrap().iter().any(|n| n == name)
    }
}

impl monetize_pay::SignupSink for HoldingSink {
    fn paid(&self, s: &PaidSignup) -> Result<monetize_pay::SignupOutcome, monetize_pay::SignupError> {
        if self.holds(&s.username) {
            return Err(monetize_pay::SignupError::NameTaken(format!(
                "username {:?} is taken on this appliance; the money is at the vendor and needs a refund BY HAND",
                s.username
            )));
        }
        self.taken.lock().unwrap().push(s.username.clone());
        Ok(monetize_pay::SignupOutcome::Created { namespace: s.username.clone(), username: s.username.clone() })
    }

    fn name_verdict(&self, username: &str) -> Result<monetize_pay::NameVerdict, monetize_pay::SignupError> {
        Ok(if self.holds(username) {
            monetize_pay::NameVerdict::Taken(format!("username {username:?} is taken"))
        } else {
            monetize_pay::NameVerdict::Free
        })
    }

    fn notify(&self, notice: &monetize_pay::CustomerNotice) -> Result<String, monetize_pay::SignupError> {
        if self.relay_down.load(std::sync::atomic::Ordering::SeqCst) {
            return Err(monetize_pay::SignupError::Unavailable("the test's relay is down".into()));
        }
        self.mailed.lock().unwrap().push(notice.clone());
        Ok(format!("{} handed to the test's relay", notice.kind))
    }
}

impl Rig {
    /// The same server with a sink that already has customers, and a vendor that
    /// mints its own signup pages.
    async fn selling(names: &[&str]) -> Rig {
        let pay = CallbackPay::with_checkout(SECRET, "https://checkout.example/");
        let mut state = AppState::in_memory(Registry::new().sells("gunnar", pay.clone()));
        state.signup_plans = [(
            PLAN.to_string(),
            SignupPlan { amount_minor: 10_000, currency: Currency::Sek, cap_bytes: 10_737_418_240, period_days: 30 },
        )]
        .into();
        // gunnar's sink, and only gunnar's (G4: one sink per product).
        let sink = HoldingSink::with(names);
        state.signup_sink = monetize_server::signup::HotSink::per_product(std::collections::BTreeMap::from([("gunnar".to_string(), sink.clone() as monetize_server::signup::Sink)]));
        let state = Arc::new(state);
        let server = TestServer::spawn(state.clone(), BEARER).await;
        let channel = Channel::from_shared(server.endpoint()).unwrap().connect().await.expect("connect");
        Rig { pay, state, server, channel, sink: Some(sink) }
    }

    /// [`Rig::selling`] with the PRODUCT linked too — the shop deployment, where
    /// there is an appliance behind the checkout that can be asked whether it
    /// has room.
    async fn selling_on(product: Arc<monetize::testing::MockProduct>) -> Rig {
        Rig::selling_on_allowing(product, monetize_server::oversell::DEFAULT_MAX_SOLD_PERCENT).await
    }

    /// [`Rig::selling_on`] with `[signups.<product>] max_sold_percent_of_capacity` set —
    /// the operator's choice of how much of the iron this deployment may sell.
    async fn selling_on_allowing(product: Arc<monetize::testing::MockProduct>, percent: u32) -> Rig {
        let pay = CallbackPay::with_checkout(SECRET, "https://checkout.example/");
        let mut state = AppState::in_memory(Registry::new().sells("gunnar", pay.clone()).shared_product(product));
        state.signup_max_sold_percents = std::collections::BTreeMap::from([("gunnar".to_string(), percent)]);
        state.signup_plans = [(
            PLAN.to_string(),
            SignupPlan { amount_minor: 10_000, currency: Currency::Sek, cap_bytes: 10_737_418_240, period_days: 30 },
        )]
        .into();
        let sink = HoldingSink::with(&[]);
        state.signup_sink = sink.clone();
        let state = Arc::new(state);
        let server = TestServer::spawn(state.clone(), BEARER).await;
        let channel = Channel::from_shared(server.endpoint()).unwrap().connect().await.expect("connect");
        Rig { pay, state, server, channel, sink: Some(sink) }
    }
}

/// ★ **THE SHOP DOES NOT SELL ROOM THE APPLIANCE DOES NOT HAVE.**
///
/// A PURCHASE has asked the product since the order model was written —
/// `Transaction::quote` calls `can_absorb` before it touches a vendor, and
/// `monetize::transaction`'s own test is called *"No money moves for capacity
/// that cannot be delivered"*. A SIGNUP asked nobody. Its three checks are the
/// name, the plan and the amount (`signup::refusal`), the sink checks the name
/// and mints a principal, and `signup_sales` records the sale with the comment
/// *"Nothing was bought at a cloud for a signup: the room was on hand"* — which
/// is an ASSUMPTION and was never once verified against the box.
///
/// So on a full appliance the shop kept minting live checkouts. Each one is a
/// real charge on a real card, the customer gets an account and a cap the box
/// cannot honour, and the way out is a refund by hand. The purchase path and
/// the signup path sold the same disk under two different rules.
///
/// Refused BEFORE the card, which is the only place a capacity refusal is free:
/// after the webhook the money has already moved.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_full_appliance_mints_no_checkout_and_the_customer_never_sees_the_box() {
    let product = Arc::new(monetize::testing::MockProduct::gunnar());
    *product.refuse_absorb.lock().unwrap() =
        Some("gunnar: the data set is full; an operator must extend the filesystem before another 10 GiB tenant".into());
    let rig = Rig::selling_on(product.clone()).await;

    let refused = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(),
            username: "olle".into(),
            email: "olle@example.com".into(),
            success_url: "https://gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        })
        .await
        .expect_err("a full appliance must not sell an account");

    // NOTHING REACHED THE VENDOR. That is the assertion that is about money.
    assert!(rig.pay.signup_orders().is_empty(), "a checkout was minted for room that does not exist");


    // And the customer reads maintenance words, never the appliance's.
    assert_eq!(refused.code(), Code::Unavailable, "{refused:?}");
    let shown = refused.message().to_lowercase();
    for word in monetize_server::signup::words::NEVER_SHOWN {
        assert!(!shown.contains(word), "the customer was shown {word:?}: {}", refused.message());
    }
    assert!(shown.contains("nothing has been charged"), "{}", refused.message());

    // Room again: the same request now mints a checkout, so the gate is a gate
    // and not a wall.
    *product.refuse_absorb.lock().unwrap() = None;
    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(),
            username: "olle".into(),
            email: "olle@example.com".into(),
            success_url: "https://gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        })
        .await
        .expect("a box with room sells")
        .into_inner();
    assert!(out.url.starts_with("https://checkout.example/"), "{}", out.url);
    assert_eq!(rig.pay.signup_orders().len(), 1);
    rig.server.stop().await;
}

/// **A deployment with NO product linked still sells.** The open build links no
/// product at all, and a capacity gate that refused where there is nobody to
/// ask would close the open shop to buy nothing.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_deployment_with_no_product_is_not_gated_by_a_box_it_does_not_have() {
    let rig = Rig::selling(&[]).await;
    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(),
            username: "olle".into(),
            email: "olle@example.com".into(),
            success_url: "https://gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        })
        .await
        .expect("no product to ask is not a refusal")
        .into_inner();
    assert!(out.url.starts_with("https://checkout.example/"), "{}", out.url);
    rig.server.stop().await;
}

/// ★ **"Choose another username", BEFORE the card is charged.**
///
/// The whole feature. The name used to be typed on the vendor's own hosted page,
/// where nothing can validate it, and the first time this deployment saw it was
/// in the webhook — after the money moved.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_taken_name_is_refused_before_any_money_moves() {
    let rig = Rig::selling(&["bob"]).await;

    let free = rig.signup_client().check_name(pb::CheckNameRequest { username: "olle".into(), product: "gunnar".into() }).await.unwrap().into_inner();
    assert!(free.free, "olle is nobody's");
    assert!(free.reason.is_empty(), "a free name carries no sentence");

    let taken = rig.signup_client().check_name(pb::CheckNameRequest { username: "bob".into(), product: "gunnar".into() }).await.unwrap().into_inner();
    assert!(!taken.free);
    assert!(taken.reason.contains("bob"), "{}", taken.reason);

    // A name that is not a name is refused with the RULE in it, and never
    // reaches the sink: the customer is owed the rule, not the word "invalid".
    let bad = rig.signup_client().check_name(pb::CheckNameRequest { username: "Bob!".into(), product: "gunnar".into() }).await.unwrap().into_inner();
    assert!(!bad.free);
    assert!(bad.reason.contains(monetize_pay::signup::USERNAME_RULE), "{}", bad.reason);

    // ★ G4: a name is checked FOR a product. None named is the caller's
    // mistake, said as one; a product this server sells no signup for is
    // refused by name, never answered by another product's sink.
    let unnamed = rig.signup_client().check_name(pb::CheckNameRequest { username: "olle".into(), product: String::new() }).await.unwrap_err();
    assert_eq!(unnamed.code(), Code::InvalidArgument, "{unnamed:?}");
    let other = rig.signup_client().check_name(pb::CheckNameRequest { username: "bob".into(), product: "holger".into() }).await.unwrap().into_inner();
    assert!(!other.free && other.reason.contains("holger"), "gunnar's sink never answers for holger: {other:?}");
    // And a checkout is minted FOR a product: none named mints nothing.
    let unnamed = rig
        .signup_client()
        .start(pb::StartSignupRequest { username: "olle".into(), email: "olle@example.com".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .unwrap_err();
    assert_eq!(unnamed.code(), Code::InvalidArgument, "{unnamed:?}");
    assert!(unnamed.message().contains("product"), "{unnamed:?}");

    // Nothing was recorded: this verb holds nothing and writes nothing.
    assert!(rig.state.signups.list(0).unwrap().is_empty());
    rig.server.stop().await;
}

/// ★ **The checkout is minted for a name the deployment has already agreed to**,
/// and the vendor is handed that name — which is the half that used to be
/// missing, and the reason a paid customer could arrive with a name nobody could
/// give them.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn start_mints_a_checkout_carrying_the_name_and_the_plans_net_price() {
    let rig = Rig::selling(&["bob"]).await;

    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest {
            username: "olle".into(),
            product: "gunnar".into(),
            // Empty: a console carries no price list, and this deployment sells one.
            plan: String::new(),
            vendor: String::new(),
            success_url: "https://gunnar.rs/welcome?session={session}".into(),
            cancel_url: "https://gunnar.rs/signup".into(),
            email: " olle@example.com ".into(),
            market: 0,
        })
        .await
        .expect("a free name gets a checkout")
        .into_inner();
    assert!(out.url.starts_with("https://checkout.example/"), "{}", out.url);

    let order = rig.pay.signup_orders().pop().expect("the vendor was asked");
    assert_eq!(order.username, "olle", "the vendor was not told the name");
    assert_eq!(order.email, "olle@example.com", "the address the buyer typed, trimmed, reaches the vendor");
    // A16 (owner 2026-10-23: a buyer never sees monetize): the product, its room and period, and
    // the price in major units — never the plan id, never öre.
    assert_eq!(order.description, "Gunnar — 10.0 GiB storage, 1 month — 100.00 SEK", "the buyer reads the product and major units");
    assert!(!order.description.contains(PLAN), "the vendor's page names no plan id: {}", order.description);

    // No address, or a mistyped one: refused by name before any card form.
    for (bad, words) in [("", "required"), ("olle.example.com", "no '@'")] {
        let refused = rig
            .signup_client()
            .start(pb::StartSignupRequest { product: "gunnar".into(), username: "olle".into(), email: bad.into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
            .await
            .expect_err("no usable address, no checkout");
        assert_eq!(refused.code(), Code::InvalidArgument, "{bad:?}: {refused:?}");
        assert!(refused.message().contains(words), "{bad:?}: {}", refused.message());
    }
    assert_eq!(rig.pay.signup_orders().len(), 1, "a checkout was minted without a usable address");
    assert_eq!(order.plan, PLAN, "the only plan this deployment sells");
    assert_eq!(order.product, "gunnar", "read off the plan id where the caller named none");
    assert_eq!(order.amount, Money { minor: 10_000, currency: Currency::Sek }, "the NET price: tax is the vendor's to add");
    assert_eq!(order.success_url, "https://gunnar.rs/welcome?session={session}");

    // And a taken name never reaches the vendor at all.
    let refused = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(), username: "bob".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .expect_err("a taken name gets no card form");
    assert_eq!(refused.code(), Code::FailedPrecondition);
    assert!(refused.message().contains("bob"), "{}", refused.message());
    assert_eq!(rig.pay.signup_orders().len(), 1, "a refused name still reached the vendor");
    rig.server.stop().await;
}

/// **A vendor that mints no signup page answers UNIMPLEMENTED**, which is what a
/// console turns into its old fixed buy link. It must be distinguishable from a
/// refusal, or a deployment that sells through a Payment Link loses its door.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_vendor_with_no_signup_page_is_unimplemented_and_not_a_refusal() {
    // `Rig::up`'s vendor is built without a checkout page.
    let rig = Rig::up().await;
    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(), username: "olle".into(), email: "olle@example.com".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .expect_err("this vendor sells no signups");
    assert_eq!(out.code(), Code::Unimplemented, "{}", out.message());
    assert!(out.message().contains("mockpay"), "it names the vendor: {}", out.message());
    rig.server.stop().await;
}

/// ★ **No vendor here can sell the signup: UNIMPLEMENTED, a typed "not sold
/// here"** (stinky gunnar-ui #7, DECISIONS 5.4): a configuration gap is told
/// apart by its CODE, never by prose a console has to match — the same code as
/// no sink, and never FAILED_PRECONDITION, which a name refusal wears.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn no_vendor_that_can_sell_the_signup_is_unimplemented_not_a_refusal() {
    let mut rig = Rig::up().await;
    let mut state = AppState::in_memory(Registry::new());
    state.signup_plans = rig.state.signup_plans.clone();
    let state = Arc::new(state);
    let server = TestServer::spawn(state.clone(), BEARER).await;
    rig.channel = Channel::from_shared(server.endpoint()).unwrap().connect().await.expect("connect");
    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(), username: "olle".into(), email: "olle@example.com".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .expect_err("no vendor: no sale");
    assert_eq!(out.code(), Code::Unimplemented, "{}", out.message());
    // The plan's price in major units with its currency, never the öre count.
    assert!(out.message().contains("at 100.00 SEK") && !out.message().contains("10000"), "{}", out.message());
    assert!(rig.pay.signup_orders().is_empty(), "nothing was minted");
    server.stop().await;
    rig.server.stop().await;
}

/// ★ **The race: a name free at the check, taken by the time the card cleared.**
///
/// The customer has paid. Before `Rename` the answer was a refund by hand and an
/// account that never appeared.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_customer_whose_name_was_taken_while_they_paid_renames_instead_of_being_refunded() {
    let rig = Rig::selling(&[]).await;
    // Somebody else's webhook lands first and takes the name.
    rig.deliver(&a_signup("cs_first", "bob"));
    // Ours lands second, for the same name, and is refused over the NAME.
    let (code, _) = rig.deliver(&a_signup("cs_second", "bob"));
    assert_eq!(code, 200);

    let refused = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_second".into() }).await.unwrap().into_inner();
    assert_eq!(refused.state(), State::Refused);
    // **The machine-readable half.** The page decides to offer one text field on
    // THIS, never on the prose.
    assert_eq!(refused.refusal(), pb::signup_status_response::Refusal::Name);

    let out = rig
        .signup_client()
        .rename(pb::RenameSignupRequest { vendor: "mockpay".into(), session: "cs_second".into(), username: "bob2".into() })
        .await
        .expect("a free name finishes it")
        .into_inner()
        .status
        .expect("the record as it stands");
    assert_eq!(out.state(), State::Created);
    assert_eq!(out.username, "bob2");
    assert_eq!(out.namespace, "bob2");

    // The money never moved twice: one payment, one row, and the poll agrees.
    assert_eq!(rig.state.signups.list(0).unwrap().len(), 2, "one row per payment");
    let polled = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_second".into() }).await.unwrap().into_inner();
    assert_eq!(polled.state(), State::Created);
    assert_eq!(polled.username, "bob2");
    rig.server.stop().await;
}

/// **A refusal about the ORDER is final on the wire too**, and the code says so
/// without anybody reading the sentence.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_refusal_about_the_order_is_final_and_rename_refuses_to_touch_it() {
    let rig = Rig::selling(&[]).await;
    let mut s = a_signup("cs_plan2", "bob");
    s.plan = "gunnar/1tb-forever".into();
    rig.deliver(&s);

    let out = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_plan2".into() }).await.unwrap().into_inner();
    assert_eq!(out.refusal(), pb::signup_status_response::Refusal::Final);

    let err = rig
        .signup_client()
        .rename(pb::RenameSignupRequest { vendor: "mockpay".into(), session: "cs_plan2".into(), username: "olle".into() })
        .await
        .expect_err("a plan nobody sells is not a name problem");
    assert_eq!(err.code(), Code::FailedPrecondition);
    assert!(err.message().contains("gunnar/1tb-forever"), "the page shows the ORIGINAL refusal: {}", err.message());
    rig.server.stop().await;
}

/// The four refusals a rename can give are four codes, because a page answers
/// each differently: a session nobody knows, a new name also taken, a record
/// that cannot be renamed, and an outage.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn the_rename_refusals_are_told_apart_by_code() {
    let rig = Rig::selling(&["bob", "olle"]).await;
    let unknown = rig
        .signup_client()
        .rename(pb::RenameSignupRequest { vendor: "mockpay".into(), session: "cs_nobody".into(), username: "x1".into() })
        .await
        .expect_err("nobody has heard of it");
    assert_eq!(unknown.code(), Code::NotFound);

    rig.deliver(&a_signup("cs_race", "bob"));
    let also_taken = rig
        .signup_client()
        .rename(pb::RenameSignupRequest { vendor: "mockpay".into(), session: "cs_race".into(), username: "olle".into() })
        .await
        .expect_err("olle is taken too");
    assert_eq!(also_taken.code(), Code::InvalidArgument, "{}", also_taken.message());

    // And the record is still renameable, so the page simply asks again.
    let still = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_race".into() }).await.unwrap().into_inner();
    assert_eq!(still.refusal(), pb::signup_status_response::Refusal::Name);
    rig.server.stop().await;
}

/// Every new verb is behind the same bearer as `Status`. `CheckName` is an
/// oracle by nature and the per-address budget lives in the console in front of
/// it, but nothing here is answered to a caller with no credential at all.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn the_new_signup_verbs_are_behind_the_same_bearer() {
    let rig = Rig::selling(&[]).await;
    let mut naked = SignupClient::new(rig.channel.clone());
    assert_eq!(naked.check_name(pb::CheckNameRequest { username: "olle".into(), product: "gunnar".into() }).await.unwrap_err().code(), Code::Unauthenticated);
    assert_eq!(naked.start(pb::StartSignupRequest { product: "gunnar".into(), username: "olle".into(), ..Default::default() }).await.unwrap_err().code(), Code::Unauthenticated);
    assert_eq!(
        naked.rename(pb::RenameSignupRequest { vendor: "mockpay".into(), session: "cs_x".into(), username: "olle".into() }).await.unwrap_err().code(),
        Code::Unauthenticated
    );
    rig.server.stop().await;
}

/// ★ **A FLEET SOLD PAST ITS ALLOWANCE MINTS NO CHECKOUT, AND THE BUYER READS
/// NONE OF IT.**
///
/// `can_absorb` — the gate above — asks about FREE SPACE, and free space is
/// what nobody has written yet. Eleven tenants holding a fraction of their
/// 10 GiB caps leave a box that says yes to the twelfth, and the twelfth is
/// sold a promise the disk cannot keep. `monetize::fleet::Oversell` has
/// measured exactly that since it was written and gated nothing.
///
/// The fixture is the front on 2026-09-18: eleven tenants at 10 GiB caps on a
/// 38 GiB set. The refusal is UNAVAILABLE with the maintenance sentence — the
/// customer must never read "oversold", "capacity" or "disk", and must read
/// that nothing has been charged, because nothing has.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_fleet_sold_past_its_allowance_mints_no_checkout_and_the_customer_never_sees_the_arithmetic() {
    const GIB: u64 = 1 << 30;
    let product = Arc::new(monetize::testing::MockProduct::gunnar());
    // The box answers every capacity question with a yes: 35 GiB really is free.
    *product.servable.lock().unwrap() = Some(monetize_product::Servable::Measured {
        servable_bytes: 35 * GIB + GIB / 4,
        total_bytes: 38 * GIB,
        growth: monetize_product::Growth::Sealed("not grown here".into()),
        ceilings: Default::default(),
    });
    let rig = Rig::selling_on(product.clone()).await;
    seed_eleven(&rig);

    let refused = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(),
            username: "olle".into(),
            email: "olle@example.com".into(),
            success_url: "https://gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        })
        .await
        .expect_err("a fleet already sold past its allowance must not sell a twelfth");

    // NOTHING REACHED THE VENDOR: the assertion that is about money.
    assert!(rig.pay.signup_orders().is_empty(), "a checkout was minted for capacity that is already promised");
    // The BOX still said yes — which is the whole point: this refusal is not
    // the appliance's, it is the fleet arithmetic's.

    assert_eq!(refused.code(), Code::Unavailable, "{refused:?}");
    let shown = refused.message().to_lowercase();
    for word in monetize_server::signup::words::NEVER_SHOWN {
        assert!(!shown.contains(word), "the customer was shown {word:?}: {}", refused.message());
    }
    assert!(shown.contains("nothing has been charged"), "{}", refused.message());

    // **THE SAME FLEET, with the allowance raised to 400 %, sells it** — so the
    // gate is the operator's number and not a wall. The state is rebuilt with
    // the same eleven tenants, because the allowance is read at start exactly
    // as it is on a real deployment.
    let roomy = Rig::selling_on_allowing(product.clone(), 400).await;
    seed_eleven(&roomy);
    let out = roomy
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(),
            username: "olle".into(),
            email: "olle@example.com".into(),
            success_url: "https://gunnar.rs/welcome?session={session}".into(),
            ..Default::default()
        })
        .await
        .expect("a fleet inside its allowance sells")
        .into_inner();
    assert!(out.url.starts_with("https://checkout.example/"), "{}", out.url);
    rig.server.stop().await;
    roomy.server.stop().await;
}

/// Eleven paid tenants at the plan's 10 GiB cap, each holding a quarter of a
/// gigabyte of it — the live front's fleet, in the ledger and the usage store.
fn seed_eleven(rig: &Rig) {
    const GIB: u64 = 1 << 30;
    for i in 0..11 {
        let tenant = format!("t{i}");
        rig.state.usage.put("gunnar", &tenant, &monetize_product::Usage { meters: [("pack_bytes".to_string(), GIB / 4)].into(), measured_at_unix_ms: 1 }).unwrap();
        rig.state
            .ledger
            .set_entitlement(
                "gunnar",
                &rig.state.signer_for("gunnar").sign_fact(monetize_product::EntitlementFact {
                    tenant: monetize_product::TenantId(tenant),
                    plan: PLAN.into(),
                    state: monetize_product::State::Paid,
                    paid_until_unix_ms: Some(2),
                    caps: [("pack_bytes".to_string(), 10_737_418_240u64)].into(),
                    source: "payment:mockpay:x".into(),
                    signature: Vec::new(),
                    issued_unix_ms: None,
                    issued_signature: Vec::new(),
                }),
            )
            .unwrap();
    }
}

/// ★ **NO SINK, NO SALE** (owner 2026-09-26). The open server's sink when
/// none is loaded is `NoSink`: `Signup.Start` is refused UNIMPLEMENTED before
/// any checkout (the console reads that as "cannot sell an account"), and a
/// paid webhook that reached it anyway is refused by name — never `Created`.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn with_no_sink_loaded_no_checkout_is_minted_and_nothing_is_ever_created() {
    let mut rig = Rig::selling(&[]).await;
    // the server a deployment gets when nothing creates accounts
    let mut state = AppState::in_memory(Registry::new().sells("gunnar", rig.pay.clone()));
    state.signup_plans = rig.state.signup_plans.clone();
    state.signup_sink = monetize_server::registry::Linked::default().build_signup_sink(std::path::Path::new("/nonexistent"), &serde_json::json!({})).unwrap();
    assert!(!state.signup_sink.creates_accounts(), "the open default creates nothing and says so");
    let state = Arc::new(state);
    let server = TestServer::spawn(state.clone(), BEARER).await;
    rig.channel = Channel::from_shared(server.endpoint()).unwrap().connect().await.expect("connect");
    let refused = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(), username: "olle".into(), email: "olle@example.com".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .expect_err("no sink: no sale");
    assert_eq!(refused.code(), tonic::Code::Unimplemented, "{refused:?}");
    assert!(refused.message().contains("no signup sink"), "{}", refused.message());
    assert!(rig.pay.signup_orders().is_empty(), "a checkout was minted for an account nobody can create");
    // and the sink itself never says Created
    let s = monetize_pay::signup::PaidSignup {
        vendor: "stripe".into(), session: "cs_x".into(), reference: String::new(), email: String::new(), username: "olle".into(),
        product: "gunnar".into(), plan: PLAN.into(), amount: monetize_pay::Money { minor: 10_000, currency: Currency::Sek },
        tax: monetize_pay::Money { minor: 0, currency: Currency::Sek }, paid_at_unix_ms: 0, customer_country: None,
    };
    assert!(matches!(state.signup_sink.paid(&s), Err(monetize_pay::signup::SignupError::Refused(m)) if m.contains("no account was created")));
    drop(server);
}

// ---------------------------------------------------------------------------
// One shop (owner 2026-10-07): an account at the shop, without room here.
// ---------------------------------------------------------------------------

/// The shop's account plan, as the kit writes it: no price, no room.
const ACCOUNT_PLAN: &str = "gunnar/account";

impl Rig {
    /// [`Rig::selling`] with the shop's account plan beside the paid one.
    async fn selling_accounts(names: &[&str]) -> Rig {
        let rig = Rig::selling(names).await;
        rig.state.signup_plans.set(
            [
                (PLAN.to_string(), SignupPlan { amount_minor: 10_000, currency: Currency::Sek, cap_bytes: 10_737_418_240, period_days: 30 }),
                (ACCOUNT_PLAN.to_string(), SignupPlan { amount_minor: 0, currency: Currency::Sek, cap_bytes: 0, period_days: 0 }),
            ]
            .into(),
            Default::default(),
        );
        rig
    }

    async fn start_account(&self, username: &str) -> Result<pb::StartSignupResponse, tonic::Status> {
        self.signup_client()
            .start(pb::StartSignupRequest {
                username: username.into(),
                email: format!("{username}@example.com"),
                plan: ACCOUNT_PLAN.into(),
                product: "gunnar".into(),
                vendor: "stripe".into(),
                success_url: "https://gunnar.rs/welcome?session={session}".into(),
                ..Default::default()
            })
            .await
            .map(tonic::Response::into_inner)
    }

    /// ★ **A free account, the whole way** (owner 2026-10-15): `Start` sends the buyer to the
    /// vendor's card check, the buyer checks a card of their own (`fp_<name>`), and the welcome
    /// page's `Status` poll makes the account. Answers the welcome page the buyer lands on.
    async fn make_account(&self, username: &str) -> Result<pb::StartSignupResponse, tonic::Status> {
        let page = self.start_account(username).await?;
        assert!(page.url.starts_with("https://checkout.example/cs_card"), "the vendor's card check: {}", page.url);
        self.pay.check_card(&page.session, &format!("fp_{username}"));
        let st = self.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: page.session.clone() }).await?.into_inner();
        assert_eq!(st.state(), State::Created, "made once the card is checked: {st:?}");
        Ok(pb::StartSignupResponse { url: format!("https://gunnar.rs/welcome?session={}", page.session), session: page.session })
    }
}

/// ★ **An account at the shop is made once its card is checked** (one shop, owner
/// 2026-10-07; the card check owner 2026-10-15): a visitor who buys only a private Gunnar
/// first makes the account they will see and grow it under. Its plan has no price, so no
/// money moves — but `Start` sends the buyer to the vendor's CARD CHECK (nothing charged),
/// never a paid checkout, and the account is made when the return page's poll finds the
/// card checked; from then on it reads CREATED. A name already held is refused before any
/// card check.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn an_account_at_the_shop_is_made_once_its_card_is_checked() {
    let rig = Rig::selling_accounts(&["bob"]).await;
    let page = rig.start_account("alice").await.expect("a card check");
    assert!(page.url.starts_with("https://checkout.example/cs_card"), "the vendor's card check: {}", page.url);
    assert!(rig.pay.signup_orders().is_empty(), "no paid checkout: nothing is paid for");
    let st = rig.signup_client().status(pb::SignupStatusRequest { vendor: "stripe".into(), session: page.session.clone() }).await.unwrap().into_inner();
    assert_ne!(st.state(), State::Created, "not made before the card is checked");
    let out = rig.make_account("carol").await.expect("made");
    let st = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: out.session.clone() }).await.unwrap().into_inner();
    assert_eq!(st.state(), State::Created, "the return page reads it made");
    assert_eq!((st.username.as_str(), st.namespace.as_str()), ("carol", "carol"));
    let taken = rig.start_account("bob").await.expect_err("a name already held");
    assert_eq!(taken.code(), Code::FailedPrecondition, "{taken:?}");
    rig.server.stop().await;
}

/// ★ **An account at the shop is mailed its sign-in link** (§3c, OM-20):
/// the moment `Start` makes the account, the buyer's address gets ONE mail
/// carrying the link the answer leads to — this console's welcome page with
/// the account's session, which registers the passkey while the account holds
/// none. A buyer who closes the tab before the passkey still has a way in that
/// is not an operator's. The secret is in the body and nowhere else (not the
/// subject); a refused start mails nothing; a relay that does not take the
/// mail never un-makes the account.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn an_account_at_the_shop_is_mailed_its_sign_in_link() {
    let rig = Rig::selling_accounts(&["bob"]).await;
    let sink = rig.sink.clone().expect("the selling rig's sink");
    let out = rig.make_account("alice").await.expect("made");
    let mailed = sink.mailed.lock().unwrap().clone();
    assert_eq!(mailed.len(), 1, "{mailed:?}");
    let m = &mailed[0];
    assert_eq!((m.product.as_str(), m.tenant.as_str(), m.to.as_str(), m.kind.as_str()), ("gunnar", "alice", "alice@example.com", "account.sign_in"), "{m:?}");
    assert!(m.body.contains(&out.url), "the link the answer leads to: {m:?}");
    assert!(m.subject.contains("gunnar.rs") && !m.subject.contains(&out.session), "{m:?}");
    rig.start_account("bob").await.expect_err("a name already held");
    assert_eq!(sink.mailed.lock().unwrap().len(), 1, "a refused start mails nothing");
    sink.relay_down.store(true, std::sync::atomic::Ordering::SeqCst);
    let carol = rig.make_account("carol").await.expect("the account is made though the mail did not go");
    let st = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: carol.session }).await.unwrap().into_inner();
    assert_eq!(st.state(), State::Created);
    rig.server.stop().await;
}

/// ★ **The sign-in link, sent again** (owner 2026-10-11: the welcome page says where the
/// link went, with [Send again]): a CREATED signup's link — the console's welcome page for
/// that session — is mailed again to the address it was made with, and the answer names it
/// MASKED only. Once a minute per session; an unknown session, a page that is no https
/// welcome page for a session and a signup of another product are refused, and nothing is
/// mailed for them. (A page off the signup's site is `site_refusal`'s `[signup-other-site]`.)
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_created_signups_sign_in_link_is_sent_again_masked_and_not_too_often() {
    let rig = Rig::selling_accounts(&[]).await;
    let sink = rig.sink.clone().expect("the selling rig's sink");
    let out = rig.make_account("alice").await.expect("made");
    assert_eq!(sink.mailed.lock().unwrap().len(), 1);
    let again = |session: &str, url: &str, product: &str| {
        let mut c = rig.signup_client();
        let r = pb::SignupSignInAgainRequest { product: product.into(), session: session.into(), welcome_url: url.into() };
        async move { c.send_sign_in_again(r).await.map(tonic::Response::into_inner) }
    };
    let welcome = "https://gunnar.rs/welcome?session={session}";
    let said = again(&out.session, welcome, "gunnar").await.expect("sent again");
    assert!(said.words.contains("al***@example.com") && !said.words.contains("alice@example.com"), "masked only: {}", said.words);
    let mailed = sink.mailed.lock().unwrap().clone();
    assert_eq!(mailed.len(), 2, "{mailed:?}");
    assert_eq!((mailed[1].to.as_str(), mailed[1].kind.as_str()), ("alice@example.com", "account.sign_in"));
    assert!(mailed[1].body.contains(&out.url), "the same link: {:?}", mailed[1]);
    let soon = again(&out.session, welcome, "gunnar").await.expect_err("once a minute");
    assert_eq!(soon.code(), Code::ResourceExhausted, "{soon:?}");
    let unknown = again("acct_00000000000000000000000000000000", welcome, "gunnar").await.expect_err("unknown");
    assert_eq!(unknown.code(), Code::NotFound, "{unknown:?}");
    for bad in ["http://gunnar.rs/welcome?session={session}", "https://gunnar.rs/welcome"] {
        let refused = again(&out.session, bad, "gunnar").await.expect_err(bad);
        assert_eq!(refused.code(), Code::InvalidArgument, "{bad}: {refused:?}");
    }
    let wrong = again(&out.session, welcome, "holger").await.expect_err("another product's");
    assert_eq!(wrong.code(), Code::NotFound, "{wrong:?}");
    assert_eq!(sink.mailed.lock().unwrap().len(), 2, "nothing more was mailed");
    rig.server.stop().await;
}

/// ★ **An account at the shop is never offered as room**: `Signup.Plans`
/// lists the paid plans and not the account's, which sells nothing.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn an_account_at_the_shop_is_never_offered_as_room() {
    let rig = Rig::selling_accounts(&[]).await;
    let plans = rig.signup_client().plans(pb::SignupPlansRequest { product: "gunnar".into(), ..Default::default() }).await.unwrap().into_inner().plans;
    assert!(plans.iter().all(|p| p.id != ACCOUNT_PLAN), "{plans:?}");
    assert!(plans.iter().any(|p| p.id == PLAN), "the paid plan is still on offer");
    rig.server.stop().await;
}

/// ★ **An account at the shop holds no room and never lapses**: its fact is
/// Free with no end (nothing to renew, so nothing to delete), its cap
/// [`monetize_server::signup::NO_ROOM_CAP`] (a zero cap is NO cap on gunnar);
/// it is no sale. And a plan with room is never free: refused, nothing made.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn an_account_at_the_shop_holds_no_room_and_never_lapses() {
    let rig = Rig::selling_accounts(&[]).await;
    rig.make_account("alice").await.expect("made");
    let facts = monetize_server::signup::signup_facts(&rig.state, "gunnar").unwrap();
    let alice = facts.iter().find(|f| f.tenant.0 == "alice").expect("alice's fact");
    assert_eq!(alice.state, monetize_product::State::Free, "{alice:?}");
    assert_eq!(alice.paid_until_unix_ms, None, "nothing ends: {alice:?}");
    assert_eq!(alice.caps.get("pack_bytes"), Some(&monetize_server::signup::NO_ROOM_CAP), "{alice:?}");
    let sales = monetize_server::signup::signup_sales(&rig.state, "gunnar").unwrap();
    assert!(sales.iter().all(|s| s.tenant != "alice"), "an account at the shop is no sale: {sales:?}");
    rig.state.signup_plans.set(
        [("gunnar/odd".to_string(), SignupPlan { amount_minor: 0, currency: Currency::Sek, cap_bytes: 10_737_418_240, period_days: 30 })].into(),
        Default::default(),
    );
    let refused = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(), username: "dora".into(), email: "dora@example.com".into(), plan: "gunnar/odd".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .expect_err("room is never free");
    assert_eq!(refused.code(), Code::FailedPrecondition, "{refused:?}");
    assert!(rig.pay.signup_orders().is_empty());
    rig.server.stop().await;
}

/// ★ **A request that names no plan never lands on the account plan**: the
/// functional test and an older page ask with none, and the shop picks the
/// paid plan as before (one per market) — the account plan beside it changes
/// nothing for them.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_request_naming_no_plan_never_lands_on_the_account_plan() {
    let rig = Rig::selling_accounts(&[]).await;
    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest { product: "gunnar".into(), username: "erik".into(), email: "erik@example.com".into(), success_url: "https://gunnar.rs/welcome?session={session}".into(), ..Default::default() })
        .await
        .expect("the paid plan, as before")
        .into_inner();
    assert!(out.url.starts_with("https://checkout.example/"), "{}", out.url);
    assert_eq!(rig.pay.signup_orders().len(), 1, "a checkout for the paid plan");
    rig.server.stop().await;
}

// ---------------------------------------------------------------------------
// STINKY ST-23: the account mail's link is always on the estate's own site.
// ---------------------------------------------------------------------------

const TEST2_BEARER: &str = "estate-bearer-of-test2-0123456789abcd";

impl Rig {
    /// [`Rig::selling_accounts`] on ONE box selling gunnar for two sites (`gunnar-rs` at
    /// gunnar.rs, home; `test2-gunnar-rs` at test2.gunnar.rs), test2 enrolled with its bearer.
    async fn selling_sites() -> Rig {
        let pay = CallbackPay::with_checkout(SECRET, "https://checkout.example/");
        let site = |site: &str| monetize_server::config::EstateConfig { product: "gunnar".into(), vendor: "mockpay".into(), owner: "ignalina".into(), site: site.into(), ..Default::default() };
        let reg = Registry::new().sells("gunnar", pay.clone()).home("gunnar", "gunnar-rs").estate("gunnar-rs", site("gunnar.rs")).estate("test2-gunnar-rs", site("test2.gunnar.rs"));
        let state = AppState::in_memory(reg);
        state.signup_plans.set([(ACCOUNT_PLAN.to_string(), SignupPlan { amount_minor: 0, currency: Currency::Sek, cap_bytes: 0, period_days: 0 })].into(), Default::default());
        let mut state = state;
        let sink = HoldingSink::with(&[]);
        state.signup_sink = monetize_server::signup::HotSink::per_product(std::collections::BTreeMap::from([("gunnar".to_string(), sink.clone() as monetize_server::signup::Sink)]));
        state.fleet.know_bearer(&monetize_server::fleet::bearer_digest(TEST2_BEARER), "test2-gunnar-rs");
        let state = Arc::new(state);
        let server = TestServer::spawn(state.clone(), BEARER).await;
        let channel = Channel::from_shared(server.endpoint()).unwrap().connect().await.expect("connect");
        Rig { pay, state, server, channel, sink: Some(sink) }
    }

    async fn start_account_as(&self, bearer: &str, username: &str, success_url: &str) -> Result<pb::StartSignupResponse, tonic::Status> {
        let b: MetadataValue<_> = format!("Bearer {bearer}").parse().unwrap();
        SignupClient::with_interceptor(self.channel.clone(), move |mut r: Request<()>| {
            r.metadata_mut().insert("authorization", b.clone());
            Ok(r)
        })
        .start(pb::StartSignupRequest { username: username.into(), email: format!("{username}@example.com"), plan: ACCOUNT_PLAN.into(), product: "gunnar".into(), vendor: "stripe".into(), success_url: success_url.into(), ..Default::default() })
        .await
        .map(tonic::Response::into_inner)
    }

    /// [`Rig::start_account_as`] the whole way: the card checked, the welcome page's poll
    /// (as the same estate) makes the account. Answers the welcome page with its session.
    async fn make_account_as(&self, bearer: &str, username: &str, success_url: &str) -> Result<pb::StartSignupResponse, tonic::Status> {
        let page = self.start_account_as(bearer, username, success_url).await?;
        self.pay.check_card(&page.session, &format!("fp_{username}"));
        let b: MetadataValue<_> = format!("Bearer {bearer}").parse().unwrap();
        let st = SignupClient::with_interceptor(self.channel.clone(), move |mut r: Request<()>| {
            r.metadata_mut().insert("authorization", b.clone());
            Ok(r)
        })
        .status(pb::SignupStatusRequest { vendor: "stripe".into(), session: page.session.clone() })
        .await?
        .into_inner();
        assert_eq!(st.state(), State::Created, "made once the card is checked: {st:?}");
        Ok(pb::StartSignupResponse { url: success_url.replace("{session}", &page.session), session: page.session })
    }
}

/// ★ **STINKY ST-23: an account's sign-in mail links only to its estate's own site.** A
/// Start that names no estate (the service bearer) for a product sold per site is refused —
/// nothing made, nothing mailed — never mailed to whatever host `success_url` names; from an
/// estate, a page off its site is refused for the account plan too; on its site the mail's
/// link and subject name that site.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn an_accounts_sign_in_mail_links_only_to_its_estates_site() {
    let rig = Rig::selling_sites().await;
    let sink = rig.sink.clone().unwrap();
    let unnamed = rig.start_account_as(BEARER, "alice", "https://evil.example/welcome?session={session}").await.expect_err("no estate named");
    assert!(unnamed.message().contains("estate-unnamed"), "{unnamed:?}");
    let off = rig.start_account_as(TEST2_BEARER, "alice", "https://evil.example/welcome?session={session}").await.expect_err("off its site");
    assert_eq!(off.code(), Code::InvalidArgument, "{off:?}");
    assert!(off.message().contains("signup-other-site"), "{off:?}");
    let other = rig.start_account_as(TEST2_BEARER, "alice", "https://gunnar.rs/welcome?session={session}").await.expect_err("another site's page");
    assert!(other.message().contains("signup-other-site"), "{other:?}");
    assert!(sink.mailed.lock().unwrap().is_empty(), "nothing was mailed for a refused start");
    let made = rig.make_account_as(TEST2_BEARER, "alice", "https://test2.gunnar.rs/welcome?session={session}").await.expect("on its site");
    let mailed = sink.mailed.lock().unwrap().clone();
    assert_eq!(mailed.len(), 1, "{mailed:?}");
    assert!(mailed[0].body.contains(&made.url) && mailed[0].subject.contains("https://test2.gunnar.rs"), "{:?}", mailed[0]);
    rig.server.stop().await;
}

/// ★ ST-7 (STINKY 2026-10-11): **a verified webhook for a checkout this box never minted is
/// another system's money on the same merchant account** — answered 200 (the vendor stops),
/// and no account is made; the same session once this box minted it is a customer.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_session_this_box_never_minted_is_ignored_and_never_becomes_an_account() {
    let rig = Rig::up().await;
    let s = a_signup("cs_elsewhere", "mallory");
    let (code, body) = rig.deliver_unminted(&s);
    assert_eq!(code, 200, "{body}");
    assert!(body.contains("\"ignored\":true") && body.contains("not minted by this monetize"), "{body}");
    let out = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: "cs_elsewhere".into() }).await.expect("status").into_inner();
    assert_eq!(out.state(), State::Unknown, "nothing was kept for another system's session");

    let (code, body) = rig.deliver(&s);
    assert_eq!(code, 200, "{body}");
    assert!(body.contains("\"state\":\"CREATED\""), "minted here: a customer: {body}");
    rig.server.stop().await;
}

/// ★ **A paid plan's account is mailed its sign-in link once it is made** (A11 fix 7,
/// 2026-10-23; Gunnar and Holger alike): the welcome page says "We've sent a sign-in link",
/// and before this only the free account's path sent one. The link is the welcome page the
/// buyer was sent back to, with the session; a second delivery of the same payment mails
/// nothing more; a payment this box keeps no welcome page for mails nothing.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_paid_plans_account_is_mailed_its_sign_in_link_once_it_is_made() {
    let rig = Rig::selling(&[]).await;
    let sink = rig.sink.clone().expect("the selling rig's sink");
    let out = rig
        .signup_client()
        .start(pb::StartSignupRequest {
            username: "olle".into(),
            product: "gunnar".into(),
            plan: String::new(),
            vendor: String::new(),
            success_url: "https://gunnar.rs/welcome?session={session}&next=%2F".into(),
            cancel_url: "https://gunnar.rs/signup".into(),
            email: "olle@example.com".into(),
            market: 0,
        })
        .await
        .expect("a checkout")
        .into_inner();
    assert!(!out.session.is_empty(), "{out:?}");
    assert!(sink.mailed.lock().unwrap().is_empty(), "nothing is mailed before the payment");
    let paid = PaidSignup { email: "olle@example.com".into(), ..a_signup(&out.session, "olle") };
    assert_eq!(rig.deliver_unminted(&paid).0, 200);
    let st = rig.signup_client().status(pb::SignupStatusRequest { vendor: "mockpay".into(), session: out.session.clone() }).await.unwrap().into_inner();
    assert_eq!(st.state(), State::Created, "{st:?}");
    let mailed = sink.mailed.lock().unwrap().clone();
    assert_eq!(mailed.len(), 1, "{mailed:?}");
    let m = &mailed[0];
    assert_eq!((m.tenant.as_str(), m.to.as_str(), m.kind.as_str()), ("olle", "olle@example.com", "account.sign_in"), "{m:?}");
    assert!(m.body.contains(&format!("https://gunnar.rs/welcome?session={}&next=%2F", out.session)), "the welcome page with its session: {m:?}");
    assert!(!m.subject.contains(&out.session), "the link is in the body only: {m:?}");
    assert_eq!(rig.deliver_unminted(&paid).0, 200);
    assert_eq!(sink.mailed.lock().unwrap().len(), 1, "a second delivery mails nothing more");
    rig.deliver(&a_signup("cs_elsewhere", "kim"));
    assert_eq!(sink.mailed.lock().unwrap().len(), 1, "no welcome page kept, no mail");
    rig.server.stop().await;
}

/// ★ **A made account is on the ledger before a bundle is raised from it** (the buy trials on
/// `linked()`, 2026-10-24): a free account's fact lives in the signup store until the poller's
/// next tick adopts it, while the site's product already holds it (`NO_ROOM_CAP`). A "more
/// room" order in that window was resolved against an EMPTY ledger, so the site's ticket (held
/// + delta) and the ONE box's caps differed and the raise was refused (`WHO_NOT_CONFIRMED`).
/// `adopt_signup` seeds the granted fact at once, as the tick would; twice is once.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn a_made_account_is_adopted_onto_the_ledger_before_a_raise() {
    let rig = Rig::selling_accounts(&[]).await;
    rig.make_account("alice").await.expect("made");
    assert!(rig.state.ledger.entitlement("gunnar", "alice").unwrap().is_none(), "the signup store holds it, the ledger not yet");
    assert!(monetize_server::poller::adopt_signup(&rig.state, "gunnar", "alice").expect("adopted"), "adopted now");
    let fact = rig.state.ledger.entitlement("gunnar", "alice").unwrap().expect("on the ledger");
    assert_eq!((fact.state, fact.caps.get("pack_bytes").copied()), (monetize_product::State::Free, Some(monetize_server::signup::NO_ROOM_CAP)), "{fact:?}");
    assert!(!monetize_server::poller::adopt_signup(&rig.state, "gunnar", "alice").expect("no-op"), "twice is once");
    assert!(!monetize_server::poller::adopt_signup(&rig.state, "gunnar", "nobody").expect("no-op"), "no signup, nothing adopted");
    rig.server.stop().await;
}