Пример #1
0
        public void YieldCartLines_08_Multiple(
            IRuleValue <string> targetTag,
            Cart cart,
            CartProductComponent component,
            CommerceContext commerceContext,
            IRuleExecutionContext context)
        {
            /**********************************************
            * Arrange
            **********************************************/
            context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
            component.Tags.Add(new Tag("Smartphone"));;
            cart.Lines.ForEach(l => l.SetComponent(component));
            commerceContext.AddObject(cart);
            targetTag.Yield(context).ReturnsForAnyArgs("Smartphone");

            /**********************************************
            * Act
            **********************************************/
            var matchingLines = targetTag.YieldCartLinesWithTag(context);

            /**********************************************
            * Assert
            **********************************************/
            matchingLines.Should().HaveCount(3);
        }
            public void Execute_06_EmptyFulfillmentOptionName(
                CartShippingOptionAmountOffAction action,
                IRuleValue <string> fulfillmentOptionName,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                fulfillmentOptionName.Yield(context).Returns(string.Empty);
                action.FulfillmentOptionName = fulfillmentOptionName;
                action.AmountOff             = amountOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().BeEmpty();
            }
Пример #3
0
        public void YieldCartLines_04_NoLineItemComponent(
            IRuleValue <string> targetTag,
            Cart cart,
            CommerceContext commerceContext,
            IRuleExecutionContext context)
        {
            /**********************************************
            * Arrange
            **********************************************/
            context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
            commerceContext.AddObject(cart);
            targetTag.Yield(context).ReturnsForAnyArgs("Smartphone");

            /**********************************************
            * Act
            **********************************************/
            IEnumerable <CartLineComponent> matchingLines = null;
            Action executeAction = () => matchingLines = targetTag.YieldCartLinesWithTag(context);

            /**********************************************
            * Assert
            **********************************************/
            executeAction.Should().NotThrow <Exception>();
            matchingLines.Should().BeEmpty();
        }
Пример #4
0
        public void YieldCartLines_04_NoLineItemComponent(
            IRuleValue <string> targetCategorySitecoreId,
            Cart cart,
            CommerceContext commerceContext,
            IRuleExecutionContext context)
        {
            /**********************************************
            * Arrange
            **********************************************/
            context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
            commerceContext.AddObject(cart);
            targetCategorySitecoreId.Yield(context).ReturnsForAnyArgs("c2bfaf91-7825-4846-0ad3-0479cdf7b607");;

            /**********************************************
            * Act
            **********************************************/
            IEnumerable <CartLineComponent> matchingLines = null;
            Action executeAction = () => matchingLines = targetCategorySitecoreId.YieldCartLinesWithCategory(context);

            /**********************************************
            * Assert
            **********************************************/
            executeAction.Should().NotThrow <Exception>();
            matchingLines.Should().BeEmpty();
        }
Пример #5
0
        public void YieldCartLines_08_Multiple(
            IRuleValue <string> targetCategorySitecoreId,
            Cart cart,
            LineItemProductExtendedComponent component,
            CommerceContext commerceContext,
            IRuleExecutionContext context)
        {
            /**********************************************
            * Arrange
            **********************************************/
            context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
            component.ParentCategoryList = "8e456d84-4251-dba1-4b86-ce103dedcd02|c2bfaf91-7825-4846-0ad3-0479cdf7b607";
            cart.Lines.ForEach(l => l.SetComponent(component));
            commerceContext.AddObject(cart);
            targetCategorySitecoreId.Yield(context).ReturnsForAnyArgs("c2bfaf91-7825-4846-0ad3-0479cdf7b607");

            /**********************************************
            * Act
            **********************************************/
            var matchingLines = targetCategorySitecoreId.YieldCartLinesWithCategory(context);

            /**********************************************
            * Assert
            **********************************************/
            matchingLines.Should().HaveCount(3);
        }
