public void Execute_AmountOffLessThanFulfillmentFee_True(
                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);

                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().HaveCount(2, "The cart adjustments should only contain the fulfillment fee and shipping discount adjustments.");
                var adjustment = cart.Adjustments.LastOrDefault();

                adjustment.AwardingBlock.Should().Be(nameof(CartShippingOptionAmountOffAction), "Adjustment should be awarded by CartShippingOptionAmountOffAction.");
                adjustment.Adjustment.Amount.Should().Be(-MINIMUM_AMOUNT_OFF, "Adjustment amount should match the AmountOff rule.");
            }
            public void Execute_13_ZeroDiscount(
                IRuleValue <string> fulfillmentOptionName,
                IRuleValue <decimal> amountOff,
                Cart cart,
                CommerceContext commerceContext,
                IRuleExecutionContext context,
                string fulfillmentOptionNameValue,
                FulfillmentComponent fulfillmentComponent)
            {
                /**********************************************
                * Arrange
                **********************************************/
                cart.Adjustments.Clear();
                cart.Adjustments.Add(new AwardedAdjustment()
                {
                    Name = "FulfillmentFee"
                });
                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(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.Count.Should().Be(1);
            }