Luigit
repositories / smith

smith

There are many coding harnesses - but this one is fast

owned by admin

smith-cli/tests/e2e_auth.rs

Raw
//! End-to-end credential store behavior through the `smith auth` CLI
//! (`SMH-SPEC-SPEC0001`, Providers: authentication).

use assert_cmd::Command;
use std::path::PathBuf;

fn scratch(name: &str) -> PathBuf {
    std::env::temp_dir().join(format!("smith-auth-test-{name}-{}", std::process::id()))
}

fn smith(name: &str) -> Command {
    let mut command = Command::cargo_bin("smith").unwrap();
    command
        .env("XDG_DATA_HOME", scratch(name))
        .env_remove("ANTHROPIC_API_KEY")
        .env_remove("OPENAI_API_KEY")
        .env_remove("GEMINI_API_KEY");
    command
}

#[test]
fn add_list_remove_round_trips_with_user_only_permissions() {
    let mut add = smith("roundtrip");
    add.args(["auth", "add", "--provider", "anthropic"])
        .write_stdin("sk-test-secret\n")
        .assert()
        .success()
        .stdout("anthropic: stored\n");

    let mut list = smith("roundtrip");
    list.args(["auth", "list"])
        .assert()
        .success()
        .stdout("anthropic: store\n");

    let mut check = smith("roundtrip");
    check
        .args(["auth", "check", "--provider", "anthropic"])
        .assert()
        .success()
        .stdout("anthropic: store\n");

    let mut remove = smith("roundtrip");
    remove
        .args(["auth", "remove", "--provider", "anthropic"])
        .assert()
        .success()
        .stdout("anthropic: removed\n");

    let mut gone = smith("roundtrip");
    gone.args(["auth", "check", "--provider", "anthropic"])
        .assert()
        .failure()
        .stderr(predicates::str::contains(
            "no credential for anthropic (tried store, env ANTHROPIC_API_KEY)",
        ));

    let mut empty = smith("roundtrip");
    empty
        .args(["auth", "remove", "--provider", "anthropic"])
        .assert()
        .failure()
        .stderr(predicates::str::contains(
            "no stored credential for anthropic",
        ));
}

#[test]
fn stored_secret_never_prints_and_permissions_are_user_only() {
    let mut add = smith("hygiene");
    add.args(["auth", "add", "--provider", "openai"])
        .write_stdin("sk-super-secret-value\n")
        .assert()
        .success();

    let secret_file = scratch("hygiene").join("smith/auth/openai");
    #[cfg(unix)]
    {
        use std::os::unix::fs::PermissionsExt;
        let mode = std::fs::metadata(&secret_file)
            .unwrap()
            .permissions()
            .mode();
        assert_eq!(mode & 0o777, 0o600);
    }

    let mut list = smith("hygiene");
    list.args(["auth", "list"])
        .assert()
        .stdout("openai: store\n");
}

#[test]
fn check_reports_environment_source() {
    let mut check = smith("envsource");
    check
        .args(["auth", "check", "--provider", "google"])
        .env("GEMINI_API_KEY", "sk-env")
        .assert()
        .success()
        .stdout("google: env:GEMINI_API_KEY\n");
}