Пример #6
0
        public void YieldCartLines_06_EmptyCategory(
            IRuleValue <string> targetCategorySitecoreId,
            Cart cart,
            LineItemProductExtendedComponent component,
            CommerceContext commerceContext,
            IRuleExecutionContext context)
        {
            /**********************************************
            * Arrange
            **********************************************/
            context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
            component.ParentCategoryList = "8e456d84-4251-dba1-4b86-ce103dedcd02|c2bfaf91-7825-4846-0ad3-0479cdf7b607";
            cart.Lines[1].SetComponent(component);
            commerceContext.AddObject(cart);
            targetCategorySitecoreId.Yield(context).ReturnsForAnyArgs("");

            /**********************************************
            * Act
            **********************************************/
            IEnumerable <CartLineComponent> matchingLines = null;
            Action executeAction = () => matchingLines = targetCategorySitecoreId.YieldCartLinesWithCategory(context);

            /**********************************************
            * Assert
            **********************************************/
            executeAction.Should().NotThrow <Exception>();
            matchingLines.Should().BeEmpty();
        }
Пример #7
0
            public void Execute_ShouldRoundPriceCalc_True(
                BaseCartItemSubtotalPercentOffAction action,
                IRuleValue <decimal> subtotal,
                IRuleValue <decimal> percentOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = true;
                globalPricingPolicy.RoundDigits                  = 3;
                globalPricingPolicy.MidPointRoundUp              = true;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                var cartline = cart.Lines[1];

                cartline.Totals.SubTotal.Amount = 175;
                var cartTotals = new CartTotals(cart);

                subtotal.Yield(context).ReturnsForAnyArgs(150);
                percentOff.Yield(context).ReturnsForAnyArgs(33.3333333M);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines);
                action.SubtotalOperator = new DecimalGreaterThanEqualToOperator();
                action.Subtotal         = subtotal;
                action.PercentOff       = percentOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1);
                cart.Adjustments.Should().BeEmpty();
                cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(116.667M);
                cartline.Adjustments.Should().NotBeEmpty();
                cartline.Adjustments.FirstOrDefault().Should().NotBeNull();
                cartline.Adjustments.FirstOrDefault().Should().BeOfType <CartLineLevelAwardedAdjustment>();
                cartline.Adjustments.FirstOrDefault()?.Name.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount);
                cartline.Adjustments.FirstOrDefault()?.DisplayName.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount);
                cartline.Adjustments.FirstOrDefault()?.AdjustmentType.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount);
                cartline.Adjustments.FirstOrDefault()?.AwardingBlock.Should().Contain(nameof(BaseCartItemSubtotalPercentOffAction));
                cartline.Adjustments.FirstOrDefault()?.IsTaxable.Should().BeFalse();
                cartline.Adjustments.FirstOrDefault()?.Adjustment.CurrencyCode.Should().Be(commerceContext.CurrentCurrency());
                cartline.Adjustments.FirstOrDefault()?.Adjustment.Amount.Should().Be(-58.333M);
                cartline.HasComponent <MessagesComponent>().Should().BeTrue();
            }
            public void Execute_09_NoCartFulfillmentComponent(
                IRuleValue <string> fulfillmentOptionName,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context,
                string fulfillmentOptionNameValue)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                fulfillmentOptionName.Yield(context).ReturnsForAnyArgs(fulfillmentOptionNameValue);
                amountOff.Yield(context).ReturnsForAnyArgs(MINIMUM_AMOUNT_OFF);

                var commander = Substitute.For <CommerceCommander>(Substitute.For <IServiceProvider>());
                var command   = Substitute.For <GetFulfillmentMethodsCommand>(
                    Substitute.For <IFindEntityPipeline>(),
                    Substitute.For <IGetCartFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetCartLineFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetFulfillmentMethodsPipeline>(),
                    Substitute.For <IServiceProvider>());

                var fulfillmentMethod = new FulfillmentMethod()
                {
                    FulfillmentType = fulfillmentOptionNameValue
                };

                command.Process(commerceContext).ReturnsForAnyArgs(new List <FulfillmentMethod>()
                {
                    fulfillmentMethod
                }.AsEnumerable());
                commander.When(x => x.Command <GetFulfillmentMethodsCommand>()).DoNotCallBase();
                commander.Command <GetFulfillmentMethodsCommand>().Returns(command);
                var action = new CartShippingOptionAmountOffAction(commander)
                {
                    FulfillmentOptionName = fulfillmentOptionName,
                    AmountOff             = amountOff
                };

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                command.Received().Process(commerceContext);
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().BeEmpty();
            }
            public void Evaluate_09_EmptyFulfillmentMethodName(
                IRuleValue <string> fulfillmentOptionName,
                CommerceContext commerceContext,
                Cart cart,
                IRuleExecutionContext context,
                SplitFulfillmentComponent splitFulfillmentComponent,
                FulfillmentComponent fulfillmentComponent,
                string fulfillmentOptionNameValue)
            {
                /**********************************************
                * Arrange
                **********************************************/
                fulfillmentComponent.FulfillmentMethod.Name = null;
                cart.SetComponent(splitFulfillmentComponent);
                while (cart.Lines.Count > 1)
                {
                    cart.Lines.RemoveAt(0);
                }
                cart.Lines[0].SetComponent(fulfillmentComponent);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                fulfillmentOptionName.Yield(context).ReturnsForAnyArgs(fulfillmentOptionNameValue);
                var command = Substitute.For <GetFulfillmentMethodsCommand>(
                    Substitute.For <IFindEntityPipeline>(),
                    Substitute.For <IGetCartFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetCartLineFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetFulfillmentMethodsPipeline>(),
                    Substitute.For <IServiceProvider>());

                var commander         = Substitute.For <CommerceCommander>(Substitute.For <IServiceProvider>());
                var fulfillmentMethod = new FulfillmentMethod()
                {
                    FulfillmentType = fulfillmentOptionNameValue
                };

                command.Process(commerceContext).ReturnsForAnyArgs(new List <FulfillmentMethod>()
                {
                    fulfillmentMethod
                }.AsEnumerable());
                commander.When(x => x.Command <GetFulfillmentMethodsCommand>()).DoNotCallBase();
                commander.Command <GetFulfillmentMethodsCommand>().Returns(command);
                var condition = new CartLineHasFulfillmentOptionCondition(commander)
                {
                    FulfillmentOptionName = fulfillmentOptionName
                };

                /**********************************************
                * Act
                **********************************************/
                var result = condition.Evaluate(context);

                /**********************************************
                * Assert
                **********************************************/
                result.Should().BeFalse();
            }
