public void CreateShoppingBasket_1InputLineWith1Book_1BookInShoppingBasket()
        {
            //Arrange
            string[] inputLines = new string[]
            {
                "1 book at 12.49"
            };
            IDictionary <string, CategoryType> productCategories = new Dictionary <string, CategoryType>()
            {
                { "book", CategoryType.Books }
            };

            //Act
            ShoppingBasket shoppingBasket = _shoppingBasketCreator.CreateShoppingBasket(inputLines, productCategories);

            //Assert
            Assert.AreEqual(1, shoppingBasket.Products.Count);

            IProduct product = shoppingBasket.Products.Single();

            Assert.AreEqual(1, product.Quantity);
            Assert.AreEqual("book", product.ProductName);
            Assert.AreEqual("1 book", product.Description);
            Assert.AreEqual(CategoryType.Books, product.Category);
            Assert.AreEqual(false, product.IsImported);
            Assert.AreEqual(12.49, product.Price);
            Assert.AreEqual("1 book", product.GetDescription());
            Assert.AreEqual(12.49, product.CalculateGrossAmount());
        }
        public void CreateShoppingBasket_2InputLinesWith1ImportedBookAnd2Cakes_2ProductsInShoppingBasket()
        {
            //Arrange
            string[] inputLines = new string[]
            {
                "1 imported book at 12.49",
                "2 cake at 10",
            };
            IDictionary <string, CategoryType> productCategories = new Dictionary <string, CategoryType>()
            {
                { "book", CategoryType.Books },
                { "cake", CategoryType.Foods }
            };

            //Act
            ShoppingBasket shoppingBasket = _shoppingBasketCreator.CreateShoppingBasket(inputLines, productCategories);

            //Assert
            Assert.AreEqual(2, shoppingBasket.Products.Count);

            IProduct book = shoppingBasket.Products.First();

            Assert.AreEqual(1, book.Quantity);
            Assert.AreEqual("book", book.ProductName);
            Assert.AreEqual("1 imported book", book.Description);
            Assert.AreEqual(CategoryType.Books, book.Category);
            Assert.AreEqual(true, book.IsImported);
            Assert.AreEqual(12.49, book.Price);
            Assert.AreEqual("1 imported book", book.GetDescription());
            Assert.AreEqual(12.49, book.CalculateGrossAmount());

            IProduct cake = shoppingBasket.Products.Last();

            Assert.AreEqual(2, cake.Quantity);
            Assert.AreEqual("cake", cake.ProductName);
            Assert.AreEqual("2 cake", cake.Description);
            Assert.AreEqual(CategoryType.Foods, cake.Category);
            Assert.AreEqual(false, cake.IsImported);
            Assert.AreEqual(20, cake.Price);
            Assert.AreEqual("2 cake", cake.GetDescription());
            Assert.AreEqual(20, cake.CalculateGrossAmount());
        }
        public IList<TaxedProduct> ApplyTaxes(ShoppingBasket shoppingBasket)
        {
            if (shoppingBasket == null) throw new ArgumentNullException(nameof(shoppingBasket));

            IList<TaxedProduct> taxedProducts = new List<TaxedProduct>();
            for (var i = 0; i < shoppingBasket.Products.Count; i++)
            {
                IProduct product = shoppingBasket.Products[i];
                foreach (Tax taxRule in _taxRules)
                {
                    if (taxRule.IsApplicableFor(product))
                    {
                        ProductDecorator productDecorator = taxRule.GetTaxableProductDecorator(product);
                        product = productDecorator;
                    }
                }
                decimal grossAmount = product.CalculateGrossAmount();
                taxedProducts.Add(new TaxedProduct(product, grossAmount));
            }
            return taxedProducts;
        }