public void EvaluateRewards_CombineByPriorityOrder() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("FedEx Get 50% Off", "FedEx Get 30% Off", "ProductA and ProductB Get 2 With 50% Off", "Get ProductA With 25$ Off")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var productB = new ProductPromoEntry { ProductId = "ProductB", Price = 100, Quantity = 3 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 100, PromoEntries = new [] { productA, productB } }; //Act var rewards = evalPolicy.EvaluatePromotion(context).Rewards; //Assert Assert.Equal(rewards.Count(), 5); Assert.Equal(context.ShipmentMethodPrice, 35m); Assert.Equal(productA.Price, 37.5m); Assert.Equal(productB.Price, 50); }
public void EvaluatePromotion_GetBestPaymentReward() { //Agganre var blockReward = new BlockReward().WithChildrens(new RewardPaymentGetOfAbs() { Amount = 10m, PaymentMethod = "PayTest" }); var dynamicPromotion = new DynamicPromotion { DynamicExpression = AbstractTypeFactory <PromotionConditionAndRewardTree> .TryCreateInstance() }; dynamicPromotion.DynamicExpression.WithChildrens(blockReward); var evalPolicy = GetPromotionEvaluationPolicy(new[] { dynamicPromotion }); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { PaymentMethodCode = "PayTest", PaymentMethodPrice = 5m, PromoEntries = new[] { productA } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards.OfType <PaymentReward>().ToList(); //Assert Assert.Equal(10m, rewards.First().Amount); Assert.True(rewards.First().IsValid); }
public void EvaluateRewards_CombineByPriorityOrder() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("FedEx Get 50% Off", "FedEx Get 30% Off", "ProductA and ProductB Get 2 With 50% Off", "Get ProductA With 25$ Off")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var productB = new ProductPromoEntry { ProductId = "ProductB", Price = 100, Quantity = 3 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 100, PromoEntries = new[] { productA, productB } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards; //Assert Assert.Equal(5, rewards.Count); Assert.Equal(35m, context.ShipmentMethodPrice); Assert.Equal(37.5m, productA.Price); Assert.Equal(66.67m, Math.Round(productB.Price, 2)); }
public static bool IsItemInCategory(this PromotionEvaluationContext context, string categoryId, string[] excludingCategoryIds, string[] excludingProductIds) { var result = new ProductPromoEntry[] { context.PromoEntry }.InCategories(new[] { categoryId }) .ExcludeCategories(excludingCategoryIds) .ExcludeProducts(excludingProductIds) .Any(); return(result); }
private static bool IsLineItemInCategories(ProductPromoEntry entry, IEnumerable <string> categoryIds) { var retVal = categoryIds.Contains(entry.CategoryId); if (!retVal && entry.Outline != null) { retVal = entry.Outline.Split(';').Any(x => x == entry.CategoryId); } return(retVal); }
public static bool ProductInCategories(this ProductPromoEntry entry, ICollection <string> categoryIds) { var result = categoryIds.Contains(entry.CategoryId, StringComparer.OrdinalIgnoreCase); if (!result && entry.Outline != null) { result = entry.Outline.Split(';', '/', '\\').Intersect(categoryIds, StringComparer.OrdinalIgnoreCase).Any(); } return(result); }
public void EvaluateRewards_NonHandledReward_Throws() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Reward non handled by the policy")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { PromoEntries = new[] { productA }, }; //Act //Assert Assert.ThrowsAsync <NotSupportedException>(() => evalPolicy.EvaluatePromotionAsync(context)); }
public void EvaluateRewards_PickBestRelativeDiscount(int quantity, decimal expectedReward, params string[] promotions) { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions(promotions)); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = quantity }; var context = new PromotionEvaluationContext { PromoEntries = new[] { productA } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards.OfType <CatalogItemAmountReward>().ToList(); //Assert Assert.Single(rewards); Assert.Equal(expectedReward, rewards.First().Amount); }
public void EvaluateRewards_SkipRewardsMakingPriceNegative() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Get ProductA Free", "Get ProductA With 25$ Off")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { PromoEntries = new[] { productA } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards; //Assert Assert.Single(rewards); Assert.Equal("Get ProductA Free", rewards.Single().Promotion.Id); Assert.Equal(0, productA.Price); }
public async Task EvaluateRewards_PaymentMethodNotSpecified_AppliedForAnyProductPaymentMethod(string productPaymentMethod) { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("For Any Payment method => get 10% off for payment method")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { PaymentMethodCode = productPaymentMethod, PaymentMethodPrice = 100, PromoEntries = new[] { productA }, }; //Act await evalPolicy.EvaluatePromotionAsync(context); //Assert Assert.Equal(90m, context.PaymentMethodPrice); Assert.Equal(100m, productA.Price); }
public async Task EvaluateRewards_SpecificPaymentMethod_NotApplied() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("For MasterCard Payment method => get 10% off for payment method")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { PaymentMethodCode = "AuthorizeNet", PaymentMethodPrice = 100, PromoEntries = new[] { productA }, }; //Act await evalPolicy.EvaluatePromotionAsync(context); //Assert Assert.Equal(100m, context.PaymentMethodPrice); Assert.Equal(100m, productA.Price); }
public void EvaluateRewards_ShippingMethodNotSpecified_Counted() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Any shipment 50% Off")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 100, PromoEntries = new[] { productA } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards; //Assert Assert.Equal(1, rewards.Count); Assert.Equal(50m, context.ShipmentMethodPrice); Assert.Equal(100m, productA.Price); }
public async Task EvaluateRewards_PromotionRewardEvaluation_CalledOnceOnTwoDifferentTypeRewardsInOnePromotion() { //Arrange var promotionRewardEvaluatorMock = GetPromotionRewardEvaluatorMock(); var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Register and First time buyer => get 20% off and free shipping."), promotionRewardEvaluatorMock); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 45, Quantity = 1 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 5, PromoEntries = new[] { productA } }; //Act var rewards = (await evalPolicy.EvaluatePromotionAsync(context)).Rewards; //Assert promotionRewardEvaluatorMock.Verify(x => x.GetOrderedValidRewardsAsync(It.IsAny <IEnumerable <Promotion> >(), It.IsAny <IEvaluationContext>()), Times.Once); Assert.Equal(2, rewards.Count); }
public async Task EvaluateRewards_PromotionRewardEvaluation_CalledOnceWhenNoPossibleDiscountsAffectingCartTotal() { //Arrange var promotionRewardEvaluatorMock = GetPromotionRewardEvaluatorMock(); var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Any shipment 50% Off", "Free shipping on orders totaling $35.00 or more."), promotionRewardEvaluatorMock); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 45, Quantity = 1 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 5, PromoEntries = new[] { productA } }; //Act var rewards = (await evalPolicy.EvaluatePromotionAsync(context)).Rewards; //Assert promotionRewardEvaluatorMock.Verify(x => x.GetOrderedValidRewardsAsync(It.IsAny <IEnumerable <Promotion> >(), It.IsAny <IEvaluationContext>()), Times.Once); Assert.Equal(2, rewards.Count); }
public async Task EvaluateRewards_PromotionRewardEvaluation_ConditionCalculatesBasedOnChangedPrice(decimal initialPrice, int expectedRewardsApplied, decimal expectedPrice, decimal expectedShipmentPrice) { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Register and First time buyer => get 20% off.", "Free shipping on orders totaling $35.00 or more.")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = initialPrice, Quantity = 1 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 5, PromoEntries = new[] { productA } }; //Act var rewards = (await evalPolicy.EvaluatePromotionAsync(context)).Rewards; //Assert Assert.Equal(expectedRewardsApplied, rewards.Count); Assert.Equal(expectedShipmentPrice, context.ShipmentMethodPrice); Assert.Equal(expectedPrice, productA.Price); }
public void EvaluateRewards_ShippingMethodNotSpecified_Counted() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("FedEx Get 30% Off", "Any shipment 70% Off")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 100, PromoEntries = new[] { productA } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards.OfType <ShipmentReward>().ToList(); //Assert Assert.Equal(2, rewards.Count); Assert.Equal(30m, rewards.FirstOrDefault(x => x.Promotion.Id.EqualsInvariant("FedEx Get 30% Off")).Amount); Assert.Equal(70m, rewards.FirstOrDefault(x => x.Promotion.Id.EqualsInvariant("Any shipment 70% Off")).Amount); }
public async Task EvaluateRewards_CartSubTotalReward_Applied() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Buy Order with 55% Off")); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var productB = new ProductPromoEntry { ProductId = "ProductB", Price = 10, Quantity = 1 }; var context = new PromotionEvaluationContext { PromoEntries = new[] { productA, productB } }; //Act var rewards = (await evalPolicy.EvaluatePromotionAsync(context)).Rewards; //Assert Assert.Single(rewards); Assert.Equal("Buy Order with 55% Off", rewards.Single().Promotion.Id); Assert.Equal(100m, productA.Price); Assert.Equal(10m, productB.Price); }
public void EvaluateRewards_BuyProductWithTag_Counted() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(new List <BuyProductWithTagPromotion>() { new BuyProductWithTagPromotion(new [] { "tag1" }, 10) }); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1, Attributes = new Dictionary <string, string> { { "tag", "tag1" } } }; var context = new PromotionEvaluationContext { PromoEntries = new[] { productA } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards; //Assert Assert.Equal(1, rewards.Count); }
public void EvaluateRewards_OnlySingleExclusivePromotion() { //Arrange var evalPolicy = GetPromotionEvaluationPolicy(TestPromotions); var productA = new ProductPromoEntry { ProductId = "ProductA", Price = 100, Quantity = 1 }; var productB = new ProductPromoEntry { ProductId = "ProductB", Price = 100, Quantity = 1 }; var context = new PromotionEvaluationContext { ShipmentMethodCode = "FedEx", ShipmentMethodPrice = 100, PromoEntries = new[] { productA, productB } }; //Act var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards; //Assert Assert.Single(rewards); Assert.Equal("Exclusive ProductB Get 10$ Off", rewards.Single().Promotion.Id); }
public static bool ProductInProducts(this ProductPromoEntry entry, IEnumerable <string> productIds) { return(productIds.Contains(entry.ProductId, StringComparer.OrdinalIgnoreCase)); }
private static bool IsLineItemInProducts(ProductPromoEntry entry, string[] productIds) { var retVal = productIds.Contains(entry.ProductId, StringComparer.OrdinalIgnoreCase); return(retVal); }