Пример #10
0
            public void Execute_PercentOff(
                CartItemQuantityRangePercentOffAction action,
                IRuleValue <string> targetItemId,
                IRuleValue <decimal> minQuantity,
                IRuleValue <decimal> maxQuantity,
                IRuleValue <decimal> percentOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = true;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                targetItemId.Yield(context).Returns("Habitat_Master|12345|");
                var index = 12345;

                cart.Lines.ForEach(line =>
                {
                    line.ItemId   = $"Habitat_Master|{index++}|";
                    line.Quantity = 2;
                    line.Totals.SubTotal.Amount = 150;
                    line.SetPolicy(new PurchaseOptionMoneyPolicy());
                });
                var cartTotals = new CartTotals(cart);

                minQuantity.Yield(context).ReturnsForAnyArgs(2);
                maxQuantity.Yield(context).ReturnsForAnyArgs(3);
                percentOff.Yield(context).ReturnsForAnyArgs(10);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.TargetItemId = targetItemId;
                action.MinQuantity  = minQuantity;
                action.MaxQuantity  = maxQuantity;
                action.PercentOff   = percentOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1);
                cart.Adjustments.Should().BeEmpty();
                cartTotals.Lines[cart.Lines[0].Id].SubTotal.Amount.Should().Be(135);
            }
