From: Vihiga Tyonum Date: Fri, 12 Jun 2026 07:05:06 +0000 (+0100) Subject: test: Add wallets, descriptor, compile & config X-Git-Tag: v4.0.0~5^2~12 X-Git-Url: http://internal-gitweb-vhost/blockdata/script/encode/-script/enum.EncodeError.html?a=commitdiff_plain;h=b8761bc944fb776870d92e208848f7050b35193d;p=bdk-cli test: Add wallets, descriptor, compile & config - Add integration tests for wallets, descriptor, compile and config modules --- diff --git a/tests/cli.rs b/tests/cli.rs index db97d65..955d958 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -13,16 +13,18 @@ mod common; +use crate::common::BdkCli; +use predicates::prelude::*; +use tempfile::TempDir; // --- KEY COMMAND TESTS --- mod test_key { - use crate::common::BdkCli; - use predicates::prelude::*; + use super::*; use serde_json::Value; #[test] fn test_cli_key_generate() { - // compile binary - let cli = BdkCli::new("testnet", None); + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); cli.key_cmd(&["generate"]) .assert() @@ -34,7 +36,8 @@ mod test_key { #[test] fn test_cli_key_derive() { - let cli = BdkCli::new("testnet", None); + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); let generate_output = cli .key_cmd(&["generate"]) @@ -62,8 +65,8 @@ mod test_key { #[test] fn test_cli_key_restore() { - // Generate key - let cli = BdkCli::new("testnet", None); + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); // Execute the command and capture the output let generate_cmd = cli @@ -85,7 +88,8 @@ mod test_key { .expect("Fingerprint missing"); // Restore using the mnemonic - let output_restore = cli.key_cmd(&["restore", "--mnemonic", mnemonic]) + let output_restore = cli + .key_cmd(&["restore", "--mnemonic", mnemonic]) .output() .expect("Failed to execute restore command"); assert!(output_restore.status.success(), "Restore command failed"); @@ -113,3 +117,150 @@ mod test_key { ); } } + +// --- WALLETS COMMAND TESTS --- +mod test_wallets { + use super::*; + + #[test] + fn test_list_wallets_empty() { + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); + + let mut cmd = cli.build_base_cmd(); + cmd.arg("wallets"); + + cmd.assert() + .failure() + .stderr(predicate::str::contains("No wallets configured yet.")); + } +} + +// --- DESCRIPTOR COMMAND TESTS --- +mod test_descriptor { + use super::*; + + #[test] + fn test_generate_new_descriptor() { + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); + + // Run `bdk-cli descriptor --type tr` + cli.cmd("descriptor", &["--type", "tr"]) + .assert() + .success() + .stdout(predicate::str::contains("\"public_descriptors\":")) + .stdout(predicate::str::contains("\"private_descriptors\":")) + .stdout(predicate::str::contains("\"mnemonic\":")) + .stdout(predicate::str::contains("\"fingerprint\":")); + } +} + +// --- COMPILE COMMAND TESTS --- +#[cfg(feature = "compiler")] +mod test_compile { + use super::*; + + #[test] + fn test_compile_valid_policy() { + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); + + let policy = "pk(02e5b88fdb71c696e1a473f309a47535b7190e21a22bd25e7fc8bd055db3bba12f)"; + + cli.cmd("compile", &[policy, "--type", "wsh"]) + .assert() + .success() + .stdout(predicate::str::contains("\"descriptor\":")) + .stdout(predicate::str::contains("wsh(")); + } + + #[test] + fn test_compile_invalid_policy() { + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf())); + + cli.cmd("compile", &["invalid_policy", "--type", "wsh"]) + .assert() + .failure() + .stderr(predicate::str::contains("Invalid policy")); + } +} + +// --- CONFIG COMMAND TESTS --- +#[cfg(feature = "rpc")] +mod test_config { + use super::*; + use serde_json::Value; + + #[test] + fn test_save_and_read_wallet_config() { + let temp_dir = TempDir::new().unwrap(); + let cli = BdkCli::new("regtest", Some(temp_dir.path().to_path_buf())); + + let desc = cli + .cmd("descriptor", &["--type", "tr"]) + .output() + .expect("Command to generate descriptors failed"); + + let desc_values: Value = + serde_json::from_slice(&desc.stdout).expect("Invalid JSON from output descriptor"); + + let pub_desc = &desc_values["public_descriptors"]; + + let ext_desc = pub_desc["external"].as_str().unwrap(); + let int_desc = pub_desc["internal"].as_str().unwrap(); + let wallet_name = "test_config_wallet"; + let client_type = "rpc"; + let db = "sqlite"; + let url = "http://localhost:18443"; + + let mut cmd_init = cli.build_base_cmd(); + cmd_init + .arg("wallet") + .arg("--wallet") + .arg(wallet_name) + .arg("config") + .arg("--ext-descriptor") + .arg(ext_desc) + .arg("--int-descriptor") + .arg(int_desc) + .arg("--client-type") + .arg(client_type) + .arg("--database-type") + .arg(db) + .arg("--url") + .arg(url); + + cmd_init.assert().success(); + + // verify saved config + let mut cmd = cli.build_base_cmd(); + cmd.arg("wallets"); + + let output = cmd.output().expect("Failed to execute wallets command"); + + assert!( + output.status.success(), + "The wallets command failed to execute" + ); + + let json_output: Value = + serde_json::from_slice(&output.stdout).expect("CLI did not output valid JSON"); + + let config = &json_output[wallet_name]; + + assert!( + !config.is_null(), + "The wallet {wallet_name} was not found in the root JSON object" + ); + + assert_eq!(config["wallet"].as_str().unwrap(), wallet_name); + assert_eq!(config["network"].as_str().unwrap(), "regtest"); + assert_eq!(config["database_type"].as_str().unwrap(), db); + assert_eq!(config["client_type"].as_str().unwrap(), client_type); + assert_eq!(config["server_url"].as_str().unwrap(), url); + assert_eq!(config["ext_descriptor"].as_str().unwrap(), ext_desc); + assert_eq!(config["int_descriptor"].as_str().unwrap(), int_desc); + } +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs index e957584..4dbd261 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -37,7 +37,7 @@ impl BdkCli { } /// Creates the base assert_cmd::Command with the global flags pre-loaded - fn build_base_cmd(&self) -> Command { + pub fn build_base_cmd(&self) -> Command { let mut cmd = Command::cargo_bin("bdk-cli").expect("bdk-cli binary must compile"); cmd.arg("--network").arg(&self.network); @@ -53,15 +53,24 @@ impl BdkCli { cmd } + /// Returns a pre-configured Command builder for any top-level subcommand + pub fn cmd(&self, subcommand: &str, args: &[&str]) -> Command { + let mut cmd = self.build_base_cmd(); + cmd.arg(subcommand); + cmd.args(args); + cmd + } + /// Returns a pre-configured Command builder for `key` operations pub fn key_cmd(&self, args: &[&str]) -> Command { let mut cmd = self.build_base_cmd(); cmd.arg("key"); - cmd.args(args); + cmd.args(args); cmd } /// Returns a pre-configured Command builder for `wallet` operations + #[allow(unused)] pub fn wallet_cmd(&self, args: &[&str]) -> Command { let mut cmd = self.build_base_cmd(); cmd.arg("wallet");