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

nordisk/dwarves

dwarves-gui/tests/robot_mimir_release.rs

//! **ROBOT-UI: the 🚀 Mímir release tab draws the plan the FORGE read from Mímir.**
//!
//! ```text
//!   mock nornir (Mimir dependency verbs) ── forge (MimirRelease on its jera lane) ── the shell
//! ```
//!
//! The shipped shell is given only the forge. The tab asks `MimirRelease.Plan`; the forge
//! answers at once with the jera job, computes the plan from the mock's BuildOrder /
//! DepsOf / ChangedSinceLastRelease / AffectedByChange, and the tab — asking again — draws:
//!
//! 1. Mímir's release order and each repo's convergence (`moved` / `downstream` /
//!    `converged`) and dependencies;
//! 2. what to release, in order;
//! 3. every Mímir read was made BY THE FORGE for the selected workspace (the shell holds
//!    no nornir address, and reads no checkout);
//! 4. no publish affordance.

mod common;

use std::collections::BTreeMap;

use common::*;
use facett_core::Facet;
use nornir_warehouse_embed::testkit::{spawn_mock_mimir, MockMimir};
use serde_json::json;

fn mimir() -> MockMimir {
    let dep = |repo: &str, deps: serde_json::Value| {
        (
            repo.to_string(),
            json!({ "repo": repo, "transitive": false, "dependencies": deps }).to_string(),
        )
    };
    MockMimir {
        build_order: json!({ "build_order": ["shop-core", "shop", "web"] }).to_string(),
        deps_of: BTreeMap::from([
            dep("shop-core", json!([])),
            dep(
                "shop",
                json!([{ "repo": "shop-core", "via": ["shop-core"] }]),
            ),
            dep(
                "web",
                json!([{ "repo": "shop", "via": ["shop", "shop-api"] }]),
            ),
        ]),
        changed_since_last_release: Ok(
            json!({ "changed": ["shop"], "affected": ["shop", "web"], "build_order": [] })
                .to_string(),
        ),
        affected_by_change: json!({ "changed": ["shop"], "affected": ["shop", "web"] }).to_string(),
        ..MockMimir::default()
    }
}

#[test]
fn the_mimir_release_tab_draws_the_forges_plan_from_mimir() {
    let m = mimir();
    let calls = m.calls.clone();
    let nornir = spawn_mock_mimir(m);
    let forge = dwarves::mimir_release::spawn_forge(nornir.endpoint.clone(), String::new());
    let mut app = shell(&forge.endpoint);
    Facet::update_json(&mut app, &json!({ "set_tab": "Mímir release" }).to_string());
    Facet::update_json(&mut app, r#"{"wait":true}"#);
    let s = Facet::state_json(&app);
    let r = &s["mimir-release"];

    // 1. the order, the convergence, the dependencies — Mímir's
    assert_eq!(r["state"], "done", "{r}");
    assert_eq!(r["plan"]["order"], json!(["shop-core", "shop", "web"]));
    assert_eq!(
        r["plan"]["status"],
        json!({ "shop-core": "converged", "shop": "moved", "web": "downstream" })
    );
    assert_eq!(r["plan"]["deps"]["web"], json!(["shop"]));
    assert_eq!(r["plan"]["since_last_release"], "measured");
    // 2. what to release
    assert_eq!(r["plan"]["to_release"], json!(["shop", "web"]));
    // 3. asked of the forge, for the selected workspace; the forge read Mímir
    assert!(
        r["via"].as_str().unwrap().contains("MimirRelease.Plan"),
        "{r}"
    );
    assert!(
        !r["job_id"].as_str().unwrap_or("").is_empty(),
        "the plan names the jera job that computed it: {r}"
    );
    let calls = calls.lock().unwrap().clone();
    assert!(
        !calls.is_empty() && calls.iter().all(|c| c.ends_with(&format!(" {WS}"))),
        "{calls:?}"
    );
    assert_eq!(r["reads_local_checkouts"], false);
    // 4. nothing to publish
    assert_eq!(r["can_publish"], false);
    matrix("mimir_release_tab_draws_the_forges_plan", true, "🚀 Mímir release: MimirRelease.Plan on the forge's jera lane, from Mímir's BuildOrder/DepsOf/ChangedSinceLastRelease/AffectedByChange, drawn as order + convergence + to-release");
}