use assert_cmd::Command;
use predicates::prelude::*;
use std::path::PathBuf;
fn sdkt_isolated(dir: &std::path::Path) -> Command {
let mut cmd = Command::cargo_bin("sdkt").unwrap();
cmd.env("SDKT_IDENTITY_DIR", dir.join("identity"));
cmd.env("SDKT_NETWORK_DIR", dir.join("network"));
cmd
}
fn fixture_wasm() -> PathBuf {
let manifest = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let ws_root = manifest.ancestors().nth(2).unwrap_or(&manifest);
ws_root
.join("crates/sdkt-cli/tests/fixtures/us_new.wasm")
.to_path_buf()
}
#[test]
fn deploy_invalid_salt_non_hex_rejected() {
let dir = std::env::temp_dir().join(format!(
"sdkt-salt-auto-{}-nonhex",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::create_dir_all(&dir);
let wasm = fixture_wasm();
if !wasm.exists() {
eprintln!("Skipping: fixture WASM not found at {:?}", wasm);
return;
}
sdkt_isolated(&dir)
.args([
"deploy",
"--wasm",
wasm.to_str().unwrap(),
"--salt",
"not_a_hex_string!",
"--identity",
"default",
])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid --salt"));
}
#[test]
fn deploy_invalid_salt_wrong_length_rejected() {
let dir = std::env::temp_dir().join(format!(
"sdkt-salt-auto-{}-len",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::create_dir_all(&dir);
let wasm = fixture_wasm();
if !wasm.exists() {
eprintln!("Skipping: fixture WASM not found at {:?}", wasm);
return;
}
sdkt_isolated(&dir)
.args([
"deploy",
"--wasm",
wasm.to_str().unwrap(),
"--salt",
"00112233445566778899aabbccddeeff0011",
"--identity",
"default",
])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid --salt"));
}
#[test]
fn deploy_40char_nonhex_salt_rejected_with_hex_error() {
let dir = std::env::temp_dir().join(format!(
"sdkt-salt-auto-{}-40hex",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::create_dir_all(&dir);
let wasm = fixture_wasm();
if !wasm.exists() {
eprintln!("Skipping: fixture WASM not found at {:?}", wasm);
return;
}
let bad_salt = "z".repeat(40);
sdkt_isolated(&dir)
.args([
"deploy",
"--wasm",
wasm.to_str().unwrap(),
"--salt",
bad_salt.as_str(),
"--identity",
"default",
])
.assert()
.failure()
.stderr(predicate::str::contains("not a hex digit"));
}
#[test]
fn deploy_explicit_salt_help_works() {
let dir = std::env::temp_dir().join(format!(
"sdkt-salt-auto-{}-help",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::create_dir_all(&dir);
sdkt_isolated(&dir)
.args(["deploy", "--help"])
.assert()
.success()
.stdout(predicate::str::contains("--salt"))
.stdout(predicate::str::contains("--wasm"));
}
#[test]
fn deploy_without_salt_flag_shows_optional() {
let dir = std::env::temp_dir().join(format!(
"sdkt-salt-auto-{}-optional",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::create_dir_all(&dir);
let output = sdkt_isolated(&dir)
.args(["deploy", "--help"])
.output()
.unwrap();
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(stdout.contains("--salt"), "Help should mention --salt");
}
#[test]
fn deploy_explicit_salt_parses_correctly() {
let dir = std::env::temp_dir().join(format!(
"sdkt-salt-auto-{}-parse",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
let _ = std::fs::create_dir_all(&dir);
let wasm = fixture_wasm();
if !wasm.exists() {
eprintln!("Skipping: fixture WASM not found at {:?}", wasm);
return;
}
let output = sdkt_isolated(&dir)
.args([
"deploy",
"--wasm",
wasm.to_str().unwrap(),
"--salt",
"00112233445566778899aabbccddeeff00112233",
"--identity",
"default",
])
.output()
.unwrap();
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.contains("Invalid --salt"),
"Valid salt should not be rejected: {}",
stderr
);
}