Пример #11
0
            public void Execute_TimesQualified_Two_MaximumApplications_One(
                CartAnyItemQuantityXForQuantityYAction action,
                IRuleValue <int> quantityX,
                IRuleValue <int> quantityY,
                IRuleValue <int> maximumApplications,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = false;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                while (cart.Lines.Count > 1)
                {
                    cart.Lines.RemoveAt(0);
                }
                var cartline = cart.Lines[0];

                cartline.Quantity = 8;
                cartline.Totals.SubTotal.Amount = 200;
                cartline.SetPolicy(new PurchaseOptionMoneyPolicy
                {
                    SellPrice = new Money(25)
                });
                var cartTotals = new CartTotals(cart);

                quantityX.Yield(context).ReturnsForAnyArgs(4);
                quantityY.Yield(context).ReturnsForAnyArgs(3);
                maximumApplications.Yield(context).ReturnsForAnyArgs(1);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.QuantityX           = quantityX;
                action.QuantityY           = quantityY;
                action.MaximumApplications = maximumApplications;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1);
                cart.Adjustments.Should().BeEmpty();
                cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(175);
            }
            public void Execute_12_NoPurchaseOptionMoneyPolicy(
                CartItemQuantityXForQuantityYAction action,
                IRuleValue <string> targetItemId,
                IRuleValue <int> quantityX,
                IRuleValue <int> quantityY,
                IRuleValue <int> maximumApplications,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = false;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                while (cart.Lines.Count > 1)
                {
                    cart.Lines.RemoveAt(0);
                }
                var cartline = cart.Lines[0];

                cartline.Quantity = 4;
                cartline.Totals.SubTotal.Amount = 100;
                cartline.ItemId = "Habitat_Master|12345|";
                var cartTotals = new CartTotals(cart);

                targetItemId.Yield(context).ReturnsForAnyArgs("Habitat_Master|12345|");
                quantityX.Yield(context).ReturnsForAnyArgs(4);
                quantityY.Yield(context).ReturnsForAnyArgs(3);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.TargetItemId        = targetItemId;
                action.QuantityX           = quantityX;
                action.QuantityY           = quantityY;
                action.MaximumApplications = maximumApplications;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(0);
                cart.Adjustments.Should().BeEmpty();
            }
Пример #13
0
            public void Evaluate_HasMatchingFulfillmentMethod_True(
                IRuleValue <string> fulfillmentOptionName,
                CommerceContext commerceContext,
                Cart cart,
                IRuleExecutionContext context,
                FulfillmentComponent fulfillmentComponent,
                string fulfillmentOptionNameValue)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.SetComponent(fulfillmentComponent);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                fulfillmentOptionName.Yield(context).ReturnsForAnyArgs(fulfillmentOptionNameValue);
                var command = Substitute.For <GetFulfillmentMethodsCommand>(
                    Substitute.For <IFindEntityPipeline>(),
                    Substitute.For <IGetCartFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetCartLineFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetFulfillmentMethodsPipeline>(),
                    Substitute.For <IServiceProvider>());

                var commander         = Substitute.For <CommerceCommander>(Substitute.For <IServiceProvider>());
                var fulfillmentMethod = new FulfillmentMethod
                {
                    FulfillmentType = fulfillmentOptionNameValue,
                    Id   = fulfillmentComponent.FulfillmentMethod.EntityTarget,
                    Name = fulfillmentComponent.FulfillmentMethod.Name
                };

                command.Process(commerceContext).ReturnsForAnyArgs(new List <FulfillmentMethod>()
                {
                    fulfillmentMethod
                }.AsEnumerable());
                commander.When(x => x.Command <GetFulfillmentMethodsCommand>()).DoNotCallBase();
                commander.Command <GetFulfillmentMethodsCommand>().Returns(command);
                var condition = new CartHasFulfillmentOptionCondition(commander)
                {
                    FulfillmentOptionName = fulfillmentOptionName
                };

                /**********************************************
                * Act
                **********************************************/
                var result = condition.Evaluate(context);

                /**********************************************
                * Assert
                **********************************************/
                result.Should().BeTrue();
            }
Пример #14
0
        public static IEnumerable <CartLineComponent> YieldCartLinesWithCategory(this IRuleValue <string> ruleValue, IRuleExecutionContext context)
        {
            string targetCategory = ruleValue?.Yield(context);
            Cart   cart           = context.Fact <CommerceContext>()?.GetObject <Cart>();

            if (cart == null || !cart.Lines.Any() || string.IsNullOrEmpty(targetCategory))
            {
                return(Enumerable.Empty <CartLineComponent>());
            }

            return(cart.Lines.Where(l =>
                                    (l.GetComponent <LineItemProductExtendedComponent>().ParentCategoryList.IndexOf(targetCategory, StringComparison.OrdinalIgnoreCase) >= 0)));
        }
