public class DiscountServiceTests
public void ApplyFixedDiscount_ValidDiscount_UpdatesDiscountPrice()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var discount = new FixedDiscount(20);
var service = new DiscountService();
service.ApplyDiscount(product, discount);
Assert.AreEqual(80, product.DiscountPrice);
public void ApplyFixedDiscount_DiscountGreaterThanPrice_DiscountPriceIsZero()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var discount = new FixedDiscount(150);
var service = new DiscountService();
service.ApplyDiscount(product, discount);
Assert.AreEqual(0, product.DiscountPrice);
public void ApplyFixedDiscount_ZeroDiscount_NoChange()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var discount = new FixedDiscount(0);
var service = new DiscountService();
service.ApplyDiscount(product, discount);
Assert.AreEqual(100, product.DiscountPrice);
public void ApplyFixedDiscount_NegativeDiscount_ThrowsArgumentOutOfRangeException()
Assert.Throws<ArgumentOutOfRangeException>(() => new FixedDiscount(-10));
public void ApplyPercentDiscount_ValidDiscount_UpdatesDiscountPrice()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var discount = new PercentDiscount(10);
var service = new DiscountService();
service.ApplyDiscount(product, discount);
Assert.AreEqual(90, product.DiscountPrice);
public void ApplyPercentDiscount_FullDiscount_DiscountPriceIsZero()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var discount = new PercentDiscount(100);
var service = new DiscountService();
service.ApplyDiscount(product, discount);
Assert.AreEqual(0, product.DiscountPrice);
public void ApplyPercentDiscount_ZeroDiscount_NoChange()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var discount = new PercentDiscount(0);
var service = new DiscountService();
service.ApplyDiscount(product, discount);
Assert.AreEqual(100, product.DiscountPrice);
public void ApplyPercentDiscount_InvalidPercent_ThrowsArgumentOutOfRangeException()
Assert.Throws<ArgumentOutOfRangeException>(() => new PercentDiscount(-10));
Assert.Throws<ArgumentOutOfRangeException>(() => new PercentDiscount(110));
public void ApplyDiscount_NullProduct_ThrowsArgumentNullException()
var discount = new FixedDiscount(10);
var service = new DiscountService();
Assert.Throws<ArgumentNullException>(() => service.ApplyDiscount(null, discount));
public void ApplyDiscount_NullDiscount_ThrowsArgumentNullException()
var product = new ProductOrderModel(1, 101, "Test Product", 2, 100);
var service = new DiscountService();
Assert.Throws<ArgumentNullException>(() => service.ApplyDiscount(product, null));
public class ProductOrderModel
public ulong? Id { get; set; }
public ulong? ProductId { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal SubTotal { get; set; }
public decimal DiscountPrice { get; set; }
public ProductOrderModel(ulong? id, ulong? productId, string name, int quantity, decimal price)
SubTotal = price * quantity;
public abstract class Discount
public abstract decimal CalculateDiscount(decimal price);
public class FixedDiscount : Discount
public decimal Amount { get; }
public FixedDiscount(decimal amount)
throw new ArgumentOutOfRangeException(nameof(amount), "Fixed discount amount cannot be negative.");
public override decimal CalculateDiscount(decimal price)
public class PercentDiscount : Discount
public decimal Percentage { get; }
public PercentDiscount(decimal percentage)
if (percentage < 0 || percentage > 100)
throw new ArgumentOutOfRangeException(nameof(percentage), "Percentage discount must be between 0 and 100.");
public override decimal CalculateDiscount(decimal price)
return price * (Percentage / 100);
public class DiscountService
public void ApplyDiscount(ProductOrderModel product, Discount discount)
throw new ArgumentNullException(nameof(product), "Product order model cannot be null.");
throw new ArgumentNullException(nameof(discount), "Discount cannot be null.");
decimal discountAmount = discount.CalculateDiscount(product.Price);
if (discountAmount >= product.Price)
product.DiscountPrice = 0;
product.DiscountPrice = product.Price - discountAmount;
public static void Main()
Console.WriteLine("-------------- STARTING UNIT TESTING ---------------");
new NUnitLite.AutoRun().Execute(["--noc" ]);