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_dupes_reads_lens.rs

//! **ROBOT-UI: the 🧬 Dupes tab READS `lens_similar_code` over the wire — it does not
//! fold.**
//!
//! Since the lens chain landed, the duplicate answer is computed by a jera job and read
//! off the `lens_similar_code` warehouse table over the SAME thin `Mimir.SimilarCode`
//! RPC seam the Lenses pane's `SimilarCode` view uses. This drove the SHIPPED Dupes pane
//! (`dupes::dupes_pane` / `DupesPane::live`) through the REAL widget tree against an
//! in-process mock `Mimir` server (`testkit::spawn_mock_mimir` — a real tonic server on
//! an ephemeral port, NOT a stub), and asserts APPLIED output: the pane reads itself on
//! open, off the egui thread, and carries the server's answer verbatim.
//!
//! RED-first, the fold path is GONE: the mock's `similar_code` body carries
//! `__over_wire__: true` — a marker NO local `detect()` fold could ever synthesise — so
//! the pane showing it proves the read path. Before this refactor the tab folded locally
//! over `Warehouse.Scan`; it could not produce the sentinel and `folded_locally` was the
//! whole findings path, not an apply-only escape hatch.

use std::time::{Duration, Instant};

use dwarves_gui::dupes::{dupes_pane, DupesPane};
use facett_core::Facet;
use nornir_robotui::egui_kittest::Harness;
use nornir_robotui::{Observable, RobotSession};
use nornir_warehouse_embed::testkit::{spawn_mock_mimir, MockMimir};
use serde_json::json;

struct DupesApp(DupesPane);
impl Observable for DupesApp {
    fn state_json(&self) -> serde_json::Value {
        Facet::state_json(&self.0)
    }
}

/// The lens reply is held this long, so the open frame must come back BEFORE it — proving
/// the read ran on a worker, not the egui thread.
const REPLY_DELAY: Duration = Duration::from_millis(400);

/// A `Mimir.SimilarCode` answer in nornir's Mímir v2 envelope: ranked clusters, the
/// feeds it read, `lens_meta.state` + an over-wire sentinel a LOCAL fold could never make.
fn lens_body() -> String {
    json!({
        "__over_wire__": true,
        "kind": "similar_code",
        "cluster_count": 2,
        "cluster_count_total": 2,
        "clusters_shown": 2,
        "top_clusters": [
            { "canonical": "nornir#progress", "size": 2, "avg_cosine": 0.99, "structural": 0.9, "score": 1.98 },
            { "canonical": "korp#config", "size": 3, "avg_cosine": 0.94, "structural": 0.7, "score": 2.82 }
        ],
        "evidence_note": "similar_code: 2 cluster(s). MISSING: `embeddings` carried no row for 1 repo.",
        "feeds": [ { "table": "embeddings", "rows": 0, "root": "", "missing": true } ],
        "lens_meta": { "state": "partial", "lens": "similar_code", "repo_scope": "", "gaps": [], "lower_bounds": [], "ms": 4 }
    })
    .to_string()
}

#[allow(unused_variables)]
fn matrix(check: &str, ok: bool, detail: &str) {
    #[cfg(feature = "testmatrix")]
    nornir_testmatrix::functional_status("dwarves-gui", check, ok, detail);
}

