Skip to content

Commit b8761bc

Browse files
committed
test: Add wallets, descriptor, compile & config
- Add integration tests for wallets, descriptor, compile and config modules
1 parent 38a709f commit b8761bc

2 files changed

Lines changed: 170 additions & 10 deletions

File tree

tests/cli.rs

Lines changed: 159 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@
1313
1414
mod common;
1515

16+
use crate::common::BdkCli;
17+
use predicates::prelude::*;
18+
use tempfile::TempDir;
1619
// --- KEY COMMAND TESTS ---
1720
mod test_key {
18-
use crate::common::BdkCli;
19-
use predicates::prelude::*;
21+
use super::*;
2022
use serde_json::Value;
2123

2224
#[test]
2325
fn test_cli_key_generate() {
24-
// compile binary
25-
let cli = BdkCli::new("testnet", None);
26+
let temp_dir = TempDir::new().unwrap();
27+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
2628

2729
cli.key_cmd(&["generate"])
2830
.assert()
@@ -34,7 +36,8 @@ mod test_key {
3436

3537
#[test]
3638
fn test_cli_key_derive() {
37-
let cli = BdkCli::new("testnet", None);
39+
let temp_dir = TempDir::new().unwrap();
40+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
3841

3942
let generate_output = cli
4043
.key_cmd(&["generate"])
@@ -62,8 +65,8 @@ mod test_key {
6265

6366
#[test]
6467
fn test_cli_key_restore() {
65-
// Generate key
66-
let cli = BdkCli::new("testnet", None);
68+
let temp_dir = TempDir::new().unwrap();
69+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
6770

6871
// Execute the command and capture the output
6972
let generate_cmd = cli
@@ -85,7 +88,8 @@ mod test_key {
8588
.expect("Fingerprint missing");
8689

8790
// Restore using the mnemonic
88-
let output_restore = cli.key_cmd(&["restore", "--mnemonic", mnemonic])
91+
let output_restore = cli
92+
.key_cmd(&["restore", "--mnemonic", mnemonic])
8993
.output()
9094
.expect("Failed to execute restore command");
9195
assert!(output_restore.status.success(), "Restore command failed");
@@ -113,3 +117,150 @@ mod test_key {
113117
);
114118
}
115119
}
120+
121+
// --- WALLETS COMMAND TESTS ---
122+
mod test_wallets {
123+
use super::*;
124+
125+
#[test]
126+
fn test_list_wallets_empty() {
127+
let temp_dir = TempDir::new().unwrap();
128+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
129+
130+
let mut cmd = cli.build_base_cmd();
131+
cmd.arg("wallets");
132+
133+
cmd.assert()
134+
.failure()
135+
.stderr(predicate::str::contains("No wallets configured yet."));
136+
}
137+
}
138+
139+
// --- DESCRIPTOR COMMAND TESTS ---
140+
mod test_descriptor {
141+
use super::*;
142+
143+
#[test]
144+
fn test_generate_new_descriptor() {
145+
let temp_dir = TempDir::new().unwrap();
146+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
147+
148+
// Run `bdk-cli descriptor --type tr`
149+
cli.cmd("descriptor", &["--type", "tr"])
150+
.assert()
151+
.success()
152+
.stdout(predicate::str::contains("\"public_descriptors\":"))
153+
.stdout(predicate::str::contains("\"private_descriptors\":"))
154+
.stdout(predicate::str::contains("\"mnemonic\":"))
155+
.stdout(predicate::str::contains("\"fingerprint\":"));
156+
}
157+
}
158+
159+
// --- COMPILE COMMAND TESTS ---
160+
#[cfg(feature = "compiler")]
161+
mod test_compile {
162+
use super::*;
163+
164+
#[test]
165+
fn test_compile_valid_policy() {
166+
let temp_dir = TempDir::new().unwrap();
167+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
168+
169+
let policy = "pk(02e5b88fdb71c696e1a473f309a47535b7190e21a22bd25e7fc8bd055db3bba12f)";
170+
171+
cli.cmd("compile", &[policy, "--type", "wsh"])
172+
.assert()
173+
.success()
174+
.stdout(predicate::str::contains("\"descriptor\":"))
175+
.stdout(predicate::str::contains("wsh("));
176+
}
177+
178+
#[test]
179+
fn test_compile_invalid_policy() {
180+
let temp_dir = TempDir::new().unwrap();
181+
let cli = BdkCli::new("testnet", Some(temp_dir.path().to_path_buf()));
182+
183+
cli.cmd("compile", &["invalid_policy", "--type", "wsh"])
184+
.assert()
185+
.failure()
186+
.stderr(predicate::str::contains("Invalid policy"));
187+
}
188+
}
189+
190+
// --- CONFIG COMMAND TESTS ---
191+
#[cfg(feature = "rpc")]
192+
mod test_config {
193+
use super::*;
194+
use serde_json::Value;
195+
196+
#[test]
197+
fn test_save_and_read_wallet_config() {
198+
let temp_dir = TempDir::new().unwrap();
199+
let cli = BdkCli::new("regtest", Some(temp_dir.path().to_path_buf()));
200+
201+
let desc = cli
202+
.cmd("descriptor", &["--type", "tr"])
203+
.output()
204+
.expect("Command to generate descriptors failed");
205+
206+
let desc_values: Value =
207+
serde_json::from_slice(&desc.stdout).expect("Invalid JSON from output descriptor");
208+
209+
let pub_desc = &desc_values["public_descriptors"];
210+
211+
let ext_desc = pub_desc["external"].as_str().unwrap();
212+
let int_desc = pub_desc["internal"].as_str().unwrap();
213+
let wallet_name = "test_config_wallet";
214+
let client_type = "rpc";
215+
let db = "sqlite";
216+
let url = "http://localhost:18443";
217+
218+
let mut cmd_init = cli.build_base_cmd();
219+
cmd_init
220+
.arg("wallet")
221+
.arg("--wallet")
222+
.arg(wallet_name)
223+
.arg("config")
224+
.arg("--ext-descriptor")
225+
.arg(ext_desc)
226+
.arg("--int-descriptor")
227+
.arg(int_desc)
228+
.arg("--client-type")
229+
.arg(client_type)
230+
.arg("--database-type")
231+
.arg(db)
232+
.arg("--url")
233+
.arg(url);
234+
235+
cmd_init.assert().success();
236+
237+
// verify saved config
238+
let mut cmd = cli.build_base_cmd();
239+
cmd.arg("wallets");
240+
241+
let output = cmd.output().expect("Failed to execute wallets command");
242+
243+
assert!(
244+
output.status.success(),
245+
"The wallets command failed to execute"
246+
);
247+
248+
let json_output: Value =
249+
serde_json::from_slice(&output.stdout).expect("CLI did not output valid JSON");
250+
251+
let config = &json_output[wallet_name];
252+
253+
assert!(
254+
!config.is_null(),
255+
"The wallet {wallet_name} was not found in the root JSON object"
256+
);
257+
258+
assert_eq!(config["wallet"].as_str().unwrap(), wallet_name);
259+
assert_eq!(config["network"].as_str().unwrap(), "regtest");
260+
assert_eq!(config["database_type"].as_str().unwrap(), db);
261+
assert_eq!(config["client_type"].as_str().unwrap(), client_type);
262+
assert_eq!(config["server_url"].as_str().unwrap(), url);
263+
assert_eq!(config["ext_descriptor"].as_str().unwrap(), ext_desc);
264+
assert_eq!(config["int_descriptor"].as_str().unwrap(), int_desc);
265+
}
266+
}

tests/common/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl BdkCli {
3737
}
3838

3939
/// Creates the base assert_cmd::Command with the global flags pre-loaded
40-
fn build_base_cmd(&self) -> Command {
40+
pub fn build_base_cmd(&self) -> Command {
4141
let mut cmd = Command::cargo_bin("bdk-cli").expect("bdk-cli binary must compile");
4242

4343
cmd.arg("--network").arg(&self.network);
@@ -53,15 +53,24 @@ impl BdkCli {
5353
cmd
5454
}
5555

56+
/// Returns a pre-configured Command builder for any top-level subcommand
57+
pub fn cmd(&self, subcommand: &str, args: &[&str]) -> Command {
58+
let mut cmd = self.build_base_cmd();
59+
cmd.arg(subcommand);
60+
cmd.args(args);
61+
cmd
62+
}
63+
5664
/// Returns a pre-configured Command builder for `key` operations
5765
pub fn key_cmd(&self, args: &[&str]) -> Command {
5866
let mut cmd = self.build_base_cmd();
5967
cmd.arg("key");
60-
cmd.args(args);
68+
cmd.args(args);
6169
cmd
6270
}
6371

6472
/// Returns a pre-configured Command builder for `wallet` operations
73+
#[allow(unused)]
6574
pub fn wallet_cmd(&self, args: &[&str]) -> Command {
6675
let mut cmd = self.build_base_cmd();
6776
cmd.arg("wallet");

0 commit comments

Comments
 (0)