use super::{deposit, get_asset_manager_and_ledger}; use crate::{AccountId, Asset}; #[tokio::test] async fn pending_deposit_and_failure() { let source = "account1".parse::().expect("account"); let ledger = get_asset_manager_and_ledger().await; let usd: Asset = "USD/2".parse().expect("asset"); let rev_id = ledger .deposit( &source, usd.from_human("30").expect("amount"), "processing".into(), vec![], "Test".to_owned(), ) .await .expect("valid tx") .revision_id .clone(); assert!(ledger .get_balance(&source) .await .expect("balance") .is_empty()); ledger .change_status(rev_id, "failed".into(), "failed due test".to_owned()) .await .expect("valid tx"); assert!(ledger .get_balance(&source) .await .expect("balance") .is_empty()); } #[tokio::test] async fn deposit_and_transfer() { let source = "account1".parse::().expect("account"); let dest = "account2".parse::().expect("account"); let fee = "fee".parse::().expect("account"); let ledger = get_asset_manager_and_ledger().await; let usd: Asset = "USD/2".parse().expect("asset"); let btc: Asset = "BTC/8".parse().expect("asset"); deposit(&ledger, &source, usd.from_human("10").expect("amount")).await; deposit(&ledger, &source, usd.from_human("20").expect("amount")).await; deposit(&ledger, &source, btc.from_human(".2").expect("amount")).await; let mut balances = ledger.get_balance(&source).await.expect("balance"); balances.sort_by(|a, b| a.asset().name.cmp(&b.asset().name)); assert_eq!( vec![ btc.from_human("0.2").expect("amount"), usd.from_human("30").expect("amount") ], balances ); ledger .new_transaction( "Exchange one".to_owned(), "settled".into(), vec![(source.clone(), usd.from_human("13").expect("amount"))], vec![ (dest.clone(), usd.from_human("12.5").expect("amount")), (fee.clone(), usd.from_human("0.5").expect("amount")), ], ) .await .expect("valid tx"); let mut balances = ledger.get_balance(&source).await.expect("balance"); balances.sort_by(|a, b| a.asset().name.cmp(&b.asset().name)); assert_eq!( vec![ btc.from_human("0.2").expect("amount"), usd.from_human("17").expect("amount") ], balances ); assert_eq!( vec![usd.from_human("12.5").expect("amount"),], ledger.get_balance(&dest).await.expect("balance") ); assert_eq!( vec![usd.from_human("0.5").expect("amount"),], ledger.get_balance(&fee).await.expect("balance") ); } #[tokio::test] async fn balance_decreases_while_pending_spending_and_confirm() { let source = "account1".parse::().expect("account"); let dest = "account2".parse::().expect("account"); let fee = "fee".parse::().expect("account"); let ledger = get_asset_manager_and_ledger().await; let usd: Asset = "USD/2".parse().expect("asset"); deposit(&ledger, &source, usd.from_human("10").expect("amount")).await; deposit(&ledger, &source, usd.from_human("20").expect("amount")).await; assert_eq!( vec![usd.from_human("30").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); let rev_id = ledger .new_transaction( "Exchange one".to_owned(), "pending".into(), vec![(source.clone(), usd.from_human("13").expect("amount"))], vec![ (dest.clone(), usd.from_human("12.5").expect("amount")), (fee.clone(), usd.from_human("0.5").expect("amount")), ], ) .await .expect("valid tx") .revision_id .clone(); assert_eq!( vec![usd.from_human("17").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); ledger .change_status(rev_id, "settled".into(), "ready".to_owned()) .await .expect("valid tx"); assert_eq!( vec![usd.from_human("17").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert_eq!( vec![usd.from_human("12.5").expect("amount"),], ledger.get_balance(&dest).await.expect("balance") ); assert_eq!( vec![usd.from_human("0.5").expect("amount"),], ledger.get_balance(&fee).await.expect("balance") ); } #[tokio::test] async fn balance_decreases_while_pending_spending_and_cancel() { let source = "account1".parse::().expect("account"); let dest = "account2".parse::().expect("account"); let fee = "fee".parse::().expect("account"); let ledger = get_asset_manager_and_ledger().await; let usd: Asset = "USD/2".parse().expect("asset"); deposit(&ledger, &source, usd.from_human("10").expect("amount")).await; deposit(&ledger, &source, usd.from_human("20").expect("amount")).await; assert_eq!( vec![usd.from_human("30").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); let rev_id = ledger .new_transaction( "Exchange one".to_owned(), "pending".into(), vec![(source.clone(), usd.from_human("13").expect("amount"))], vec![ (dest.clone(), usd.from_human("12.5").expect("amount")), (fee.clone(), usd.from_human("0.5").expect("amount")), ], ) .await .expect("valid tx") .revision_id .clone(); assert_eq!( vec![usd.from_human("17").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); ledger .change_status(rev_id, "cancelled".into(), "cancelled by test".to_owned()) .await .expect("valid tx"); assert_eq!( vec![usd.from_human("30").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); } #[tokio::test] async fn balance_decreases_while_pending_spending_and_failed() { let source = "account1".parse::().expect("account"); let dest = "account2".parse::().expect("account"); let fee = "fee".parse::().expect("account"); let ledger = get_asset_manager_and_ledger().await; let usd: Asset = "USD/2".parse().expect("asset"); deposit(&ledger, &source, usd.from_human("10").expect("amount")).await; deposit(&ledger, &source, usd.from_human("20").expect("amount")).await; assert_eq!( vec![usd.from_human("30").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); let rev_id = ledger .new_transaction( "Exchange one".to_owned(), "pending".into(), vec![(source.clone(), usd.from_human("13").expect("amount"))], vec![ (dest.clone(), usd.from_human("12.5").expect("amount")), (fee.clone(), usd.from_human("0.5").expect("amount")), ], ) .await .expect("valid tx") .revision_id .clone(); assert_eq!( vec![usd.from_human("17").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); let new_rev_id = ledger .change_status(rev_id, "processing".into(), "processing now".to_owned()) .await .expect("valid tx") .revision_id; assert_eq!( vec![usd.from_human("17").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); assert_eq!( "Transaction: Error in status: Invalid transition from processing to cancelled".to_owned(), ledger .change_status( new_rev_id.clone(), "cancelled".into(), "cancelled by user".to_owned() ) .await .unwrap_err() .to_string() ); assert_eq!( vec![usd.from_human("17").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); ledger .change_status(new_rev_id, "failed".into(), "it has failed".to_owned()) .await .expect("valid"); assert_eq!( vec![usd.from_human("30").expect("amount"),], ledger.get_balance(&source).await.expect("balance") ); assert!(ledger.get_balance(&dest).await.expect("balance").is_empty()); assert!(ledger.get_balance(&fee).await.expect("balance").is_empty()); }