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

nordisk/gunnar

crates/gunnar-cli/tests/no_unlock_helper.rs

//! **The local unlock helper is gone** (CRYPT-YUBI, owner 2026-10-26: "the
//! local helper: off with it"). `gunnar unlock` was a 127.0.0.1 agent that
//! unwrapped key rings for the browser console. The browser now opens a
//! person's encryption key with their security key (WebAuthn PRF), in the tab;
//! the CLI's own `gunnar crypt unlock` stays.

#![cfg(feature = "client")]

use std::path::Path;
use std::process::Command;

/// ★ `gunnar unlock` is no command any more; `gunnar crypt unlock` is.
#[test]
fn gunnar_unlock_is_no_command() {
    let out = Command::new(env!("CARGO_BIN_EXE_gunnar-cli"))
        .args(["unlock", "--port", "0"])
        .output()
        .expect("gunnar runs");
    assert!(
        !out.status.success(),
        "gunnar unlock still runs: {}",
        String::from_utf8_lossy(&out.stdout)
    );
    let said = String::from_utf8_lossy(&out.stderr);
    assert!(
        said.contains("unrecognized subcommand") || said.contains("unexpected argument"),
        "{said}"
    );
    let help = Command::new(env!("CARGO_BIN_EXE_gunnar-cli"))
        .args(["crypt", "unlock", "--help"])
        .output()
        .expect("gunnar runs");
    assert!(help.status.success(), "`gunnar crypt unlock` stays");
}

fn sources(dir: &Path, out: &mut Vec<std::path::PathBuf>) {
    for e in std::fs::read_dir(dir).into_iter().flatten().flatten() {
        let p = e.path();
        if p.is_dir() {
            if p.file_name()
                .is_some_and(|n| n == "target" || n == "tests" || n == "vendor")
            {
                continue;
            }
            sources(&p, out);
        } else if p.extension().is_some_and(|x| x == "rs") {
            out.push(p);
        }
    }
}

/// ★ Nothing in gunnar serves the helper's routes: no source names them.
#[test]
fn no_source_serves_the_helpers_routes() {
    let crates = Path::new(env!("CARGO_MANIFEST_DIR"))
        .parent()
        .expect("crates/");
    let mut files = Vec::new();
    sources(crates, &mut files);
    assert!(
        files.len() > 100,
        "the workspace's sources were found ({})",
        files.len()
    );
    let routes = [
        concat!("/v1/", "unwrap"),
        concat!("/v1/", "pair"),
        concat!("127.0.0.1:", "7471"),
    ];
    let hits: Vec<String> = files
        .iter()
        .filter_map(|f| {
            let text = std::fs::read_to_string(f).ok()?;
            let found: Vec<&str> = routes
                .iter()
                .copied()
                .filter(|r| text.contains(r))
                .collect();
            (!found.is_empty()).then(|| format!("{} names {found:?}", f.display()))
        })
        .collect();
    assert!(
        hits.is_empty(),
        "the unlock helper's routes are still served: {hits:#?}"
    );
}