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/unsaved_run.rs

//! **A28 M16: a run the shop cannot write down is CODE RED, never `let _ = save`.** The run
//! file is the order's memory across a restart: a write that failed was dropped at three
//! sites (a resend's note, a plan change's finished step, a resized machine), so memory and
//! disk disagreed and a restart forgot what was done. Now each is raised CODE RED under
//! `save:<estate>:run`, and the next write of the run clears it.

use super::*;

const RED: &str = "save:acme:run";

/// The estate's run directory turned into a plain file: every write of the run fails, as on
/// a full or read-only volume (a root test cannot be refused by a mode bit). Answers where
/// the directory was kept.
fn break_the_run_dir(r: &Rig) -> std::path::PathBuf {
    let d = r.state.estates.run_dir("acme").expect("a run directory");
    let kept = d.with_extension("kept");
    std::fs::rename(&d, &kept).unwrap();
    std::fs::write(&d, b"not a directory").unwrap();
    kept
}

fn mend_the_run_dir(r: &Rig, kept: &std::path::Path) {
    let d = r.state.estates.run_dir("acme").expect("a run directory");
    std::fs::remove_file(&d).unwrap();
    std::fs::rename(kept, &d).unwrap();
}

/// ★ **A resend whose note cannot be written is CODE RED**: the signed order is queued (the
/// buyer's link is on its way), and the operator is told the run on disk lacks the note.
/// The next write of the run clears it.
#[test]
fn a_run_the_shop_cannot_write_is_code_red_and_the_next_write_clears_it() {
    let r = rig_with("unsaved-run", cfg(), "PASS");
    start_for(
        &r.state,
        "acme",
        "buyer@example.com",
        "",
        "alice",
        &EstateSizes::default(),
    )
    .unwrap();
    r.pay.authorize(&handle_of(&r, "acme"));
    drive(&r.state, "acme");
    assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
    let kept = break_the_run_dir(&r);
    send_sign_in_again(&r.state, "acme").expect("queued: the signed order is the resend");
    let red = code_red::list(&r.state)
        .into_iter()
        .find(|c| c.key == RED)
        .unwrap_or_else(|| {
            panic!(
                "CODE RED for the unwritten run: {:#?}",
                code_red::list(&r.state)
            )
        });
    assert!(
        red.what.contains("NOT written") && red.what.contains("sign-in link"),
        "{red:?}"
    );
    assert!(!red.error.is_empty() && !red.next.is_empty(), "{red:?}");

    mend_the_run_dir(&r, &kept);
    let run = r.state.estates.get("acme").unwrap();
    {
        let _pen = r.state.estates.pen("acme");
        super::super::save(&r.state, &run).expect("written again");
    }
    assert!(
        code_red::list(&r.state).iter().all(|c| c.key != RED),
        "the next write clears it: {:#?}",
        code_red::list(&r.state)
    );
}