crates/monetize-server/src/estate_order/tests/queued_deadline.rs
//! ★ **A32-22: a paid buyer never reads "queued" for ever.** A paid order that waits in HELD for
//! room is told to the operator after [`QUEUED_TELL_AFTER_MS`] (and again while it waits), the
//! buyer reads since when it waits and the day it is set up or refunded by; at
//! [`QUEUED_DEADLINE_MS`] it is OWED (the operator's: retry or refund, never a refund by
//! itself). An OWED order is told to the operator every [`OWED_TELL_EVERY_MS`] (an ALERT and a
//! CODE RED) until it is settled, and the buyer reads the day it was told and the day by which
//! it is set up or refunded.
use super::*;
/// acme paid and queued: no slot is free (`max_open = 0`).
fn queued(name: &str) -> Rig {
let r = rig_with(
name,
EstateOrderConfig {
max_open: 0,
..cfg()
},
"PASS",
);
start(
&r.state,
"acme",
"a@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::HELD, "{:#?}", run.history);
assert!(run.captured_at_ms > 0, "paid, then queued");
r
}
#[test]
fn a_paid_order_queued_too_long_is_told_and_then_owed_and_the_buyer_reads_the_days() {
let r = queued("queued-long");
let t0 = r.clock.load(Ordering::SeqCst);
let run = at(&r, t0 + 60_000);
assert_eq!(run.queue_told_at_ms, 0, "a short wait is not told");
assert_eq!(
run.customer_view_as("gunnar.rs", &gw()).1,
"Your Gunnar is paid and being prepared."
);
let run = at(&r, t0 + QUEUED_TELL_AFTER_MS);
assert!(run.queue_told_at_ms > 0, "told once it waits long");
let (st, words, _) = run.customer_view_as("gunnar.rs", &gw());
let by = monetize_embed::civil::iso_date(run.held_since_ms() + QUEUED_DEADLINE_MS);
assert_eq!(st, "queued");
assert!(
words.contains("waits for room") && words.contains(&by) && words.contains("refund"),
"the buyer reads the day: {words}"
);
let told = run.queue_told_at_ms;
assert_eq!(
at(&r, t0 + QUEUED_TELL_AFTER_MS + 60_000).queue_told_at_ms,
told,
"not on every tick"
);
let run = at(&r, t0 + QUEUED_DEADLINE_MS + 1);
assert_eq!(
run.phase,
phase::OWED,
"past its deadline the operator decides: {:#?}",
run.history
);
assert_eq!(r.pay.refunds(), 0, "never a refund by itself");
}
#[test]
fn an_owed_order_is_told_every_day_until_settled_and_the_buyer_reads_the_days() {
let r = queued("owed-told");
let t0 = r.clock.load(Ordering::SeqCst);
let run = at(&r, t0 + QUEUED_DEADLINE_MS + 1);
assert_eq!(run.phase, phase::OWED);
tick(&r.state);
let run = r.state.estates.get("acme").unwrap();
let first = run.owed_told_at_ms;
assert!(first > 0, "told");
assert!(
code_red::list(&r.state)
.iter()
.any(|c| c.key == "owed:acme"),
"{:#?}",
code_red::list(&r.state)
);
let (st, words, _) = run.customer_view_as("gunnar.rs", &gw());
assert_eq!(st, "queued");
assert!(
words.contains(&monetize_embed::civil::iso_date(run.owed_since_ms()))
&& words.contains(&monetize_embed::civil::iso_date(
run.owed_since_ms() + OWED_DEADLINE_MS
))
&& words.contains("refund"),
"{words}"
);
r.clock
.store(t0 + QUEUED_DEADLINE_MS + 3_600_000, Ordering::SeqCst);
tick(&r.state);
assert_eq!(
r.state.estates.get("acme").unwrap().owed_told_at_ms,
first,
"once a day"
);
r.clock.store(first + OWED_TELL_EVERY_MS, Ordering::SeqCst);
tick(&r.state);
assert!(
r.state.estates.get("acme").unwrap().owed_told_at_ms > first,
"told again the next day"
);
}