public void ShoppingCartUpdated_WithNullCart_SetsItemCountZero()
        {
            var shoppingCartRepository = new MockShoppingCartRepository();
            var shoppingCart = new ShoppingCart(new List<ShoppingCartItem> {new ShoppingCartItem {Quantity = 99}});
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult(shoppingCart);
            var eventAggregator = new MockEventAggregator();
            var shoppingCartUpdatedEvent = new ShoppingCartUpdatedEvent();
            eventAggregator.GetEventDelegate = type =>
            {
                if (type == typeof(ShoppingCartUpdatedEvent)) return shoppingCartUpdatedEvent;
                if (type == typeof(ShoppingCartItemUpdatedEvent)) return new ShoppingCartItemUpdatedEvent();
                return null;
            };
            var accountService = new MockAccountService();
            accountService.VerifyUserAuthenticationAsyncDelegate = () => Task.FromResult((UserInfo)null);
            var target = new ShoppingCartTabUserControlViewModel(shoppingCartRepository, eventAggregator, null, null, accountService);

            shoppingCartUpdatedEvent.Publish(null);

            Assert.AreEqual(99, target.ItemCount);

            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult<ShoppingCart>(null);
            shoppingCartUpdatedEvent.Publish(null);

            Assert.AreEqual(0, target.ItemCount);
        }
        public void OnNavigatedTo_Fill_Properties_With_Shopping_Cart_Items()
        {
            var navigationService = new MockNavigationService();
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () =>
            {
                ShoppingCart shoppingCart = null;
                var shoppingCartItems = new ObservableCollection<ShoppingCartItem>
                                            {
                                                new ShoppingCartItem() {Product = new Product { ListPrice = 100, DiscountPercentage = 50, ProductNumber = "p1", ImageUri = new Uri("http://image")}, Currency = "USD", Quantity = 1}, 
                                                new ShoppingCartItem() {Product = new Product { ListPrice = 100, DiscountPercentage = 50, ProductNumber = "p2", ImageUri = new Uri("http://image")}, Currency = "USD", Quantity = 1}
                                            };
                shoppingCart = new ShoppingCart(shoppingCartItems) { Currency = "USD"};

                return Task.FromResult(shoppingCart);
            };

            bool signInUserControlOnNavigatedToCalled = false;
            var signInUserControlViewModel = new MockSignInUserControlViewModel()
                {
                    OnNavigatedToDelegate = (a, b, c) => signInUserControlOnNavigatedToCalled = true
                };

            var eventAggregator = new MockEventAggregator();
            eventAggregator.GetEventDelegate = type => new MockShoppingCartUpdatedEvent();
            var target = new ShoppingCartPageViewModel(shoppingCartRepository, navigationService, new MockAccountService(), signInUserControlViewModel, null, null, null, null, eventAggregator);
            target.OnNavigatedTo(new NavigatedToEventArgs { Parameter = null, NavigationMode = NavigationMode.New }, null);

            Assert.IsTrue(signInUserControlOnNavigatedToCalled);
            Assert.AreEqual("$200.00", target.FullPrice);
            Assert.AreEqual("$100.00", target.TotalDiscount);
            Assert.AreEqual(2, target.ShoppingCartItemViewModels.Count);
        }
        public void VMListensToShoppingCartUpdatedEvent_ThenCalculatesTotalNumberOfItemsInCart()
        {
            var shoppingCart = new ShoppingCart(new List<ShoppingCartItem>());
            var shoppingCartRepository = new MockShoppingCartRepository();

            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult(shoppingCart);
            var shoppingCartUpdatedEvent = new ShoppingCartUpdatedEvent();
            var eventAggregator = new MockEventAggregator();
            eventAggregator.GetEventDelegate = type =>
            {
                if (type == typeof(ShoppingCartUpdatedEvent)) return shoppingCartUpdatedEvent;
                if (type == typeof(ShoppingCartItemUpdatedEvent)) return new ShoppingCartItemUpdatedEvent();
                return null;
            };
            var accountService = new MockAccountService();
            accountService.VerifyUserAuthenticationAsyncDelegate = () => Task.FromResult((UserInfo)null);
            var target = new ShoppingCartTabUserControlViewModel(shoppingCartRepository, eventAggregator, null, null, accountService);

            shoppingCart = new ShoppingCart(new List<ShoppingCartItem>()
                                               {
                                                   new ShoppingCartItem {Quantity = 1},
                                                   new ShoppingCartItem {Quantity = 2}
                                               });

            Assert.AreEqual(0, target.ItemCount);

            shoppingCartUpdatedEvent.Publish(null);

            Assert.AreEqual(3, target.ItemCount);

        }
        public async Task SubmitValidOrder_NavigatesToOrderConfirmation()
        {
            bool navigateCalled = false;
            bool clearCartCalled = false;
            var navigationService = new MockNavigationService();
            navigationService.NavigateDelegate = (s, o) =>
                                                     {
                                                         Assert.AreEqual("OrderConfirmation", s);
                                                         navigateCalled = true;
                                                         return true;
                                                     };
            
            var accountService = new MockAccountService()
                {
                    VerifySavedCredentialsAsyncDelegate = () => Task.FromResult<UserInfo>(new UserInfo())
                };
            var orderService = new MockOrderService()
                {
                    // the order is valid, it can be processed
                    ProcessOrderAsyncDelegate = (o) => Task.FromResult(true)
                };
            var resourcesService = new MockResourceLoader()
                {
                    GetStringDelegate = (key) => key
                };
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.ClearCartAsyncDelegate = () =>
                                                                {
                                                                    clearCartCalled = true;
                                                                    return Task.Delay(0);
                                                                };
            var target = new CheckoutSummaryPageViewModel(navigationService, orderService, null, null, null, shoppingCartRepository, accountService, resourcesService, null, null);
            await target.SubmitCommand.Execute();

            Assert.IsTrue(navigateCalled);
            Assert.IsTrue(clearCartCalled);
        }
        public void FailedCallToShoppingCartRepository_ShowsAlert()
        {
            var alertCalled = false;
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () =>
                                                                      {
                                                                          throw new Exception();
                                                                      };
            var alertMessageService = new MockAlertMessageService();
            alertMessageService.ShowAsyncDelegate = (s, s1) =>
                                                        {
                                                            alertCalled = true;
                                                            Assert.AreEqual("ErrorServiceUnreachable", s1);
                                                            return Task.FromResult(string.Empty);
                                                        };
            var accountService = new MockAccountService();
            accountService.VerifyUserAuthenticationAsyncDelegate = () => Task.FromResult((UserInfo)null);
            var target = new ShoppingCartTabUserControlViewModel(shoppingCartRepository, null, alertMessageService, new MockResourceLoader(), accountService);

            Assert.IsTrue(alertCalled);
        }
        public void ShoppingCartUpdated_WhenShoppingCartChanged()
        {
            var navigationService = new MockNavigationService();
            var accountService = new MockAccountService();
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () =>
            {
                ShoppingCart shoppingCart = new ShoppingCart(new ObservableCollection<ShoppingCartItem>()) { Currency = "USD"};
                return Task.FromResult(shoppingCart);
            };
            bool signInUserControlOnNavigatedToCalled = false;
            var signInUserControlViewModel = new MockSignInUserControlViewModel()
            {
                OnNavigatedToDelegate = (a, b, c) => signInUserControlOnNavigatedToCalled = true
            };
            var eventAggregator = new MockEventAggregator();
            var shoppingCartUpdatedEvent = new ShoppingCartUpdatedEvent();
            eventAggregator.GetEventDelegate = type => shoppingCartUpdatedEvent;
            var target = new ShoppingCartPageViewModel(shoppingCartRepository, navigationService, accountService, signInUserControlViewModel, null, null, null, null, eventAggregator);
            target.OnNavigatedTo(new NavigatedToEventArgs { Parameter = null, NavigationMode = NavigationMode.New }, null);  

            Assert.AreEqual("$0.00", target.FullPrice);

            shoppingCartRepository.GetShoppingCartAsyncDelegate = () =>
            {
                var shoppingCartItems = new ObservableCollection<ShoppingCartItem>
                                            {
                                                new ShoppingCartItem() { Product = new Product { ListPrice = 100, ProductNumber = "p1", ImageUri = new Uri("http://image")}, Currency = "USD", Quantity = 2}, 
                                            };
                ShoppingCart shoppingCart = new ShoppingCart(new ObservableCollection<ShoppingCartItem>(shoppingCartItems)) { Currency = "USD" };
                return Task.FromResult(shoppingCart);
            };

            shoppingCartUpdatedEvent.Publish(null);

            Assert.IsTrue(signInUserControlOnNavigatedToCalled);
            Assert.AreEqual("$200.00", target.FullPrice);
        }
        public void DecrementCountCommand_NotExecutable()
        {
            var navigationService = new MockNavigationService();
            var shoppingCartRepository = new MockShoppingCartRepository();
            var eventAggregator = new MockEventAggregator();
            eventAggregator.GetEventDelegate = type => new MockShoppingCartUpdatedEvent();
            var target = new ShoppingCartPageViewModel(shoppingCartRepository, navigationService, null, null, null, null, null, null, eventAggregator);

            target.SelectedItem = new ShoppingCartItemViewModel(new ShoppingCartItem(){ Quantity = 2, Currency = "USD", Product = new Product() }, null);

            Assert.IsTrue(target.DecrementCountCommand.CanExecute());

            target.SelectedItem = new ShoppingCartItemViewModel(new ShoppingCartItem() { Quantity = 1, Currency = "USD", Product = new Product() }, null);

            Assert.IsFalse(target.DecrementCountCommand.CanExecute());
        }
        public void CheckoutCommand_NotExecutable_IfNoItemsInCart()
        {
            var navigationService = new MockNavigationService();
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult<ShoppingCart>(null);
            var eventAggregator = new MockEventAggregator();
            eventAggregator.GetEventDelegate = type => new MockShoppingCartUpdatedEvent();
            var target = new ShoppingCartPageViewModel(shoppingCartRepository, navigationService, null, null, null, null, null, null, eventAggregator);
            target.UpdateShoppingCartAsync(null);
            
            Assert.IsFalse(target.CheckoutCommand.CanExecute());

            shoppingCartRepository.GetShoppingCartAsyncDelegate = 
                () => Task.FromResult(new ShoppingCart(new Collection<ShoppingCartItem>()){Currency = "USD", FullPrice = 0, TaxRate = 0, TotalDiscount = 0, TotalPrice = 0});
            target.UpdateShoppingCartAsync(null);
            
            Assert.IsFalse(target.CheckoutCommand.CanExecute());

            shoppingCartRepository.GetShoppingCartAsyncDelegate =
                () => Task.FromResult(new ShoppingCart(new Collection<ShoppingCartItem> { new ShoppingCartItem{Product = new Product(), Currency = "USD", Quantity = 0} }) 
                { Currency = "USD", FullPrice = 0, TaxRate = 0, TotalDiscount = 0, TotalPrice = 0 });
            target.UpdateShoppingCartAsync(null);

            Assert.IsTrue(target.CheckoutCommand.CanExecute());

        }
        public void UpdateShoppingCart_ClearsFields_WhenShoppingCartEmpty()
        {
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult<ShoppingCart>(null);
            var eventAggregator = new MockEventAggregator();
            bool signInUserControlOnNavigatedToCalled = false;
            var signInUserControlViewModel = new MockSignInUserControlViewModel() { OnNavigatedToDelegate = (a, b, c) => Task.Delay(0) };
            eventAggregator.GetEventDelegate = type => new MockShoppingCartUpdatedEvent();
            var target = new ShoppingCartPageViewModel(shoppingCartRepository, new MockNavigationService(),
                                                       new MockAccountService(), signInUserControlViewModel, null, null, null, null, eventAggregator);

            target.OnNavigatedTo(new NavigatedToEventArgs { Parameter = null, NavigationMode = NavigationMode.New }, null);

            Assert.AreEqual(string.Empty, target.TotalPrice);
            Assert.AreEqual(string.Empty, target.TotalDiscount);
            Assert.AreEqual(string.Empty, target.FullPrice);
        }
        public async Task ExecuteGoNextCommand_ProcessesFormsAndNavigates_IfViewModelsAreValid()
        {
            bool shippingInfoProcessed = false;
            bool billingInfoProcessed = false;
            bool paymentInfoProcessed = false;
            bool navigated = false;
            var shippingAddressPageViewModel = new MockShippingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = () =>
                                                   {
                                                       shippingInfoProcessed = true;
                                                       return Task.Delay(0);
                                                   }
                };
            var billingAddressPageViewModel = new MockBillingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = () =>
                                                   {
                                                       billingInfoProcessed = true;
                                                       return Task.Delay(0);
                                                   }
                };
            var paymentMethodPageViewModel = new MockPaymentMethodPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = async () => 
                        {
                            paymentInfoProcessed = true;
                            await Task.Delay(0);
                        }
                };
            var accountService = new MockAccountService()
                {
                    VerifyUserAuthenticationAsyncDelegate = () => Task.FromResult(new UserInfo()),
                    SignedInUser = new UserInfo() { UserName = "******" }
                };
            var orderRepository = new MockOrderRepository()
                {
                    CreateBasicOrderAsyncDelegate = (a, b, c, d, e) => Task.FromResult(new Order() { Id = 1 })
                };
            var shoppingCartRepository = new MockShoppingCartRepository()
                {
                    GetShoppingCartAsyncDelegate = () => Task.FromResult(new ShoppingCart(null))
                };
            var navigationService = new MockNavigationService()
                {
                    NavigateDelegate = (a, b) => navigated = true
                };

            var target = new CheckoutHubPageViewModel(navigationService, accountService, orderRepository, shoppingCartRepository,
                                            shippingAddressPageViewModel, billingAddressPageViewModel, paymentMethodPageViewModel, null, null);
            await target.GoNextCommand.Execute();

            Assert.IsTrue(shippingInfoProcessed);
            Assert.IsTrue(billingInfoProcessed);
            Assert.IsTrue(paymentInfoProcessed);
            Assert.IsTrue(navigated);
        }
        public void ProcessFormAsync_WithServerValidationError_ShowsMessage()
        {
            var shippingAddressPageViewModel = new MockShippingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = () => Task.Delay(0),
                    Address = new Address()
                };
            var billingAddressPageViewModel = new MockBillingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = () => Task.Delay(0),
                    Address = new Address()
                };
            var paymentMethodPageViewModel = new MockPaymentMethodPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = async () => await Task.Delay(0),
                    PaymentMethod = new PaymentMethod()
                };
            var accountService = new MockAccountService()
                {
                    VerifyUserAuthenticationAsyncDelegate = () => Task.FromResult(new UserInfo()),
                    SignedInUser = new UserInfo()
                };
            var shoppingCartRepository = new MockShoppingCartRepository()
                {
                    GetShoppingCartAsyncDelegate =
                        () => Task.FromResult(new ShoppingCart(null))
                };
            var orderRepository = new MockOrderRepository()
                {
                    CreateBasicOrderAsyncDelegate = (s, cart, arg3, arg4, arg5) =>
                         {
                             var result = new ModelValidationResult();
                             result.ModelState.Add("order.ShippingAddress.ZipCode", new List<string>{"Validation Message"});
                             throw new ModelValidationException(result);
                         }
                };
            var target = new CheckoutHubPageViewModel(new MockNavigationService(), accountService, orderRepository, shoppingCartRepository, shippingAddressPageViewModel,
                                                      billingAddressPageViewModel, paymentMethodPageViewModel, null, null);

            target.GoNextCommand.Execute();

            Assert.IsTrue(target.IsShippingAddressInvalid);
        }
        public async Task SettingUseShippingAddressToTrue_CopiesValuesFromShippingAddressToBilling()
        {
            var mockAddress = new Address()
                {
                    FirstName = "TestFirstName",
                    MiddleInitial = "TestMiddleInitial",
                    LastName = "TestLastName",
                    StreetAddress = "TestStreetAddress",
                    OptionalAddress = "TestOptionalAddress",
                    City = "TestCity",
                    State = "TestState",
                    ZipCode = "123456",
                    Phone = "123456"
                };
            var compareAddressesFunc = new Func<Address, Address, bool>((Address a1, Address a2) =>
                {
                    return a1.FirstName == a2.FirstName && a1.MiddleInitial == a2.MiddleInitial && a1.LastName == a2.LastName
                           && a1.StreetAddress == a2.StreetAddress && a1.OptionalAddress == a2.OptionalAddress && a1.City == a2.City
                           && a1.State == a2.State && a1.ZipCode == a2.ZipCode && a1.Phone == a2.Phone;
                });

            var shippingAddressPageViewModel = new MockShippingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = () => Task.Delay(0),
                    Address = mockAddress
                };
            var billingAddressPageViewModel = new MockBillingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true
                };
            billingAddressPageViewModel.ProcessFormAsyncDelegate = () =>
                {
                    // The Address have to be updated before the form is processed
                    Assert.IsTrue(compareAddressesFunc(shippingAddressPageViewModel.Address, billingAddressPageViewModel.Address));
                    return Task.Delay(0);
                };
            var paymentMethodPageViewModel = new MockPaymentMethodPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormAsyncDelegate = async () => await Task.Delay(0),
                };
            var accountService = new MockAccountService()
                {
                    VerifyUserAuthenticationAsyncDelegate = () => Task.FromResult(new UserInfo()),
                    SignedInUser = new UserInfo()
                };
            var orderRepository = new MockOrderRepository()
                {
                    CreateBasicOrderAsyncDelegate = (userId, shoppingCart, shippingAddress, billingAddress, paymentMethod) =>
                        {
                            // The Address information stored in the order must be the same
                            Assert.IsTrue(compareAddressesFunc(shippingAddress, billingAddress));
                            return Task.FromResult<Order>(new Order());
                        }
                };
            var shoppingCartRepository = new MockShoppingCartRepository()
                {
                    GetShoppingCartAsyncDelegate = () => Task.FromResult(new ShoppingCart(null))
                };
            var navigationService = new MockNavigationService()
                {
                    NavigateDelegate = (a, b) => true
                };

            var target = new CheckoutHubPageViewModel(navigationService, accountService, orderRepository, shoppingCartRepository,
                                            shippingAddressPageViewModel, billingAddressPageViewModel, paymentMethodPageViewModel, null, null);
            target.UseSameAddressAsShipping = true;

            await target.GoNextCommand.Execute();
        }
        public void NavigatingToWhenNoShippingMethodSelected_RecalculatesOrder()
        {
            var shippingMethods = new List<ShippingMethod> { new ShippingMethod { Id = 1, Cost = 0 } };
            var shoppingCartItems = new List<ShoppingCartItem> { new ShoppingCartItem { Quantity = 1, Currency = "USD", Product = new Product() } };
            var order = new Order
                {
                ShoppingCart = new ShoppingCart(shoppingCartItems) { Currency = "USD", TotalPrice = 100 },
                ShippingAddress = new Address { Id = "1"},
                BillingAddress = new Address { Id = "1" },
                PaymentMethod = new PaymentMethod() { CardNumber = "1234" },
                ShippingMethod = null
            };
            var shippingMethodService = new MockShippingMethodService
            {
                GetShippingMethodsAsyncDelegate = () => Task.FromResult<IEnumerable<ShippingMethod>>(shippingMethods)
            };
            var orderRepository = new MockOrderRepository { CurrentOrder = order };
            var shoppingCartRepository = new MockShoppingCartRepository
                {
                    GetShoppingCartAsyncDelegate = () => Task.FromResult(order.ShoppingCart)
                };
            var checkoutDataRepository = new MockCheckoutDataRepository();
            checkoutDataRepository.GetShippingAddressAsyncDelegate = s => Task.FromResult(new Address());
            checkoutDataRepository.GetBillingAddressAsyncDelegate = s => Task.FromResult(new Address());
            checkoutDataRepository.GetPaymentMethodDelegate = s => Task.FromResult(new PaymentMethod { CardNumber = "1234" });
            var target = new CheckoutSummaryPageViewModel(new MockNavigationService(), new MockOrderService(), orderRepository, shippingMethodService,
                                                          checkoutDataRepository, shoppingCartRepository,
                                                          new MockAccountService(), new MockResourceLoader(), null, null);

            target.OnNavigatedTo(new NavigatedToEventArgs { Parameter = null, NavigationMode = NavigationMode.New }, null);

            Assert.AreEqual("$0.00", target.ShippingCost);
            Assert.AreEqual("$100.00", target.OrderSubtotal);
            Assert.AreEqual("$100.00", target.GrandTotal);
        }
        public void SelectCheckoutData_Opens_AppBar()
        {
            var shippingMethods = new List<ShippingMethod>() { new ShippingMethod() { Id = 1, Cost = 0 } };
            var shoppingCartItems = new List<ShoppingCartItem>() { new ShoppingCartItem() { Quantity = 1, Currency = "USD", Product = new Product() } };
            var order = new Order()
            {
                ShoppingCart = new ShoppingCart(shoppingCartItems) { Currency = "USD", FullPrice = 100 },
                ShippingAddress = new Address(),
                BillingAddress = new Address(),
                PaymentMethod = new PaymentMethod() { CardNumber = "1234" },
                ShippingMethod = shippingMethods.First()
            };
            var shippingMethodService = new MockShippingMethodService()
            {
                GetShippingMethodsAsyncDelegate = () => Task.FromResult<IEnumerable<ShippingMethod>>(shippingMethods)
            };
            var orderRepository = new MockOrderRepository() { CurrentOrder = order};
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult(order.ShoppingCart);
            var checkoutDataRepository = new MockCheckoutDataRepository();
            checkoutDataRepository.GetShippingAddressAsyncDelegate = s => Task.FromResult(new Address());
            checkoutDataRepository.GetBillingAddressAsyncDelegate = s => Task.FromResult(new Address());
            checkoutDataRepository.GetPaymentMethodDelegate = s => Task.FromResult(new PaymentMethod { CardNumber = "1234" });
            var target = new CheckoutSummaryPageViewModel(new MockNavigationService(), new MockOrderService(), orderRepository, shippingMethodService,
                                                          checkoutDataRepository, shoppingCartRepository,
                                                          new MockAccountService(), new MockResourceLoader(), null, null);

            target.OnNavigatedTo(new NavigatedToEventArgs { Parameter = null, NavigationMode = NavigationMode.New }, null);
            Assert.IsFalse(target.IsBottomAppBarOpened);

            target.SelectedCheckoutData = target.CheckoutDataViewModels.First();
            Assert.IsTrue(target.IsBottomAppBarOpened);
        }