using Grand.Business.Catalog.Services.Products;
using Grand.Business.Checkout.Validators;
using Grand.Business.Core.Interfaces.Catalog.Products;
using Grand.Business.Core.Interfaces.Checkout.CheckoutAttributes;
using Grand.Business.Core.Interfaces.Common.Localization;
using Grand.Business.Core.Interfaces.Common.Security;
using Grand.Domain;
using Grand.Domain.Catalog;
using Grand.Domain.Common;
using Grand.Domain.Customers;
using Grand.Domain.Orders;
using Grand.Domain.Permissions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Grand.Business.Checkout.Tests.Validators
{
    [TestClass]
    public class ShoppingCartValidatorsTests
    {
        private Mock<ITranslationService> _translationServiceMock;
        private Mock<ICheckoutAttributeParser> _checkoutAttributeParserMock;
        private Mock<ICheckoutAttributeService> _checkoutAttributeServiceMock;
        private Mock<IProductService> _productServiceMock;
        private Mock<IAclService> _aclServiceMock;
        private Mock<IProductAttributeService> _productAttributeService;
        private Mock<IProductReservationService> _productReservationServiceMock;
        private Mock<IPermissionService> _permissionServiceMock;
        private IStockQuantityService _stockQuantityService;

        [TestInitialize]
        public void Init()
        {
            _translationServiceMock = new Mock<ITranslationService>();
            _checkoutAttributeParserMock = new Mock<ICheckoutAttributeParser>();
            _checkoutAttributeServiceMock = new Mock<ICheckoutAttributeService>();
            _productServiceMock = new Mock<IProductService>();
            _aclServiceMock = new Mock<IAclService>();
            _productAttributeService = new Mock<IProductAttributeService>();
            _productReservationServiceMock = new Mock<IProductReservationService>();
            _permissionServiceMock = new Mock<IPermissionService>();
            _stockQuantityService = new StockQuantityService(_translationServiceMock.Object);
            _translationServiceMock.Setup(x => x.GetResource(It.IsAny<string>())).Returns("Name");
        }

        [TestMethod]
        public void ShoppingCartAuctionValidator_Success()
        {
            //Arrange
            var shoppingCartAuctionValidator = new ShoppingCartAuctionValidator(_translationServiceMock.Object);
            //Act
            var result = shoppingCartAuctionValidator.Validate(new ShoppingCartAuctionValidatorRecord(new Domain.Customers.Customer(), new Domain.Catalog.Product() { AvailableEndDateTimeUtc = DateTime.UtcNow.AddDays(1) }, new Domain.Orders.ShoppingCartItem(), 10));
            //Assert
            Assert.IsTrue(result.IsValid);

        }

        [TestMethod]
        public void ShoppingCartAuctionValidator_Fail()
        {
            //Arrange
            var shoppingCartAuctionValidator = new ShoppingCartAuctionValidator(_translationServiceMock.Object);
            //Act
            var result = shoppingCartAuctionValidator.Validate(new ShoppingCartAuctionValidatorRecord(new Domain.Customers.Customer(), new Domain.Catalog.Product() { AvailableEndDateTimeUtc = DateTime.UtcNow.AddDays(1), StartPrice = 20 }, new Domain.Orders.ShoppingCartItem(), 10));
            //Assert
            Assert.IsFalse(result.IsValid);
        }
        [TestMethod]
        public void ShoppingCartGiftVoucherValidator_Success()
        {
            //Arrange
            var shoppingCartGiftVoucherValidator = new ShoppingCartGiftVoucherValidator(_translationServiceMock.Object);
            var customAttributes = new List<CustomAttribute>();
            customAttributes.Add(new CustomAttribute() { Key = "RecipientName", Value = "value" });
            customAttributes.Add(new CustomAttribute() { Key = "RecipientEmail", Value = "value@emai.com" });
            customAttributes.Add(new CustomAttribute() { Key = "SenderName", Value = "value" });
            customAttributes.Add(new CustomAttribute() { Key = "SenderEmail", Value = "value@email.com" });
            customAttributes.Add(new CustomAttribute() { Key = "Message", Value = "value" });
            //Act
            var result = shoppingCartGiftVoucherValidator.Validate(new ShoppingCartGiftVoucherValidatorRecord(new Domain.Customers.Customer(), new Domain.Catalog.Product() {
                GiftVoucherTypeId = GiftVoucherType.Virtual
            }, new Domain.Orders.ShoppingCartItem() { Attributes = customAttributes }));
            //Assert
            Assert.IsTrue(result.IsValid);

        }

        [TestMethod]
        public void ShoppingCartGiftVoucherValidator_Fail_Wrong_SenderEmail()
        {
            //Arrange
            var shoppingCartGiftVoucherValidator = new ShoppingCartGiftVoucherValidator(_translationServiceMock.Object);
            var customAttributes = new List<CustomAttribute>();
            customAttributes.Add(new CustomAttribute() { Key = "RecipientName", Value = "value" });
            customAttributes.Add(new CustomAttribute() { Key = "RecipientEmail", Value = "value@emai.com" });
            customAttributes.Add(new CustomAttribute() { Key = "SenderName", Value = "value" });
            customAttributes.Add(new CustomAttribute() { Key = "SenderEmail", Value = "@email.com" });
            customAttributes.Add(new CustomAttribute() { Key = "Message", Value = "value" });
            //Act
            var result = shoppingCartGiftVoucherValidator.Validate(new ShoppingCartGiftVoucherValidatorRecord(new Domain.Customers.Customer(), new Domain.Catalog.Product() {
                GiftVoucherTypeId = GiftVoucherType.Virtual
            }, new Domain.Orders.ShoppingCartItem() { Attributes = customAttributes }));
            //Assert
            Assert.IsFalse(result.IsValid);

        }

        [TestMethod]
        public async Task ShoppingCartCheckoutAttributesValidator_Success()
        {
            //Arrange
            var shoppingCartCheckoutValidator = new ShoppingCartCheckoutAttributesValidator(_translationServiceMock.Object,
                _checkoutAttributeParserMock.Object, _checkoutAttributeServiceMock.Object);

            _checkoutAttributeParserMock.Setup(x => x.ParseCheckoutAttributes(It.IsAny<IList<CustomAttribute>>()))
                .Returns(() => Task.FromResult((IList<CheckoutAttribute>)new List<CheckoutAttribute>() { new CheckoutAttribute() { Id = "1", Name = "test", IsRequired = true, AttributeControlTypeId = AttributeControlType.TextBox } }));

            _checkoutAttributeServiceMock.Setup(x => x.GetAllCheckoutAttributes(It.IsAny<string>(), true, false))
                .Returns(() => Task.FromResult((IList<CheckoutAttribute>)new List<CheckoutAttribute>() { new CheckoutAttribute() { Id = "1", Name = "test", IsRequired = true, AttributeControlTypeId = AttributeControlType.TextBox } }));

            _checkoutAttributeParserMock.Setup(x => x.IsConditionMet(
                It.IsAny<CheckoutAttribute>(), It.IsAny<IList<CustomAttribute>>())).Returns(() => Task.FromResult((bool?)true));

            //Act
            var result = await shoppingCartCheckoutValidator.ValidateAsync(new ShoppingCartCheckoutAttributesValidatorRecord(
                new Domain.Customers.Customer(),
                new Domain.Stores.Store(),
                new List<ShoppingCartItem>() { new ShoppingCartItem() { } },
                new List<CustomAttribute>() { new CustomAttribute() { Key = "1", Value = "test" } }
                ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartCheckoutAttributesValidator_Fail()
        {
            //Arrange
            var shoppingCartCheckoutValidator = new ShoppingCartCheckoutAttributesValidator(_translationServiceMock.Object,
                _checkoutAttributeParserMock.Object, _checkoutAttributeServiceMock.Object);

            _checkoutAttributeParserMock.Setup(x => x.ParseCheckoutAttributes(It.IsAny<IList<CustomAttribute>>()))
                .Returns(() => Task.FromResult((IList<CheckoutAttribute>)new List<CheckoutAttribute>() { new CheckoutAttribute() { Id = "1", Name = "test", IsRequired = true, AttributeControlTypeId = AttributeControlType.TextBox, ValidationMinLength = 10 } }));

            _checkoutAttributeServiceMock.Setup(x => x.GetAllCheckoutAttributes(It.IsAny<string>(), true, false))
                .Returns(() => Task.FromResult((IList<CheckoutAttribute>)new List<CheckoutAttribute>() { new CheckoutAttribute() { Id = "1", Name = "test", IsRequired = true, AttributeControlTypeId = AttributeControlType.TextBox, ValidationMinLength = 10 } }));

            _checkoutAttributeParserMock.Setup(x => x.IsConditionMet(
                It.IsAny<CheckoutAttribute>(), It.IsAny<IList<CustomAttribute>>())).Returns(() => Task.FromResult((bool?)true));

            //Act
            var result = await shoppingCartCheckoutValidator.ValidateAsync(new ShoppingCartCheckoutAttributesValidatorRecord(
                new Domain.Customers.Customer(),
                new Domain.Stores.Store(),
                new List<ShoppingCartItem>() { new ShoppingCartItem() { } },
                new List<CustomAttribute>() { new CustomAttribute() { Key = "1", Value = "" } }
                ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartInventoryProductValidator_Success()
        {
            //Arrange
            var shoppingCartInventoryValidator = new ShoppingCartInventoryProductValidator(_translationServiceMock.Object,
                _productServiceMock.Object, _stockQuantityService, new ShoppingCartSettings() { });

            //Act
            var result = await shoppingCartInventoryValidator.ValidateAsync(new ShoppingCartInventoryProductValidatorRecord(
                new Domain.Customers.Customer(),
                new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock },
                new ShoppingCartItem() { ProductId = "1", Quantity = 1 }
                ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartInventoryProductValidator_Fail()
        {
            //Arrange
            var shoppingCartInventoryValidator = new ShoppingCartInventoryProductValidator(_translationServiceMock.Object,
                _productServiceMock.Object, _stockQuantityService, new ShoppingCartSettings() { });

            //Act
            var result = await shoppingCartInventoryValidator.ValidateAsync(new ShoppingCartInventoryProductValidatorRecord(
                new Domain.Customers.Customer(),
                new Product() { Id = "1", StockQuantity = 0, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock },
                new ShoppingCartItem() { ProductId = "1", Quantity = 1 }
                ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartItemAttributeValidator_Success()
        {
            //Arrange
            var shoppingCartItemAttributeValidator = new ShoppingCartItemAttributeValidator(_translationServiceMock.Object,
                _productServiceMock.Object, _productAttributeService.Object);

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            _productAttributeService.Setup(x => x.GetProductAttributeById(It.IsAny<string>()))
                .Returns(() => Task.FromResult(new ProductAttribute() { Name = "test" }));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            var mapping = new ProductAttributeMapping() { Id = "1", ProductAttributeId = "1", AttributeControlTypeId = AttributeControlType.DropdownList, IsRequired = true };
            mapping.ProductAttributeValues.Add(new ProductAttributeValue() { Id = "1", Name = "a" });
            product.ProductAttributeMappings.Add(mapping);

            var attributes = new List<CustomAttribute>() { new CustomAttribute() { Key = "1", Value = "1" } };

            //Act
            var result = await shoppingCartItemAttributeValidator.ValidateAsync(new ShoppingCartItemAttributeValidatorRecord(
                new Domain.Customers.Customer(),
                product,
                new ShoppingCartItem() { ProductId = "1", Quantity = 1, Attributes = attributes },
                false
                ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartItemAttributeValidator_Fail()
        {
            //Arrange
            var shoppingCartItemAttributeValidator = new ShoppingCartItemAttributeValidator(_translationServiceMock.Object,
                _productServiceMock.Object, _productAttributeService.Object);

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            _productAttributeService.Setup(x => x.GetProductAttributeById(It.IsAny<string>()))
                .Returns(() => Task.FromResult(new ProductAttribute() { Name = "test" }));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            var mapping = new ProductAttributeMapping() { Id = "1", ProductAttributeId = "1", AttributeControlTypeId = AttributeControlType.DropdownList, IsRequired = true };
            mapping.ProductAttributeValues.Add(new ProductAttributeValue() { Id = "1", Name = "a" });
            product.ProductAttributeMappings.Add(mapping);

            var attributes = new List<CustomAttribute>() { new CustomAttribute() { Key = "2" } };

            //Act
            var result = await shoppingCartItemAttributeValidator.ValidateAsync(new ShoppingCartItemAttributeValidatorRecord(
                new Domain.Customers.Customer(),
                product,
                new ShoppingCartItem() { ProductId = "1", Quantity = 1, Attributes = attributes },
                false
                ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartRequiredProductValidator_Success()
        {
            //Arrange
            var shoppingCartRequiredProductValidator = new ShoppingCartRequiredProductValidator(_translationServiceMock.Object, _productServiceMock.Object, new ShoppingCartSettings());

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            _productServiceMock.Setup(x => x.GetProductById("1", false))
                .Returns(() => Task.FromResult(new Product() { Id = "1", Name = "test" }));

            _productServiceMock.Setup(x => x.GetProductById("2", false))
                 .Returns(() => Task.FromResult(new Product() { Id = "2", Name = "test" }));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            product.RequireOtherProducts = true;
            product.RequiredProductIds = "2";
            var customer = new Domain.Customers.Customer();
            customer.ShoppingCartItems.Add(new ShoppingCartItem() { ProductId = "2", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" });
            //Act
            var result = await shoppingCartRequiredProductValidator.ValidateAsync(new ShoppingCartRequiredProductValidatorRecord(
                customer,
                new Domain.Stores.Store() { Id = "1" },
                product,
                new ShoppingCartItem() { ProductId = "1", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" }
                ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartRequiredProductValidator_Fail()
        {
            //Arrange
            var shoppingCartRequiredProductValidator = new ShoppingCartRequiredProductValidator(_translationServiceMock.Object, _productServiceMock.Object, new ShoppingCartSettings());

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            _productServiceMock.Setup(x => x.GetProductById("1", false))
                .Returns(() => Task.FromResult(new Product() { Id = "1", Name = "test" }));

            _productServiceMock.Setup(x => x.GetProductById("2", false))
                 .Returns(() => Task.FromResult(new Product() { Id = "2", Name = "test" }));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            product.RequireOtherProducts = true;
            product.RequiredProductIds = "2";
            var customer = new Domain.Customers.Customer();
            //Act
            var result = await shoppingCartRequiredProductValidator.ValidateAsync(new ShoppingCartRequiredProductValidatorRecord(
                customer,
                new Domain.Stores.Store() { Id = "1" },
                product,
                new ShoppingCartItem() { ProductId = "2", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" }
                ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartReservationProductValidator_Success()
        {
            //Arrange
            var shoppingCartReservationProductValidator = new ShoppingCartReservationProductValidator(_translationServiceMock.Object, _productReservationServiceMock.Object);

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            _productServiceMock.Setup(x => x.GetProductById("1", false))
                .Returns(() => Task.FromResult(new Product() { Id = "1", Name = "test" }));


            _productReservationServiceMock.Setup(x => x.GetCustomerReservationsHelpers(It.IsAny<string>()))
                .Returns(() => Task.FromResult((IList<CustomerReservationsHelper>)new List<CustomerReservationsHelper>() { new CustomerReservationsHelper() { Id = "1", CustomerId = "1", ShoppingCartItemId = "2" } }));

            _productReservationServiceMock.Setup(x => x.GetProductReservationsByProductId(It.IsAny<string>(), true, null, 0, int.MaxValue))
                .Returns(() => Task.FromResult((IPagedList<ProductReservation>)
                new PagedList<ProductReservation>() {
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(4).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(3).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(2).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(1).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.Date, Resource = "" } }
                ));


            var product = new Product() { Id = "1", ProductTypeId = ProductType.Reservation, IntervalUnitId = IntervalUnit.Day };

            var customer = new Domain.Customers.Customer();
            customer.ShoppingCartItems.Add(new ShoppingCartItem() { Id = "1", ProductId = "2", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" });
            //Act
            var result = await shoppingCartReservationProductValidator.ValidateAsync(new ShoppingCartReservationProductValidatorRecord(
                customer,
                product,
                new ShoppingCartItem() {
                    ProductId = "1",
                    Quantity = 1,
                    ShoppingCartTypeId = ShoppingCartType.ShoppingCart,
                    StoreId = "1",
                    RentalStartDateUtc = DateTime.UtcNow.AddDays(1).Date,
                    RentalEndDateUtc = DateTime.UtcNow.AddDays(2).Date
                }
                ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartReservationProductValidator_Fail()
        {
            //Arrange
            var shoppingCartReservationProductValidator = new ShoppingCartReservationProductValidator(_translationServiceMock.Object, _productReservationServiceMock.Object);

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            _productServiceMock.Setup(x => x.GetProductById("1", false))
                .Returns(() => Task.FromResult(new Product() { Id = "1", Name = "test" }));


            _productReservationServiceMock.Setup(x => x.GetCustomerReservationsHelpers(It.IsAny<string>()))
                .Returns(() => Task.FromResult((IList<CustomerReservationsHelper>)new List<CustomerReservationsHelper>() { new CustomerReservationsHelper() { Id = "1", CustomerId = "1", ShoppingCartItemId = "2" } }));

            _productReservationServiceMock.Setup(x => x.GetProductReservationsByProductId(It.IsAny<string>(), true, null, 0, int.MaxValue))
                .Returns(() => Task.FromResult((IPagedList<ProductReservation>)
                new PagedList<ProductReservation>() {
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(10).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(9).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(8).Date, Resource = "" },
                    new ProductReservation() { Id = "1", Date = DateTime.UtcNow.AddDays(7).Date, Resource = "" } }
                ));


            var product = new Product() { Id = "1", ProductTypeId = ProductType.Reservation, IntervalUnitId = IntervalUnit.Day };

            var customer = new Domain.Customers.Customer();
            customer.ShoppingCartItems.Add(new ShoppingCartItem() { Id = "1", ProductId = "2", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" });
            //Act
            var result = await shoppingCartReservationProductValidator.ValidateAsync(new ShoppingCartReservationProductValidatorRecord(
                customer,
                product,
                new ShoppingCartItem() {
                    ProductId = "1",
                    Quantity = 1,
                    ShoppingCartTypeId = ShoppingCartType.ShoppingCart,
                    StoreId = "1",
                    RentalStartDateUtc = DateTime.UtcNow.AddDays(1).Date,
                    RentalEndDateUtc = DateTime.UtcNow.AddDays(2).Date
                }
                ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartCommonWarningsValidator_Success()
        {
            //Arrange
            var shoppingCartCommonWarningsValidator = new ShoppingCartCommonWarningsValidator(_translationServiceMock.Object, _permissionServiceMock.Object, new ShoppingCartSettings() {
                MiniCartProductNumber = 1,
                MaximumShoppingCartItems = 100
            });
            _permissionServiceMock.Setup(x => x.Authorize(It.IsAny<Permission>(), It.IsAny<Customer>())).Returns(async () => await Task.FromResult(true));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            var customer = new Domain.Customers.Customer();
            customer.ShoppingCartItems.Add(new ShoppingCartItem() { ProductId = "2", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" });
            //Act
            var result = await shoppingCartCommonWarningsValidator.ValidateAsync(new ShoppingCartCommonWarningsValidatorRecord(
                customer,
                new Domain.Stores.Store() { Id = "1" },
                new List<ShoppingCartItem>() {
                    new ShoppingCartItem() { ProductId = "1", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" }
                },
                product, ShoppingCartType.ShoppingCart, null, null, 1, "")
                );

            //Assert
            Assert.IsTrue(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartCommonWarningsValidator_Fail()
        {
            //Arrange
            var shoppingCartCommonWarningsValidator = new ShoppingCartCommonWarningsValidator(_translationServiceMock.Object, _permissionServiceMock.Object, new ShoppingCartSettings() {
                MiniCartProductNumber = 1,
                MaximumShoppingCartItems = 100
            });
            _permissionServiceMock.Setup(x => x.Authorize(It.IsAny<Permission>(), It.IsAny<Customer>())).Returns(async () => await Task.FromResult(false));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            var customer = new Domain.Customers.Customer();
            customer.ShoppingCartItems.Add(new ShoppingCartItem() { ProductId = "2", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" });
            //Act
            var result = await shoppingCartCommonWarningsValidator.ValidateAsync(new ShoppingCartCommonWarningsValidatorRecord(
                customer,
                new Domain.Stores.Store() { Id = "1" },
                new List<ShoppingCartItem>() {
                    new ShoppingCartItem() { ProductId = "1", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" }
                },
                product, ShoppingCartType.ShoppingCart, null, null, 1, "")
                );

            //Assert
            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartStandardValidator_Success()
        {
            //Arrange
            var shoppingCartStandardValidator = new ShoppingCartStandardValidator(_translationServiceMock.Object, _aclServiceMock.Object);
            _aclServiceMock.Setup(x => x.Authorize(It.IsAny<Product>(), It.IsAny<Customer>())).Returns(() => true);
            _aclServiceMock.Setup(x => x.Authorize(It.IsAny<Product>(), It.IsAny<string>())).Returns(() => true);

            var product = new Product() { 
                Id = "1", 
                Published = true,
            };
            var customer = new Domain.Customers.Customer();
            //Act
            var result = await shoppingCartStandardValidator.ValidateAsync(new ShoppingCartStandardValidatorRecord(
                customer,
                product,
                new ShoppingCartItem() { ProductId = "1", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" }
               ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartStandardValidator_Fail()
        {
            //Arrange
            var shoppingCartStandardValidator = new ShoppingCartStandardValidator(_translationServiceMock.Object, _aclServiceMock.Object);
            _aclServiceMock.Setup(x => x.Authorize(It.IsAny<Product>(), It.IsAny<Customer>())).Returns(() => false);
            _aclServiceMock.Setup(x => x.Authorize(It.IsAny<Product>(), It.IsAny<string>())).Returns(() => true);

            var product = new Product() {
                Id = "1",
                Published = true,
            };
            var customer = new Domain.Customers.Customer();
            //Act
            var result = await shoppingCartStandardValidator.ValidateAsync(new ShoppingCartStandardValidatorRecord(
                customer,
                product,
                new ShoppingCartItem() { ProductId = "1", Quantity = 1, ShoppingCartTypeId = ShoppingCartType.ShoppingCart, StoreId = "1" }
               ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }

        [TestMethod]
        public async Task ShoppingCartWarningsValidator_Success()
        {
            //Arrange
            var shoppingCartWarningsValidator = new ShoppingCartWarningsValidator(_translationServiceMock.Object, _productServiceMock.Object);

            _productServiceMock.Setup(x => x.GetProductById(It.IsAny<string>(), false))
                .Returns(() => Task.FromResult(new Product()));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            var mapping = new ProductAttributeMapping() { Id = "1", ProductAttributeId = "1", AttributeControlTypeId = AttributeControlType.DropdownList, IsRequired = true };
            mapping.ProductAttributeValues.Add(new ProductAttributeValue() { Id = "1", Name = "a" });
            product.ProductAttributeMappings.Add(mapping);

            var attributes = new List<CustomAttribute>() { new CustomAttribute() { Key = "1", Value = "1" } };

            //Act
            var result = await shoppingCartWarningsValidator.ValidateAsync(new ShoppingCartWarningsValidatorRecord(
                new Domain.Customers.Customer(),
                new Domain.Stores.Store(),
                new List<ShoppingCartItem>()
                {
                    new ShoppingCartItem() { ProductId = "1", Quantity = 1, Attributes = attributes }
                }
                ));

            //Assert
            Assert.IsTrue(result.IsValid);
        }
        [TestMethod]
        public async Task ShoppingCartWarningsValidator_Fail()
        {
            //Arrange
            var shoppingCartWarningsValidator = new ShoppingCartWarningsValidator(_translationServiceMock.Object, _productServiceMock.Object);

            _productServiceMock.Setup(x => x.GetProductById("1", false))
                .Returns(() => Task.FromResult(new Product() { IsRecurring = true, RecurringCyclePeriodId = RecurringCyclePeriod.Weeks }));
            _productServiceMock.Setup(x => x.GetProductById("2", false))
                .Returns(() => Task.FromResult(new Product() { IsRecurring = false }));

            var product = new Product() { Id = "1", StockQuantity = 1, OrderMinimumQuantity = 1, OrderMaximumQuantity = 10, ManageInventoryMethodId = ManageInventoryMethod.ManageStock };
            var mapping = new ProductAttributeMapping() { Id = "1", ProductAttributeId = "1", AttributeControlTypeId = AttributeControlType.DropdownList, IsRequired = true };
            mapping.ProductAttributeValues.Add(new ProductAttributeValue() { Id = "1", Name = "a" });
            product.ProductAttributeMappings.Add(mapping);

            var attributes = new List<CustomAttribute>() { new CustomAttribute() { Key = "1", Value = "1" } };

            //Act
            var result = await shoppingCartWarningsValidator.ValidateAsync(new ShoppingCartWarningsValidatorRecord(
                new Domain.Customers.Customer(),
                new Domain.Stores.Store(),
                new List<ShoppingCartItem>()
                {
                    new ShoppingCartItem() { ProductId = "1", Quantity = 1, Attributes = attributes },
                    new ShoppingCartItem() { ProductId = "2", Quantity = 1, Attributes = attributes }
                }
                ));

            //Assert
            Assert.IsFalse(result.IsValid);
        }
    }
}
