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

nordisk/facett

facett-brokkrview/tests/headless.rs

//! **Backend (4) headless drive** for facett-brokkrview.
//!
//! Drives the view through the constellation-wide [`facett_core::Panel`] seam
//! (the blanket impl makes `BrokkrView` a `Panel` for free) — applying a `Vec` of
//! **JSON** messages via `update_json` and asserting the `state_json` transition
//! *sequence*. This is the exact wire the nornir robot-UI harness + test-matrix
//! consume, so one drive here proves the pane across every backend.

use facett_brokkrview::BrokkrView;
use facett_core::{panel, Panel};

#[test]
fn json_drive_switches_views_runs_and_folds_a_finished_run() {
    let mut view = BrokkrView::demo("Brokkr");

    // A run-finished payload that greens a fresh "deploy" step is not in the demo;
    // instead we replay a finished run over the demo's OWN pipeline and assert the
    // roster + log grow and the DAG stays green.
    let run_finished = r#"{
        "run_finished": {
            "run_id": "run-9",
            "pipeline": "nornir-ci",
            "status": "passed",
            "trigger": "manual",
            "sha": "0badf00d9999",
            "passed": 4,
            "total": 4,
            "duration_ms": 9800,
            "steps": { "compile": "passed", "unit": "passed", "lint": "passed", "release": "passed" },
            "dispositions": { "compile": "ran", "unit": "cache-hit" },
            "cached": ["unit"]
        }
    }"#;

    let msgs = [
        r#"{"set_view":"tree"}"#,
        r#"{"set_view":"dag"}"#,
        r#"{"set_view":"roster"}"#,
        r#"{"run":"nornir-ci"}"#,
        run_finished,
        r#"{"select_run":"run-9"}"#,
    ];

    // Drive through the Panel trait object — one snapshot per message, in order.
    let snaps = panel::drive(&mut view as &mut dyn Panel, msgs);
    assert_eq!(snaps.len(), 6, "one state snapshot per driven message");

    // The three view toggles took effect in order.
    assert_eq!(snaps[0]["view"], "tree");
    assert_eq!(snaps[1]["view"], "dag");
    assert_eq!(snaps[2]["view"], "roster");

    // Pressing Run logged the intent (the effect is host-side; the log records it).
    assert!(
        snaps[3]["log"].as_array().unwrap().iter().any(|l| l.as_str().unwrap().contains("running 'nornir-ci'")),
        "Run logged the request"
    );

    // The finished run grew the roster (demo had 3) and stayed all-green.
    assert_eq!(snaps[4]["run_count"], 4, "the finished run was prepended to the roster");
    assert_eq!(snaps[4]["dag"]["all_green"], true);
    assert_eq!(snaps[4]["green_count"], 3, "the two demo greens + the new green run");

    // Selecting the new run set the selection.
    assert_eq!(snaps[5]["selected"], "run-9");
}

#[test]
fn unknown_or_malformed_json_is_a_no_op_not_a_panic() {
    let mut view = BrokkrView::demo("Brokkr");
    let before = Panel::state_json(&view);
    // Not a known message / not even JSON — the update_json seam ignores both.
    Panel::update_json(&mut view, r#"{"nonsense":true}"#);
    Panel::update_json(&mut view, "this is not json [[[");
    let after = Panel::state_json(&view);
    assert_eq!(before, after, "an undriven/malformed message changes nothing");
}