Пример #15
0
        public static IEnumerable <CartLineComponent> YieldCartLinesWithBrand(this IRuleValue <string> ruleValue, IRuleExecutionContext context)
        {
            string targetBrand = ruleValue?.Yield(context);
            Cart   cart        = context.Fact <CommerceContext>()?.GetObject <Cart>();

            if (cart == null || !cart.Lines.Any() || string.IsNullOrEmpty(targetBrand))
            {
                return(Enumerable.Empty <CartLineComponent>());
            }

            return(cart.Lines.Where(l =>
                                    l.GetComponent <LineItemProductExtendedComponent>().Brand.Equals(targetBrand, StringComparison.OrdinalIgnoreCase)));
        }
Пример #16
0
            public void Execute_DecimalGreaterThanEqualToOperator_True(
                BaseCartItemSubtotalAmountOffAction action,
                IRuleValue <decimal> subtotal,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = false;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                var cartline = cart.Lines[1];

                cartline.Totals.SubTotal.Amount = 175;
                var cartTotals = new CartTotals(cart);

                subtotal.Yield(context).ReturnsForAnyArgs(150);
                amountOff.Yield(context).ReturnsForAnyArgs(25);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines);
                action.SubtotalOperator = new DecimalGreaterThanEqualToOperator();
                action.Subtotal         = subtotal;
                action.AmountOff        = amountOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1);
                cart.Adjustments.Should().BeEmpty();
                cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(150);
            }
            public void Evaluate_07_NoFulfillmentComponentsOnCartLines(
                IRuleValue <string> fulfillmentOptionName,
                CommerceContext commerceContext,
                Cart cart,
                IRuleExecutionContext context,
                SplitFulfillmentComponent fulfillmentComponent,
                string fulfillmentOptionNameValue,
                IEnumerable <FulfillmentMethod> fulfillmentMethods)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.SetComponent(fulfillmentComponent);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                fulfillmentOptionName.Yield(context).ReturnsForAnyArgs(fulfillmentOptionNameValue);

                var commander = Substitute.For <CommerceCommander>(Substitute.For <IServiceProvider>());
                var command   = Substitute.For <GetFulfillmentMethodsCommand>(
                    Substitute.For <IFindEntityPipeline>(),
                    Substitute.For <IGetCartFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetCartLineFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetFulfillmentMethodsPipeline>(),
                    Substitute.For <IServiceProvider>());

                command.Process(commerceContext).ReturnsForAnyArgs(fulfillmentMethods);
                commander.When(x => x.Command <GetFulfillmentMethodsCommand>()).DoNotCallBase();
                commander.Command <GetFulfillmentMethodsCommand>().Returns(command);
                var condition = new CartLineHasFulfillmentOptionCondition(commander)
                {
                    FulfillmentOptionName = fulfillmentOptionName
                };

                /**********************************************
                * Act
                **********************************************/
                var result = condition.Evaluate(context);

                /**********************************************
                * Assert
                **********************************************/
                result.Should().BeFalse();
            }
            public void Execute_11_EqualQuantityXAndQuantityY(
                CartItemQuantityXForQuantityYAction action,
                IRuleValue <string> targetItemId,
                IRuleValue <int> quantityX,
                IRuleValue <int> quantityY,
                IRuleValue <int> maximumApplications,
                Cart cart,
                CartTotals cartTotals,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                quantityX.Yield(context).ReturnsForAnyArgs(4);
                quantityY.Yield(context).ReturnsForAnyArgs(4);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.TargetItemId        = targetItemId;
                action.QuantityX           = quantityX;
                action.QuantityY           = quantityY;
                action.MaximumApplications = maximumApplications;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().BeEmpty();
            }
