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