//! 充值流程集成测试 use chrono::Utc; use rust_decimal_macros::dec; use rust_decimal::Decimal; use rustjr::domain::ledger::entity::AccountBalance; use rustjr::domain::account::AccountType; use rustjr::infrastructure::bank_integration::{BankClient, mock_bank::MockBankClient}; // ==================== 测试辅助 ==================== fn create_balance(personal: rust_decimal::Decimal, labor: rust_decimal::Decimal) -> AccountBalance { AccountBalance { id: 1, account_id: 1001, account_type: AccountType::Virtual, personal_balance: personal, labor_balance: labor, frozen_balance: Decimal::ZERO, bank_balance: personal + labor, transit_amount: Decimal::ZERO, system_balance: personal + labor, available_balance: personal + labor, frozen_amount: Decimal::ZERO, version: 1, updated_at: Utc::now(), } } // ==================== 个人余额充值测试 ==================== #[test] fn test_personal_deposit() { let mut balance = create_balance(dec!(1000.00), dec!(500.00)); // 模拟外部充值(家属汇款) balance.add_personal(dec!(2000.00)); assert_eq!(balance.personal_balance, dec!(3000.00)); assert_eq!(balance.labor_balance, dec!(500.00)); assert_eq!(balance.bank_balance, dec!(3500.00)); assert!(balance.validate_invariant().is_ok()); } #[test] fn test_multiple_deposits() { let mut balance = create_balance(dec!(0.00), dec!(0.00)); // 多次充值 balance.add_personal(dec!(100.00)); balance.add_personal(dec!(200.00)); balance.add_personal(dec!(300.00)); assert_eq!(balance.personal_balance, dec!(600.00)); assert_eq!(balance.bank_balance, dec!(600.00)); assert!(balance.validate_invariant().is_ok()); } // ==================== 劳动报酬发放测试 ==================== #[test] fn test_labor_deposit() { let mut balance = create_balance(dec!(1000.00), dec!(0.00)); // 劳动报酬发放 balance.add_labor(dec!(500.00)); assert_eq!(balance.personal_balance, dec!(1000.00)); assert_eq!(balance.labor_balance, dec!(500.00)); assert_eq!(balance.bank_balance, dec!(1500.00)); assert!(balance.validate_invariant().is_ok()); } #[test] fn test_mixed_deposits() { let mut balance = create_balance(dec!(0.00), dec!(0.00)); // 先充值个人 balance.add_personal(dec!(1000.00)); assert!(balance.validate_invariant().is_ok()); // 再发放劳动报酬 balance.add_labor(dec!(500.00)); assert!(balance.validate_invariant().is_ok()); // 再充值个人 balance.add_personal(dec!(200.00)); assert!(balance.validate_invariant().is_ok()); assert_eq!(balance.personal_balance, dec!(1200.00)); assert_eq!(balance.labor_balance, dec!(500.00)); assert_eq!(balance.bank_balance, dec!(1700.00)); } // ==================== 外部入账模拟测试 ==================== #[tokio::test] async fn test_external_deposit_via_mock_bank() { let client = MockBankClient::new(); client.create_account("PRISON001", "监狱账户", dec!(100000.00)).unwrap(); // 模拟外部入账 let bank_ref = client.simulate_external_deposit( "PRISON001", "FAMILY001", "家属张三", dec!(2000.00), Some("给罪犯XXX的充值".to_string()), ).unwrap(); assert!(bank_ref.starts_with("MOCK")); // 验证余额 let balance = client.query_balance("PRISON001").await.unwrap(); assert_eq!(balance.balance, dec!(102000.00)); } #[tokio::test] async fn test_external_deposit_in_statements() { let client = MockBankClient::new(); client.create_account("PRISON001", "监狱账户", dec!(100000.00)).unwrap(); // 模拟外部入账 client.simulate_external_deposit( "PRISON001", "FAMILY001", "家属张三", dec!(2000.00), Some("家属汇款".to_string()), ).unwrap(); // 查询流水 let today = Utc::now().date_naive(); let statements = client.query_statements("PRISON001", today, today).await.unwrap(); assert!(!statements.is_empty()); // 找到入账流水 let deposit = statements.iter().find(|s| s.direction == "in").unwrap(); assert_eq!(deposit.amount, dec!(2000.00)); } // ==================== 边界条件测试 ==================== #[test] fn test_zero_deposit() { let mut balance = create_balance(dec!(1000.00), dec!(500.00)); let original_bank = balance.bank_balance; balance.add_personal(dec!(0.00)); assert_eq!(balance.bank_balance, original_bank); assert!(balance.validate_invariant().is_ok()); } #[test] fn test_large_deposit() { let mut balance = create_balance(dec!(0.00), dec!(0.00)); balance.add_personal(dec!(999999999.99)); assert_eq!(balance.personal_balance, dec!(999999999.99)); assert_eq!(balance.bank_balance, dec!(999999999.99)); assert!(balance.validate_invariant().is_ok()); } #[test] fn test_decimal_precision_deposit() { let mut balance = create_balance(dec!(0.00), dec!(0.00)); balance.add_personal(dec!(0.01)); balance.add_personal(dec!(0.01)); balance.add_personal(dec!(0.01)); assert_eq!(balance.personal_balance, dec!(0.03)); assert!(balance.validate_invariant().is_ok()); }