|
| 1 | +//! Integration tests for the Bitcoin RPC client. |
| 2 | +//! |
| 3 | +//! These tests require a running Bitcoin Core node in regtest mode. |
| 4 | +//! |
| 5 | +//! Setup: |
| 6 | +//! ```bash |
| 7 | +//! bitcoind -regtest -rpcuser=bitcoin -rpcpassword=bitcoin -rpcport=18443 |
| 8 | +//! ``` |
| 9 | +
|
| 10 | +use bdk_rpc_client::{Auth, Client, Error}; |
| 11 | +use corepc_types::bitcoin::BlockHash; |
| 12 | +use std::path::PathBuf; |
| 13 | + |
| 14 | +/// Helper to get the test RPC URL |
| 15 | +fn test_url() -> String { |
| 16 | + std::env::var("BITCOIN_RPC_URL").unwrap_or_else(|_| "http://localhost:18443".to_string()) |
| 17 | +} |
| 18 | + |
| 19 | +/// Helper to get test credentials |
| 20 | +fn test_auth() -> Auth { |
| 21 | + let user = std::env::var("BITCOIN_RPC_USER").unwrap_or_else(|_| "bitcoin".to_string()); |
| 22 | + let pass = std::env::var("BITCOIN_RPC_PASS").unwrap_or_else(|_| "bitcoin".to_string()); |
| 23 | + Auth::UserPass(user, pass) |
| 24 | +} |
| 25 | + |
| 26 | +#[test] |
| 27 | +#[ignore] |
| 28 | +fn test_client_with_user_pass() { |
| 29 | + let client = Client::with_auth(&test_url(), test_auth()).expect("failed to create client"); |
| 30 | + |
| 31 | + let result = client |
| 32 | + .get_best_block_hash() |
| 33 | + .expect("failed to call getblockchaininfo"); |
| 34 | + |
| 35 | + assert_eq!( |
| 36 | + result.to_string().len(), |
| 37 | + 64, |
| 38 | + "block hash should be 64 characters" |
| 39 | + ); |
| 40 | + assert!( |
| 41 | + result.to_string().chars().all(|c| c.is_ascii_hexdigit()), |
| 42 | + "hash should only contain hex digits" |
| 43 | + ); |
| 44 | +} |
| 45 | + |
| 46 | +#[test] |
| 47 | +fn test_auth_none_returns_error() { |
| 48 | + let result = Client::with_auth(&test_url(), Auth::None); |
| 49 | + |
| 50 | + assert!(result.is_err()); |
| 51 | + match result { |
| 52 | + Err(Error::MissingAuthentication) => (), |
| 53 | + _ => panic!("expected MissingAuthentication error"), |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +#[test] |
| 58 | +#[ignore] |
| 59 | +fn test_invalid_credentials() { |
| 60 | + let client = Client::with_auth( |
| 61 | + &test_url(), |
| 62 | + Auth::UserPass("wrong".to_string(), "credentials".to_string()), |
| 63 | + ) |
| 64 | + .expect("client creation should succeed"); |
| 65 | + |
| 66 | + let result: Result<BlockHash, Error> = client.get_best_block_hash(); |
| 67 | + |
| 68 | + assert!(result.is_err()); |
| 69 | +} |
| 70 | + |
| 71 | +#[test] |
| 72 | +fn test_invalid_cookie_file() { |
| 73 | + let cookie_path = PathBuf::from("/nonexistent/path/to/cookie"); |
| 74 | + let result = Client::with_auth(&test_url(), Auth::CookieFile(cookie_path)); |
| 75 | + |
| 76 | + assert!(result.is_err()); |
| 77 | + match result { |
| 78 | + Err(Error::InvalidCookieFile) => (), |
| 79 | + Err(Error::Io(_)) => (), |
| 80 | + _ => panic!("expected InvalidCookieFile or Io error"), |
| 81 | + } |
| 82 | +} |
| 83 | + |
| 84 | +#[test] |
| 85 | +#[ignore] |
| 86 | +fn test_client_with_custom_transport() { |
| 87 | + use jsonrpc::http::minreq_http::Builder; |
| 88 | + |
| 89 | + let transport = Builder::new() |
| 90 | + .url(&test_url()) |
| 91 | + .expect("invalid URL") |
| 92 | + .timeout(std::time::Duration::from_secs(30)) |
| 93 | + .basic_auth("bitcoin".to_string(), Some("bitcoin".to_string())) |
| 94 | + .build(); |
| 95 | + |
| 96 | + let client = Client::with_transport(transport); |
| 97 | + |
| 98 | + let result = client |
| 99 | + .get_best_block_hash() |
| 100 | + .expect("failed to call getblockchaininfo"); |
| 101 | + |
| 102 | + assert_eq!( |
| 103 | + result.to_string().len(), |
| 104 | + 64, |
| 105 | + "block hash should be 64 characters" |
| 106 | + ); |
| 107 | +} |
0 commit comments