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);
        }
Пример #3
0
        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));
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
        }
Пример #20
0
 public static bool ProductInProducts(this ProductPromoEntry entry, IEnumerable <string> productIds)
 {
     return(productIds.Contains(entry.ProductId, StringComparer.OrdinalIgnoreCase));
 }
Пример #21
0
        private static bool IsLineItemInProducts(ProductPromoEntry entry, string[] productIds)
        {
            var retVal = productIds.Contains(entry.ProductId, StringComparer.OrdinalIgnoreCase);

            return(retVal);
        }