facett-warehousedeck/tests/robot.rs
//! **Robot JSON-drive scenario for the warehouse multi-pane deck**, driven
//! through the SHARED generic-Facet probe in `facett_core::harness` (no
//! hand-rolled render+emit boilerplate). The pane's `update_json` robot seam was a
//! **dead no-op** — the `impl_facet_via_elm!` bridge does not generate one and the
//! deck never overrode `Facet::update_json`, so a headless robot could not drive
//! it (only the in-view `ui_render` self-cell existed). This test (a) proves the
//! now-LIVE seam end-to-end — feed a scripted message list, watch `state_json`
//! transition — and (b) adds the shared probe's `headless_render` +
//! `responds_to_input` functional cells via `facett_core::testmatrix::probe_and_emit`
//! (a no-op unless built with `--features testmatrix`). The `responds_to_input`
//! aspect is NEW coverage: it would go RED if the JSON drive seam regressed back
//! to a no-op. See `.nornir/facett-platform-gaps.md`.
use facett_warehousedeck::{PaneData, WarehouseDeck};
#[test]
fn robot_json_drive_scenario() {
let mut view = WarehouseDeck::new("🏢 Warehouse");
view.add("alpha", PaneData::Blob { text: "a".into() });
view.add("beta", PaneData::Blob { text: "b".into() });
// Focus a pane, then clear the focus — the exact JSON a headless robot sends
// through the `update_json` seam (serde-tagged, no concrete Msg type).
let script = [
r#"{"select_pane":"alpha"}"#, // focus the alpha pane
r#""clear_selection""#, // clear the focus
];
let probe = facett_core::testmatrix::probe_and_emit("facett-warehousedeck", &mut view, &script);
// The initial render drew real geometry (the pane wall) over non-empty state.
assert!(probe.drew(), "the deck wall must tessellate to vertices");
assert!(probe.cardinality() > 0, "state_json reports the panes");
// The input surface is LIVE: at least one scripted message moved state.
assert!(probe.responded(), "update_json must drive state — a dead seam is a regression");
// Pane-specific: focusing lands the pane id in `selected`, clearing removes it.
assert_eq!(probe.steps[0].state["selected"], "alpha", "select_pane focuses alpha");
assert!(probe.steps[0].changed, "select_pane moved state");
assert_eq!(probe.final_state["selected"], serde_json::Value::Null, "clear_selection cleared it");
}