discount.rs (2229B)
1 mod common; 2 3 use radroots_core::{ 4 Percent, Unit, 5 pricing::{Discount, DiscountError, DiscountScope, DiscountThreshold, DiscountValue}, 6 }; 7 8 #[test] 9 fn checked_constructor_rejects_negative_percent_values() { 10 let negative_value = Discount::try_new( 11 DiscountScope::Bin, 12 DiscountThreshold::BinCount { 13 bin_id: "bin-1".to_string(), 14 min: 1, 15 }, 16 DiscountValue::Percent(Percent::new(common::dec("-0.01"))), 17 ); 18 assert_eq!(negative_value, Err(DiscountError::NegativeValue)); 19 } 20 21 #[test] 22 fn checked_constructor_and_accessors_preserve_valid_shape() { 23 let discount = Discount::try_new( 24 DiscountScope::Bin, 25 DiscountThreshold::BinCount { 26 bin_id: "bin-1".to_string(), 27 min: 2, 28 }, 29 DiscountValue::MoneyPerBin(common::money("1.25", "USD")), 30 ) 31 .unwrap(); 32 assert_eq!(discount.scope(), &DiscountScope::Bin); 33 assert!(matches!( 34 discount.threshold(), 35 DiscountThreshold::BinCount { min: 2, .. } 36 )); 37 assert!(matches!(discount.value(), DiscountValue::MoneyPerBin(_))); 38 assert_eq!(discount.validate(), Ok(())); 39 assert!(discount.is_non_negative()); 40 } 41 42 #[test] 43 fn order_quantity_and_positive_percent_cover_the_alternate_valid_shape() { 44 let discount = Discount::try_new( 45 DiscountScope::OrderTotal, 46 DiscountThreshold::OrderQuantity { 47 min: common::qty("2", Unit::Each), 48 }, 49 DiscountValue::Percent(Percent::new(common::dec("12.5"))), 50 ) 51 .unwrap(); 52 53 assert_eq!(discount.scope(), &DiscountScope::OrderTotal); 54 assert!(matches!( 55 discount.threshold(), 56 DiscountThreshold::OrderQuantity { min } if min.amount() == common::dec("2") 57 )); 58 assert!( 59 matches!(discount.value(), DiscountValue::Percent(percent) if percent.value() == common::dec("12.5")) 60 ); 61 assert_eq!(discount.validate(), Ok(())); 62 } 63 64 #[test] 65 fn discount_error_messages_are_stable() { 66 assert_eq!( 67 DiscountError::NegativeThreshold.to_string(), 68 "discount threshold must be non-negative" 69 ); 70 assert_eq!( 71 DiscountError::NegativeValue.to_string(), 72 "discount value must be non-negative" 73 ); 74 }