Пример #19
0
            public void Execute_12_MinQuantityGreaterThanMaxQuantity(
                CartItemQuantityRangePercentOffAction action,
                IRuleValue <string> targetItemId,
                IRuleValue <decimal> minQuantity,
                IRuleValue <decimal> maxQuantity,
                IRuleValue <decimal> percentOff,
                Cart cart,
                CartTotals cartTotals,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                minQuantity.Yield(context).ReturnsForAnyArgs(2);
                maxQuantity.Yield(context).ReturnsForAnyArgs(1);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.TargetItemId = targetItemId;
                action.MinQuantity  = minQuantity;
                action.MaxQuantity  = maxQuantity;
                action.PercentOff   = percentOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().BeEmpty();
            }
Пример #20
0
        public void YieldCartLines_01_NoCommerceContext(
            IRuleValue <string> targetBrand,
            IRuleExecutionContext context)
        {
            /**********************************************
            * Arrange
            **********************************************/
            context.Fact <CommerceContext>().ReturnsForAnyArgs((CommerceContext)null);
            targetBrand.Yield(context).ReturnsForAnyArgs("Smartphone");

            /**********************************************
            * Act
            **********************************************/
            IEnumerable <CartLineComponent> matchingLines = null;
            Action executeAction = () => matchingLines = targetBrand.YieldCartLinesWithBrand(context);

            /**********************************************
            * Assert
            **********************************************/
            executeAction.Should().NotThrow <Exception>();
            matchingLines.Should().BeEmpty();
        }
Пример #21
0
            public void Execute_09_ZeroAmount(
                BaseCartItemSubtotalAmountOffAction action,
                IBinaryOperator <decimal, decimal> subtotalOperator,
                IRuleValue <decimal> subtotal,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CartTotals cartTotals,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                amountOff.Yield(context).ReturnsForAnyArgs(0);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines);
                action.SubtotalOperator = subtotalOperator;
                action.Subtotal         = subtotal;
                action.AmountOff        = amountOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().BeEmpty();
            }
            public void Execute_09_ZeroSellPrice(
                CartAnyItemQuantityXSellPriceAction action,
                IRuleValue <int> quantityX,
                IRuleValue <decimal> sellPrice,
                IRuleValue <int> maximumApplications,
                Cart cart,
                CartTotals cartTotals,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                sellPrice.Yield(context).ReturnsForAnyArgs(0);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.QuantityX           = quantityX;
                action.SellPrice           = sellPrice;
                action.MaximumApplications = maximumApplications;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().BeEmpty();
            }
