public void IndexShouldThrowHttpExceptionWithCode403AndSpecifiedMessageIfStateStringWillBeNullOrEmpty()
        {
            _productRepository.GetProducts().Returns(_preparedProducts);
            _productRepository.GetProductByName(Arg.Any <string>()).Returns(_expectedProduct);
            _stateRepository.GetStateByName(Arg.Any <string>()).Returns(_expectedState);
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                             ExampleCorrectCount);

            ActionResult Call() => controller.Index(ProductName, Empty, ExampleCorrectPreferredPriceInput,
                                                    ExampleCorrectCount);

            ActionResult CallWithNull() => controller.Index(ProductName, null, ExampleCorrectPreferredPriceInput,
                                                            ExampleCorrectCount);

            var exception  = Xunit.Assert.Throws <HttpException>(Call);
            var exception2 = Xunit.Assert.Throws <HttpException>(CallWithNull);

            var code    = exception.GetHttpCode();
            var message = exception.Message;

            Assert.That(code, Is(EqualTo(Http403)));
            Assert.That(message, Is(EqualTo(ExpectedMessageFor403Code)));
            Assert.That(code, Is(EqualTo(exception2.GetHttpCode())));
            Assert.That(message, Is(EqualTo(exception2.Message)));
        }
        public void IndexPageShouldCallGetProductsOfProductsRepositoryOnlyOneTime()
        {
            _productRepository.GetProducts().Returns(_preparedProducts);
            _productRepository.GetProductByName(Arg.Any <string>()).Returns(_expectedProduct);
            _stateRepository.GetStateByName(Arg.Any <string>()).Returns(_expectedState);
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                             ExampleCorrectCount);
            _productRepository.Received(1).GetProducts();
        }
        public void IndexShouldBeNotNullWhenProvidedArgumentsAreNotNullOrEmptyOrMalformed()
        {
            _productRepository.GetProducts().Returns(_preparedProducts);
            _productRepository.GetProductByName(Arg.Any <string>()).Returns(_expectedProduct);
            _stateRepository.GetStateByName(Arg.Any <string>()).Returns(_expectedState);
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            var result = controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                                          ExampleCorrectCount);

            Assert.That(result, Is(NotNull()));
        }
        IndexShouldThrowHttpExceptionWithCode500AndSpecifiedMessageForAccessToDbIssuesIfAnyRepositoryThrewAnException()
        {
            _productRepository.GetProducts().Throws(new Exception());
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            ActionResult Call() => controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                                                    ExampleCorrectCount);

            var exception = Xunit.Assert.Throws <HttpException>(Call);

            var code    = exception.GetHttpCode();
            var message = exception.Message;

            Assert.That(code, Is(EqualTo(Http500)));
            Assert.That(message, Is(EqualTo(ExpectedMessageOf500CodeForAnyException)));
        }
        public void IndexShouldThrowHttpExceptionWithCode403AndSpecifiedMessageIfCountWillBeNegative()
        {
            _productRepository.GetProducts().Returns(_preparedProducts);
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            ActionResult Call() => controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                                                    ExampleIncorrectCount);

            var exception = Xunit.Assert.Throws <HttpException>(Call);

            var code    = exception.GetHttpCode();
            var message = exception.Message;

            Assert.That(code, Is(EqualTo(Http403)));
            Assert.That(message, Is(EqualTo(ExpectedMessageFor403Code)));
        }
        public void IfIndexWillBeCorrectlyInvokedThenMainViewModelOfActionResultShouldMatchingToExpectedOne()
        {
            _stateRepository.GetStates().Returns(_preparedStates);
            _productRepository.GetProducts().Returns(_preparedProducts);
            _categoryRepository.GetCategories().Returns(_preparedCategories);
            _productRepository.GetProductByName(Arg.Any <string>()).Returns(_expectedProduct);
            _stateRepository.GetStateByName(Arg.Any <string>()).Returns(_expectedState);
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            var result = controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                                          ExampleCorrectCount) as ViewResult;

            Assert.That(result, Is(NotNull()));

            var viewModel = result?.Model as MainViewModel;

            Assert.That(viewModel, Is(NotNull()));

            var productsList   = viewModel?.ProductSelectList.Items.Cast <ProductModel>().ToList();
            var statesList     = viewModel?.StateSelectList.Items.Cast <StateOfAmericaModel>().ToList();
            var categoriesList = viewModel?.CategorySelectList.Items.Cast <CategoryModel>().ToList();

            Assert.That(productsList, Is <ICollection>(Not(OfLength(0))));
            Assert.That(statesList, Is <ICollection>(Not(OfLength(0))));
            Assert.That(categoriesList, Is <ICollection>(Not(OfLength(0))));

            Assert.That(productsList, Has(Item(EqualTo(_expectedProduct))));
            Assert.That(categoriesList, Has(Item(EqualTo(_expectedCategory))));
            Assert.That(statesList, Has(Item(EqualTo(_expectedState))));

            var state = statesList?.FirstOrDefault();

            Assert.That(state?.TaxRates, Has(Item((EqualTo(_expectedTax)))));
            var taxes = viewModel?.Tax;

            Assert.That(taxes, Has(Item(EqualTo(_expectedState.BaseSalesTax))));
            var chosenProduct = viewModel?.ChosenProduct;

            Assert.That(chosenProduct, Is(EqualTo(_expectedProduct)));
            Assert.That(viewModel?.StateNameList, Has(Item(EqualTo(StateName))));
            Assert.That(viewModel?.PreferredPrice ?? 0, Is(EqualTo(PreferredPrice)));
            Assert.That(viewModel?.FinalPrice, Has(Item(EqualTo(PreferredPrice * ExampleCorrectCount))));

            const double diff = (PreferredPrice - PurchasePrice) * ExampleCorrectCount;

            Assert.That(viewModel?.Margin, Has(Item(EqualTo(diff))));
        }
        IndexShouldThrowHttpExceptionWithCode404AndSpecifiedMessageIfStateDoesNotExistInDatabase()
        {
            _productRepository.GetProducts().Returns(_preparedProducts);
            _productRepository.GetProductByName(Arg.Any <string>()).Returns(_expectedProduct);
            _stateRepository.GetStateByName(Arg.Any <string>()).Throws <ItemNotFoundException>();
            var controller = new StateSelectionController(_stateRepository, _categoryRepository, _productRepository);

            ActionResult Call() => controller.Index(ProductName, StateName, ExampleCorrectPreferredPriceInput,
                                                    ExampleCorrectCount);

            var exception = Xunit.Assert.Throws <HttpException>(Call);

            var code    = exception.GetHttpCode();
            var message = exception.Message;

            Assert.That(code, Is(EqualTo(Http404)));
            Assert.That(message, Is(EqualTo(ExpectedMessageOf404Code)));
        }