public async Task ExecuteGoNextCommand_ProcessesFormsAndNavigates_IfViewModelsAreValid()
        {
            bool shippingInfoProcessed = false;
            bool billingInfoProcessed = false;
            bool paymentInfoProcessed = false;
            bool navigated = false;
            var shippingAddressPageViewModel = new MockShippingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormDelegate = () => shippingInfoProcessed = true
                };
            var billingAddressPageViewModel = new MockBillingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormDelegate = () => billingInfoProcessed = true
                };
            var paymentMethodPageViewModel = new MockPaymentMethodPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormDelegate = () => paymentInfoProcessed = true
                };
            var accountService = new MockAccountService()
                {
                    GetSignedInUserAsyncDelegate = () => Task.FromResult(new UserInfo())
                };
            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, null);
            await target.GoNextCommand.Execute();

            Assert.IsTrue(shippingInfoProcessed);
            Assert.IsTrue(billingInfoProcessed);
            Assert.IsTrue(paymentInfoProcessed);
            Assert.IsTrue(navigated);
        }
        public void EditCheckoutData_Updates_Order()
        {
            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 flyoutService = new MockFlyoutService();
            flyoutService.ShowFlyoutDelegate = (flyoutName, param, success) =>
            { 
                // Update CheckoutData information and call success
                            ((PaymentMethod)param).CardNumber = "5678";
                success.Invoke();
            };
            var orderRepository = new MockOrderRepository() { GetCurrentOrderAsyncDelegate = () => order };
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult(order.ShoppingCart);

            var target = new CheckoutSummaryPageViewModel(new MockNavigationService(), new MockOrderService(), orderRepository, shippingMethodService,
                                                          null, shoppingCartRepository,
                                                          new MockAccountService(), flyoutService, new MockResourceLoader(), null);

            target.OnNavigatedTo(null, NavigationMode.New, null);
            target.SelectedCheckoutData = target.CheckoutDataViewModels[2];
            target.EditCheckoutDataCommand.Execute().Wait();

            // Check if order information has changed
            Assert.IsTrue(order.PaymentMethod.CardNumber == "5678");
            Assert.IsTrue(((PaymentMethod)target.CheckoutDataViewModels[2].Context).CardNumber == "5678");
        }
        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() {GetCurrentOrderAsyncDelegate = () => order};
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult(order.ShoppingCart);

            var target = new CheckoutSummaryPageViewModel(new MockNavigationService(), new MockOrderService(), orderRepository, shippingMethodService,
                                                          null, shoppingCartRepository,
                                                          new MockAccountService(), new MockFlyoutService(), new MockResourceLoader(), null);

            target.OnNavigatedTo(null, NavigationMode.New, null);
            Assert.IsFalse(target.IsBottomAppBarOpened);

            target.SelectedCheckoutData = target.CheckoutDataViewModels.First();
            Assert.IsTrue(target.IsBottomAppBarOpened);
        }
        public void SelectShippingMethod_Recalculates_Order()
        {
            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(),
                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() { GetCurrentOrderAsyncDelegate = () => order };
            var shoppingCartRepository = new MockShoppingCartRepository();
            shoppingCartRepository.GetShoppingCartAsyncDelegate = () => Task.FromResult(order.ShoppingCart);

            var target = new CheckoutSummaryPageViewModel(new MockNavigationService(), new MockOrderService(), orderRepository, shippingMethodService,
                                                          null, shoppingCartRepository,
                                                          new MockAccountService(), new MockFlyoutService(), new MockResourceLoader(), null);

            target.OnNavigatedTo(null, NavigationMode.New, null);

            Assert.AreEqual("$0.00", target.ShippingCost);
            Assert.AreEqual("$100.00", target.OrderSubtotal);
            Assert.AreEqual("$100.00", target.GrandTotal);

            target.SelectedShippingMethod = new ShippingMethod() { Cost = 10 };

            Assert.AreEqual("$10.00", target.ShippingCost);
            Assert.AreEqual("$100.00", target.OrderSubtotal);
            Assert.AreEqual("$110.00", target.GrandTotal);

        }
        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,
                    ProcessFormDelegate = () => Task.Delay(0),
                    Address = mockAddress
                };
            var billingAddressPageViewModel = new MockBillingAddressPageViewModel()
                {
                    ValidateFormDelegate = () => true
                };
            billingAddressPageViewModel.ProcessFormDelegate = () =>
                {
                    // The Address have to be updated before the form is processed
                    Assert.IsTrue(compareAddressesFunc(shippingAddressPageViewModel.Address, billingAddressPageViewModel.Address));
                };
            var paymentMethodPageViewModel = new MockPaymentMethodPageViewModel()
                {
                    ValidateFormDelegate = () => true,
                    ProcessFormDelegate = () => Task.Delay(0),
                };
            var accountService = new MockAccountService()
                {
                    GetSignedInUserAsyncDelegate = () => Task.FromResult(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 shippingMethodService = new MockShippingMethodService()
                {
                    GetBasicShippingMethodAsyncDelegate = () => Task.FromResult(new ShippingMethod())
                };
            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, null);
            target.UseSameAddressAsShipping = true;

            await target.GoNextCommand.Execute();
        }