#[test]
fn the_dupes_tab_reads_similarcode_over_the_wire_and_never_folds() {
    let srv = spawn_mock_mimir(MockMimir {
        reply_delay: REPLY_DELAY,
        similar_code: lens_body(),
        ..Default::default()
    });
    // The SHIPPED constructor — the pane a user actually gets. Its findings reader is the
    // thin `Mimir.SimilarCode` RPC pointed at the in-proc server.
    let pane = dupes_pane(&srv.endpoint, "", "nordisk");
    let harness = Harness::builder()
        .with_size(nornir_robotui::egui::Vec2::new(1200.0, 900.0))
        .build_ui_state(
            |ui, app: &mut DupesApp| Facet::ui(&mut app.0, ui),
            DupesApp(pane),
        );
    let mut robot = RobotSession::new(harness, "dwarves-gui");

    // THE OPEN — one frame, timed. The pane must have STARTED its read (no button) and
    // given the frame back before the server answers.
    let t0 = Instant::now();
    robot.run(1);
    let held = t0.elapsed();

    assert_eq!(
        robot.state_at("/pending"),
        Some(json!(true)),
        "the pane reads ITSELF on open — the chain folded the answer, so a button is friction (state {})",
        robot.state_at("").map(|v| v.to_string()).unwrap_or_default()
    );
    assert_eq!(
        robot.state_at("/scanned"),
        Some(json!(false)),
        "not read yet — the server holds its reply"
    );
    assert!(
        held < REPLY_DELAY,
        "the open frame took {held:?} — longer than one server reply ({REPLY_DELAY:?}); the read ran on the egui thread"
    );

    // ── THE BUTTONS. `Scan` AND `⟳` are both gone (`768983f`, 2026-08-22, the owner's
    //    call — quoted at `dupes.rs:676`): this is the Similar Code sub-view under
    //    Lenses, the jera chain folds off populate in the background, and the pane reads
    //    itself on open (asserted above). The ONE action left is the apply escape hatch,
    //    which the lens result genuinely cannot carry.
    //
    //    This file asked for `⟳` for a day after the button was removed. The absence is
    //    asked of the tree (`node_id`, no mutation) and it sits NEXT TO the control that
    //    IS there — an empty AccessKit tree would satisfy the absence just as well, so
    //    the escape hatch below is what keeps it from being a hollow guard.
    assert!(
        robot.node_id("⟳").is_none(),
        "the ⟳ re-read button is BACK in the AccessKit tree — the pane reads itself now and \
         a button is friction (dupes.rs:676)"
    );
    assert!(
        robot.click_label("⚒ Fold locally for apply").is_ok(),
        "the apply escape hatch is present (the lens carries no plan, so apply folds \
         locally) — and it is the NON-VACUITY control for the ⟳ absence above"
    );

    // Keep painting; the worker lands the reading.
    let deadline = Instant::now() + Duration::from_secs(30);
    while robot.state_at("/pending") == Some(json!(true)) && Instant::now() < deadline {
        robot.run(1);
        std::thread::sleep(Duration::from_millis(25));
    }

    // ── the reading LANDED, and it is the SERVER's answer, not a local fold ──────────
    assert_eq!(
        robot.state_at("/pending"),
        Some(json!(false)),
        "the read must land within 30 s"
    );
    assert_eq!(
        robot.state_at("/scanned"),
        Some(json!(true)),
        "the reading landed"
    );
    // `__over_wire__` is the whole proof: no `detect()` fold can synthesise it.
    assert_eq!(
        robot.state_at("/reading/__over_wire__"),
        Some(json!(true)),
        "the findings are READ from lens_similar_code over the wire, NOT folded locally: {}",
        robot
            .state_at("/reading")
            .map(|v| v.to_string())
            .unwrap_or_default()
    );
    assert_eq!(
        robot.state_at("/cluster_count_total"),
        Some(json!(2)),
        "the server's cluster count, verbatim"
    );
    assert_eq!(
        robot.state_at("/reading/top_clusters/0/canonical"),
        Some(json!("nornir#progress")),
        "the ranked clusters cross the wire intact"
    );

    // The fold path is GONE from the findings: detect() was never called on open.
    assert_eq!(
        robot.state_at("/folded_locally"),
        Some(json!(false)),
        "the findings path never folds locally"
    );
    assert_eq!(
        robot.state_at("/apply_plan_count"),
        Some(json!(0)),
        "no local fold ⇒ no plan (until the escape hatch)"
    );

    // PROVENANCE is derived off lens_meta.state and honest — what the answer rests on.
    let prov = robot
        .state_at("/provenance")
        .and_then(|v| v.as_str().map(String::from))
        .unwrap_or_default();
    assert!(prov.contains("similar_code"), "{prov}");
    assert!(
        prov.contains("partial (lower bound)"),
        "the header names the answer's own state: {prov}"
    );
    assert!(
        prov.contains("feeds missing: embeddings"),
        "…and the missing feed, never hidden: {prov}"
    );

    drop(srv);

    matrix(
        "dupes_tab_reads_similarcode_over_the_wire",
        true,
        "the shipped 🧬 Dupes pane (dupes_pane / DupesPane::live), driven through the real \
         widget tree against an in-proc Mimir.SimilarCode server (testkit::spawn_mock_mimir \
         with reply_delay), reads lens_similar_code on OPEN off the egui thread (pending=true, \
         frame returns before the reply) and carries the server's answer verbatim — an \
         __over_wire__ sentinel no local fold can make — with folded_locally=false and a \
         lens_meta.state-derived provenance header (partial (lower bound) · feeds missing). \
         The old local Warehouse.Scan fold is gone from the findings path.",
    );
}