#[cfg(test)]
mod tests {
use std::time::{SystemTime, UNIX_EPOCH};
use promotion_kit::error::PromoError;
use promotion_kit::promotion::{DiscountType, Promotion, TargetScope};
use promotion_kit::service::apply_promotion;
fn get_current_time() -> u64 {
SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()
}
#[test]
fn test_valid_promotion_percentage() {
let promo = Promotion {
code: "SAVE10".to_string(),
description: "10% off on orders".to_string(),
discount: DiscountType::Percentage(10.0),
usage_limit: Some(100),
used: 0,
valid_from: 1_700_000_000,
valid_until: 1_800_000_000,
min_transaction: Some(50.0),
target: TargetScope::Global,
currency: Some("USD".to_string()),
};
let transaction_amount = 100.0;
let now = get_current_time();
let result = apply_promotion(&promo, transaction_amount, now);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 10.0); }
#[test]
fn test_invalid_time() {
let promo = Promotion {
code: "SAVE10".to_string(),
description: "10% off on orders".to_string(),
discount: DiscountType::Percentage(10.0),
usage_limit: Some(100),
used: 0,
valid_from: 1_700_000_000,
valid_until: 1_800_000_000,
min_transaction: Some(50.0),
target: TargetScope::Global,
currency: Some("USD".to_string()),
};
let transaction_amount = 100.0;
let now = 1_900_000_000;
let result = apply_promotion(&promo, transaction_amount, now);
assert_eq!(result, Err(PromoError::InvalidTime));
}
#[test]
fn test_below_minimum_transaction() {
let promo = Promotion {
code: "SAVE10".to_string(),
description: "10% off on orders".to_string(),
discount: DiscountType::Percentage(10.0),
usage_limit: Some(100),
used: 0,
valid_from: 1_700_000_000,
valid_until: 1_800_000_000,
min_transaction: Some(150.0),
target: TargetScope::Global,
currency: Some("USD".to_string()),
};
let transaction_amount = 100.0; let now = get_current_time();
let result = apply_promotion(&promo, transaction_amount, now);
assert_eq!(result, Err(PromoError::BelowMinimumTransaction));
}
#[test]
fn test_usage_limit_reached() {
let promo = Promotion {
code: "SAVE10".to_string(),
description: "10% off on orders".to_string(),
discount: DiscountType::Percentage(10.0),
usage_limit: Some(2), used: 2, valid_from: 1_700_000_000,
valid_until: 1_800_000_000,
min_transaction: Some(50.0),
target: TargetScope::Global,
currency: Some("USD".to_string()),
};
let transaction_amount = 100.0;
let now = get_current_time();
let result = apply_promotion(&promo, transaction_amount, now);
assert_eq!(result, Err(PromoError::UsageLimitReached));
}
#[test]
fn test_invalid_period() {
let promo = Promotion {
code: "SAVE10".to_string(),
description: "10% off on orders".to_string(),
discount: DiscountType::Percentage(10.0),
usage_limit: Some(100),
used: 0,
valid_from: 1_800_000_000,
valid_until: 1_700_000_000, min_transaction: Some(50.0),
target: TargetScope::Global,
currency: Some("USD".to_string()),
};
let transaction_amount = 100.0;
let now = get_current_time();
let result = apply_promotion(&promo, transaction_amount, now);
assert_eq!(result, Err(PromoError::InvalidPeriod));
}
#[test]
fn test_valid_fixed_amount_promotion() {
let promo = Promotion {
code: "FLAT50".to_string(),
description: "Flat 50 off".to_string(),
discount: DiscountType::FixedAmount(50.0),
usage_limit: Some(100),
used: 0,
valid_from: 1_700_000_000,
valid_until: 1_800_000_000,
min_transaction: Some(50.0),
target: TargetScope::Global,
currency: Some("USD".to_string()),
};
let transaction_amount = 200.0;
let now = get_current_time();
let result = apply_promotion(&promo, transaction_amount, now);
assert!(result.is_ok());
assert_eq!(result.unwrap(), 50.0);
}
}