Last active
January 13, 2024 05:05
-
-
Save sgerodes/aef60ce1dd2dda681c45c59d6b9357e0 to your computer and use it in GitHub Desktop.
PBA assignment 2 tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use super::*; | |
use super::test_utils::*; | |
pub fn wallet_with_alice() -> Wallet { | |
Wallet::new(vec![Address::Alice].into_iter()) | |
} | |
mod tests { | |
use super::*; | |
#[test] | |
fn genesis_block_has_always_same_hash() { | |
// just ot check if two different genesis block object will equal in their id hash | |
assert_eq!(Block::genesis().id(), Block::genesis().id()); | |
} | |
/// Test: ensure_error_is_returned_if_no_address_is_submitted | |
/// Purpose: To validate that the wallet, when initialized without any addresses, handles | |
/// various operations correctly by returning either 'NoOwnedAddresses' or 'ForeignAddress' errors. | |
/// Cases Tested: | |
/// 1. total_assets_of for a non-existent address should return a relevant error. | |
/// 2. all_coins_of for a non-existent address should return a relevant error. | |
/// 3. create_manual_transaction with an empty address list should return 'NoOwnedAddresses'. | |
/// 4. create_automatic_transaction with an empty address list should return 'NoOwnedAddresses'. | |
#[test] | |
fn ensure_error_is_returned_if_no_address_is_submitted() { | |
let mut node = MockNode::new(); | |
let wallet = Wallet::new(std::iter::empty()); | |
let b1 = node.add_block_as_best(Block::genesis().id(), vec![]); | |
fn is_either_not_owned_or_foreign(error: WalletError) -> bool { | |
match error { | |
WalletError::NoOwnedAddresses | WalletError::ForeignAddress => true, | |
_ => false, | |
} | |
} | |
assert!(wallet.total_assets_of(Address::Alice).err().map_or(false, is_either_not_owned_or_foreign)); | |
assert!(wallet.all_coins_of(Address::Alice).err().map_or(false, is_either_not_owned_or_foreign)); | |
//assert_eq!(wallet.coin_details(&CoinId(1)), Err(WalletError::NoOwnedAddresses)); | |
assert_eq!(wallet.create_manual_transaction(vec![], vec![]), Err(WalletError::NoOwnedAddresses)); | |
assert_eq!(wallet.create_automatic_transaction(Address::Alice, 1, 1), Err(WalletError::NoOwnedAddresses)); | |
} | |
/// Purpose: Ensure the wallet returns 'OutputsExceedInputs' error when output values exceed input values in a manual transaction. | |
/// Process: | |
/// 1. Sync the wallet with a mock node containing a mint transaction. | |
/// 2. Attempt to create a manual transaction with output value greater than the available coin value. | |
/// 3. Confirm that the wallet correctly identifies and returns the 'OutputsExceedInputs' error. | |
#[test] | |
fn manual_transaction_outputs_exceed_inputs() { | |
let mut wallet = wallet_with_alice(); | |
let coin = Coin { value: 100, owner: Address::Alice }; | |
let mint_tx = Transaction { inputs: vec![], outputs: vec![coin.clone()] }; | |
let coin_id = mint_tx.coin_id(0); | |
let mut node = MockNode::new(); | |
node.add_block_as_best(Block::genesis().id(), vec![mint_tx]); | |
wallet.sync(&node); | |
let output_coin = Coin { value: 200, owner: Address::Bob }; | |
let create_tx_result = wallet.create_manual_transaction(vec![coin_id], vec![output_coin]); | |
assert_eq!(create_tx_result, Err(WalletError::OutputsExceedInputs)); | |
} | |
/// Purpose: Validate that the wallet returns 'OutputsExceedInputs' error for automatic transactions when requested output value exceeds the total value of owned coins. | |
/// Process: | |
/// 1. Sync wallet with a mock node containing a transaction minting coins to Alice. | |
/// 2. Attempt to create an automatic transaction requesting a transfer amount larger than the minted coin value. | |
/// 3. Check if the wallet correctly identifies the discrepancy and returns the 'OutputsExceedInputs' error. | |
#[test] | |
fn automatic_transaction_outputs_exceed_inputs() { | |
let mut wallet = wallet_with_alice(); | |
let coin = Coin { value: 100, owner: Address::Alice }; | |
let mint_tx = Transaction { inputs: vec![], outputs: vec![coin] }; | |
let mut node = MockNode::new(); | |
node.add_block_as_best(Block::genesis().id(), vec![mint_tx]); | |
wallet.sync(&node); | |
let create_tx_result = wallet.create_automatic_transaction(Address::Bob, 200, 0); | |
assert_eq!(create_tx_result, Err(WalletError::OutputsExceedInputs)); | |
} | |
/// Purpose: Test that the wallet returns 'UnknownCoin' error when queried for a CoinId not tracked by the wallet. | |
/// Process: | |
/// 1. Create a wallet with Alice's address and sync it with a mock node containing a transaction minting coins to Alice. | |
/// 2. Attempt to query details of a coin (with a new CoinId) that was not part of any synced transactions. | |
/// 3. Check if the wallet returns 'UnknownCoin' error, indicating the coin is not known to the wallet. | |
#[test] | |
fn test_unknown_coin_id_error() { | |
let mut node = MockNode::new(); | |
let mut wallet = Wallet::new(vec![Address::Alice].into_iter()); | |
let coin = Coin { value: 100, owner: Address::Alice }; | |
let tx = Transaction { inputs: vec![], outputs: vec![coin] }; | |
let block_id = node.add_block_as_best(Block::genesis().id(), vec![tx]); | |
wallet.sync(&node); | |
let coin2 = Coin { value: 100000, owner: Address::Custom(0) }; | |
let tx = Transaction { inputs: vec![], outputs: vec![coin2] }; | |
let coin2_id = tx.coin_id(0); | |
assert_eq!(wallet.coin_details(&coin2_id), Err(WalletError::UnknownCoin)); | |
} | |
/// Purpose: Test for 'UnknownCoin' error in create_manual_transaction with an unknown CoinId. | |
/// Process: | |
/// 1. Create a wallet with Alice's address. | |
/// 2. Generate a dummy transaction and create an unrealistic CoinId (not part of any transaction). | |
/// 3. Attempt to create a manual transaction using the unknown CoinId as input. | |
/// 4. Verify that the wallet returns 'UnknownCoin' error, indicating the input coin is not recognized. | |
#[test] | |
fn unknown_coin_error_in_manual_transaction() { | |
let wallet = wallet_with_alice(); | |
let dummy_tx = create_dummy_transaction(); | |
let unknown_coin_id = dummy_tx.coin_id(9999); | |
let output_coins = vec![Coin { | |
value: 50, | |
owner: Address::Bob, | |
}]; | |
let result = wallet.create_manual_transaction(vec![unknown_coin_id], output_coins); | |
assert!(matches!(result, Err(WalletError::UnknownCoin))); | |
} | |
/// Purpose: Test for 'ForeignAddress' error in total_assets_of and all_coins_of methods. | |
/// Process: | |
/// 1. Initialize a wallet with Alice's address. | |
/// 2. Attempt to query the total assets and all coins of Bob (who is not in the wallet). | |
/// 3. Verify that both queries result in 'ForeignAddress' errors, indicating the address is not managed by the wallet. | |
#[test] | |
fn foreign_address_error() { | |
let wallet = wallet_with_alice(); | |
let result = wallet.total_assets_of(Address::Bob); | |
assert!(matches!(result, Err(WalletError::ForeignAddress))); | |
let coin_id_result = wallet.all_coins_of(Address::Bob); | |
assert!(matches!(coin_id_result, Err(WalletError::ForeignAddress))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment