//! 账务服务单元测试 //! //! 测试 LedgerService 的核心功能 // 由于 LedgerService 依赖仓储,这里主要测试账务逻辑 // 实际的服务测试在集成测试中进行 use rust_decimal_macros::dec; use rustjr::domain::ledger::entity::ThreeAccountResult; // ==================== 三账校验结果测试 ==================== #[test] fn test_three_account_balanced() { let result = ThreeAccountResult { bank_balance: dec!(100000.00), transit_net: dec!(5000.00), ledger_total: dec!(95000.00), is_balanced: true, difference: dec!(0.00), }; assert!(result.is_balanced); assert_eq!(result.difference, dec!(0.00)); // 验证: ledger + transit = bank assert_eq!( result.ledger_total + result.transit_net, result.bank_balance ); } #[test] fn test_three_account_short() { // 短款:银行 < 总账 + 在途 let result = ThreeAccountResult { bank_balance: dec!(100000.00), transit_net: dec!(5000.00), ledger_total: dec!(100000.00), is_balanced: false, difference: dec!(-5000.00), // 银行少 5000 }; assert!(!result.is_balanced); assert!(result.difference < dec!(0.00)); } #[test] fn test_three_account_long() { // 长款:银行 > 总账 + 在途 let result = ThreeAccountResult { bank_balance: dec!(110000.00), transit_net: dec!(5000.00), ledger_total: dec!(100000.00), is_balanced: false, difference: dec!(5000.00), // 银行多 5000 }; assert!(!result.is_balanced); assert!(result.difference > dec!(0.00)); } // ==================== 扣款优先级逻辑测试 ==================== #[test] fn test_deduction_priority_logic() { // 测试扣款优先级计算逻辑 let personal = dec!(300.00); let labor = dec!(500.00); let to_deduct = dec!(600.00); // 先扣个人 let from_personal = personal.min(to_deduct); let remaining = to_deduct - from_personal; // 再扣劳动 let from_labor = labor.min(remaining); assert_eq!(from_personal, dec!(300.00)); assert_eq!(from_labor, dec!(300.00)); assert_eq!(from_personal + from_labor, to_deduct); } #[test] fn test_deduction_personal_sufficient() { let personal = dec!(1000.00); let labor = dec!(500.00); let to_deduct = dec!(800.00); let from_personal = personal.min(to_deduct); let remaining = to_deduct - from_personal; let from_labor = labor.min(remaining); assert_eq!(from_personal, dec!(800.00)); assert_eq!(from_labor, dec!(0.00)); } #[test] fn test_deduction_total_insufficient() { let personal = dec!(300.00); let labor = dec!(200.00); let to_deduct = dec!(600.00); let available = personal + labor; // 余额不足 assert!(available < to_deduct); } // ==================== 在途计算逻辑测试 ==================== #[test] fn test_transit_flow_calculation() { // 模拟在途流转计算 let initial_personal = dec!(1000.00); let initial_bank = dec!(1000.00); let transit_amount = dec!(300.00); // 1. 扣款(可用 -> 在途) let after_deduct_personal = initial_personal - transit_amount; let after_deduct_bank = initial_bank; // 银行余额不变 let in_transit = transit_amount; assert_eq!(after_deduct_personal, dec!(700.00)); assert_eq!(in_transit, dec!(300.00)); // 2. 结转(银行确认扣款) let final_bank = after_deduct_bank - transit_amount; let final_transit = in_transit - transit_amount; assert_eq!(final_bank, dec!(700.00)); assert_eq!(final_transit, dec!(0.00)); } #[test] fn test_transit_rollback_calculation() { // 模拟在途回退计算 let after_deduct_personal = dec!(700.00); let initial_bank = dec!(1000.00); let in_transit = dec!(300.00); // 回退(银行失败) let final_personal = after_deduct_personal + in_transit; let final_bank = initial_bank; // 银行余额不变 let final_transit = dec!(0.00); assert_eq!(final_personal, dec!(1000.00)); assert_eq!(final_bank, dec!(1000.00)); assert_eq!(final_transit, dec!(0.00)); } // ==================== 冻结逻辑测试 ==================== #[test] fn test_freeze_from_available() { // 冻结只能从可用余额中冻结 let personal = dec!(1000.00); let labor = dec!(500.00); let available = personal + labor; let to_freeze = dec!(800.00); assert!(available >= to_freeze); // 冻结后 let new_personal = personal - to_freeze; let new_frozen = to_freeze; assert_eq!(new_personal, dec!(200.00)); assert_eq!(new_frozen, dec!(800.00)); } #[test] fn test_frozen_cannot_be_deducted() { // 冻结金额不能被扣款 let personal = dec!(200.00); let labor = dec!(500.00); let frozen = dec!(800.00); let available = personal + labor; // 不含冻结 let to_deduct = dec!(1000.00); // 余额不足(虽然总额够,但可用余额不够) assert!(available < to_deduct); }