Пример #23
0
            public void Execute_WithProperties(
                BaseCartItemSubtotalAmountOffAction action,
                IRuleValue <decimal> subtotal,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = false;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                var cartline = cart.Lines[1];

                cartline.Totals.SubTotal.Amount = 150;
                var cartTotals = new CartTotals(cart);

                subtotal.Yield(context).ReturnsForAnyArgs(150);
                amountOff.Yield(context).ReturnsForAnyArgs(25);
                var propertiesModel = new PropertiesModel();

                propertiesModel.Properties.Add("PromotionId", "id");
                propertiesModel.Properties.Add("PromotionCartText", "carttext");
                propertiesModel.Properties.Add("PromotionText", "text");
                commerceContext.AddObject(propertiesModel);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines);
                action.SubtotalOperator = new DecimalGreaterThanEqualToOperator();
                action.Subtotal         = subtotal;
                action.AmountOff        = amountOff;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1);
                cart.Adjustments.Should().BeEmpty();
                cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(125);
                cartline.Adjustments.Should().NotBeEmpty();
                cartline.Adjustments.FirstOrDefault().Should().NotBeNull();
                cartline.Adjustments.FirstOrDefault().Should().BeOfType <CartLineLevelAwardedAdjustment>();
                cartline.Adjustments.FirstOrDefault()?.Name.Should().Be("text");
                cartline.Adjustments.FirstOrDefault()?.DisplayName.Should().Be("carttext");
                cartline.Adjustments.FirstOrDefault()?.AdjustmentType.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount);
                cartline.Adjustments.FirstOrDefault()?.AwardingBlock.Should().Contain(nameof(BaseCartItemSubtotalAmountOffAction));
                cartline.Adjustments.FirstOrDefault()?.IsTaxable.Should().BeFalse();
                cartline.Adjustments.FirstOrDefault()?.Adjustment.CurrencyCode.Should().Be(commerceContext.CurrentCurrency());
                cartline.Adjustments.FirstOrDefault()?.Adjustment.Amount.Should().Be(-25);
                cartline.HasComponent <MessagesComponent>().Should().BeTrue();
            }
            public void Execute_WithProperties(
                IRuleValue <string> fulfillmentOptionName,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context,
                string fulfillmentOptionNameValue,
                FulfillmentComponent fulfillmentComponent)
            {
                /**********************************************
                * Arrange
                **********************************************/
                const decimal FULFILLMENT_FEE = MINIMUM_AMOUNT_OFF + 10m;

                cart.Adjustments.Clear();
                var awardedAdjustment = new AwardedAdjustment()
                {
                    Name = "FulfillmentFee"
                };

                awardedAdjustment.Adjustment = new Money(FULFILLMENT_FEE);
                cart.Adjustments.Add(awardedAdjustment);
                cart.Lines.ForEach(l => l.Adjustments.Clear());
                cart.SetComponent(fulfillmentComponent);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc = false;
                fulfillmentOptionName.Yield(context).ReturnsForAnyArgs(fulfillmentOptionNameValue);
                amountOff.Yield(context).ReturnsForAnyArgs(MINIMUM_AMOUNT_OFF);
                var propertiesModel = new PropertiesModel();

                propertiesModel.Properties.Add("PromotionId", "id");
                propertiesModel.Properties.Add("PromotionCartText", "carttext");
                propertiesModel.Properties.Add("PromotionText", "text");
                commerceContext.AddObject(propertiesModel);

                var commander = Substitute.For <CommerceCommander>(Substitute.For <IServiceProvider>());
                var command   = Substitute.For <GetFulfillmentMethodsCommand>(
                    Substitute.For <IFindEntityPipeline>(),
                    Substitute.For <IGetCartFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetCartLineFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetFulfillmentMethodsPipeline>(),
                    Substitute.For <IServiceProvider>());

                var fulfillmentMethod = new FulfillmentMethod()
                {
                    FulfillmentType = fulfillmentOptionNameValue
                };

                command.Process(commerceContext).ReturnsForAnyArgs(new List <FulfillmentMethod>()
                {
                    fulfillmentMethod
                }.AsEnumerable());
                commander.When(x => x.Command <GetFulfillmentMethodsCommand>()).DoNotCallBase();
                commander.Command <GetFulfillmentMethodsCommand>().Returns(command);
                var action = new CartShippingOptionAmountOffAction(commander)
                {
                    FulfillmentOptionName = fulfillmentOptionName,
                    AmountOff             = amountOff
                };

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(0);
                cart.Adjustments.Should().NotBeEmpty();
                cart.Adjustments.LastOrDefault().Should().NotBeNull();
                cart.Adjustments.LastOrDefault().Should().BeOfType <CartLevelAwardedAdjustment>();
                cart.Adjustments.LastOrDefault().Name.Should().Be("text");
                cart.Adjustments.LastOrDefault().DisplayName.Should().Be("carttext");
                cart.Adjustments.LastOrDefault().AdjustmentType.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount);
                cart.Adjustments.LastOrDefault().AwardingBlock.Should().Contain(nameof(CartShippingOptionAmountOffAction));
                cart.Adjustments.LastOrDefault().IsTaxable.Should().BeFalse();
                cart.Adjustments.LastOrDefault().Adjustment.CurrencyCode.Should().Be(commerceContext.CurrentCurrency());
                cart.Adjustments.LastOrDefault().Adjustment.Amount.Should().Be(-MINIMUM_AMOUNT_OFF);
                cart.HasComponent <MessagesComponent>().Should().BeTrue();
            }
            public void Execute_AmountOffLessThanFulfillmentFee_False(
                IRuleValue <string> fulfillmentOptionName,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context,
                string fulfillmentOptionNameValue,
                FulfillmentComponent fulfillmentComponent)
            {
                /**********************************************
                * Arrange
                **********************************************/
                const decimal FULFILLMENT_FEE = 10m;
                const decimal AMOUNT_OFF      = FULFILLMENT_FEE + 1m;

                cart.Adjustments.Clear();
                var awardedAdjustment = new AwardedAdjustment()
                {
                    Name = "FulfillmentFee"
                };

                awardedAdjustment.Adjustment = new Money(FULFILLMENT_FEE);
                cart.Adjustments.Add(awardedAdjustment);
                cart.Lines.ForEach(l => l.Adjustments.Clear());
                cart.SetComponent(fulfillmentComponent);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cart);

                fulfillmentOptionName.Yield(context).ReturnsForAnyArgs(fulfillmentOptionNameValue);
                amountOff.Yield(context).ReturnsForAnyArgs(AMOUNT_OFF);

                var commander = Substitute.For <CommerceCommander>(Substitute.For <IServiceProvider>());
                var command   = Substitute.For <GetFulfillmentMethodsCommand>(
                    Substitute.For <IFindEntityPipeline>(),
                    Substitute.For <IGetCartFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetCartLineFulfillmentMethodsPipeline>(),
                    Substitute.For <IGetFulfillmentMethodsPipeline>(),
                    Substitute.For <IServiceProvider>());

                var fulfillmentMethod = new FulfillmentMethod()
                {
                    FulfillmentType = fulfillmentOptionNameValue
                };

                command.Process(commerceContext).ReturnsForAnyArgs(new List <FulfillmentMethod>()
                {
                    fulfillmentMethod
                }.AsEnumerable());
                commander.When(x => x.Command <GetFulfillmentMethodsCommand>()).DoNotCallBase();
                commander.Command <GetFulfillmentMethodsCommand>().Returns(command);
                var action = new CartShippingOptionAmountOffAction(commander)
                {
                    FulfillmentOptionName = fulfillmentOptionName,
                    AmountOff             = amountOff
                };

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                command.Received().Process(commerceContext);
                cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty();
                cart.Adjustments.Should().HaveCount(2, "The cart adjustments should only contain the fulfillment fee and shipping discount adjustments.");
                var adjustment = cart.Adjustments.LastOrDefault();

                adjustment.Adjustment.Amount.Should().Be(-FULFILLMENT_FEE, "Adjustment amount should match the AmountOff rule.");
            }
Пример #26
0
            public void Execute_TimesQualified_One_UpperLimit(
                CartItemQuantityXSellPriceAction action,
                IRuleValue <string> targetItemId,
                IRuleValue <int> quantityX,
                IRuleValue <decimal> sellPrice,
                IRuleValue <int> maximumApplications,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Lines.ForEach(l => l.Adjustments.Clear());

                var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>();

                globalPricingPolicy.ShouldRoundPriceCalc         = false;
                cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100);
                while (cart.Lines.Count > 1)
                {
                    cart.Lines.RemoveAt(0);
                }
                var cartline = cart.Lines[0];

                cartline.Quantity = 3;
                cartline.Totals.SubTotal.Amount = 225;
                cartline.ItemId = "Habitat_Master|12345|";
                cartline.SetPolicy(new PurchaseOptionMoneyPolicy
                {
                    SellPrice = new Money(75)
                });
                var cartTotals = new CartTotals(cart);

                targetItemId.Yield(context).ReturnsForAnyArgs("Habitat_Master|12345|");
                quantityX.Yield(context).ReturnsForAnyArgs(2);
                sellPrice.Yield(context).ReturnsForAnyArgs(40);
                maximumApplications.Yield(context).ReturnsForAnyArgs(0);

                context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext);
                commerceContext.AddObject(cartTotals);
                commerceContext.AddObject(cart);
                action.TargetItemId        = targetItemId;
                action.QuantityX           = quantityX;
                action.SellPrice           = sellPrice;
                action.MaximumApplications = maximumApplications;

                /**********************************************
                * Act
                **********************************************/
                Action executeAction = () => action.Execute(context);

                /**********************************************
                * Assert
                **********************************************/
                executeAction.Should().NotThrow <Exception>();
                cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1);
                cart.Adjustments.Should().BeEmpty();
                cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(115);
            }