public async void Index_EmptyCart_ReturnsMatchingModel() { Cart cart = new Cart { MemberId = UserId, Items = new List<CartItem>() }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, new ShippingCostService()) { ControllerContext = contextStub.Object }; var result = await controller.Index() as ViewResult; Assert.That(result != null); Assert.That(result.Model, Is.InstanceOf<CartViewModel>()); var model = (CartViewModel)result.Model; Assert.That(model.Cart.Items.Count, Is.EqualTo(0)); }
/// <summary> /// Decreases inventory levels and adds all the cart items to <see cref="newOrder"/> /// </summary> /// <param name="cart"> /// The <see cref="Cart"/> to retrieve items from /// </param> /// <param name="newOrder"> /// The <see cref="WebOrder"/> to add items to /// </param> /// <returns> /// A <see cref="Task"/> to await /// </returns> private async Task DecreaseInventoryAndAddToOrder(Cart cart, WebOrder newOrder) { foreach (var productGrouping in cart.Items.GroupBy(i => i.ProductId)) { ProductLocationInventory inventory = await db.ProductLocationInventories. Where( pli => pli.ProductId == productGrouping.Key && pli.Location.SiteName == Location.ONLINE_WAREHOUSE_NAME). FirstOrDefaultAsync(); foreach (var lineItem in productGrouping) { if (lineItem.IsNew) { AvailabilityStatus itemStatus = lineItem.Product.ProductAvailabilityStatus; if (itemStatus == AvailabilityStatus.Available || itemStatus == AvailabilityStatus.PreOrder) { inventory.NewOnHand -= lineItem.Quantity; } else if ((itemStatus == AvailabilityStatus.DiscontinuedByManufacturer || itemStatus == AvailabilityStatus.NotForSale) && lineItem.Quantity <= inventory.NewOnHand) { inventory.NewOnHand -= lineItem.Quantity; } else { throw new NotEnoughInventoryException( $"Not enough copies of {lineItem.Product.Name}, which has been discontinued, to " + "guarantee we will be able to fulfill your order.", lineItem.Product); } } else { if (inventory.UsedOnHand < lineItem.Quantity) { throw new NotEnoughInventoryException( $"Not enough used copies of {lineItem.Product.Name} to guarantee we " + "will be able to fulfill your order.", lineItem.Product); } inventory.UsedOnHand -= lineItem.Quantity; } newOrder.OrderItems.Add( new OrderItem { IsNew = lineItem.IsNew, ListPrice = lineItem.IsNew ? lineItem.Product.NewWebPrice : lineItem.Product.UsedWebPrice.Value, Product = lineItem.Product, ProductId = lineItem.ProductId, Quantity = lineItem.Quantity }); } } }
/// <summary> /// Check if the passed <see cref="Cart"/> has the same items as <see cref="items"/> /// </summary> /// <param name="items"> /// The <see cref="List{T}"/> of <see cref="CartItem"/> the <see cref="cart"/> should match /// </param> /// <param name="memberId"> /// The id for the current member. This is used to set /// the <see cref="CartItem.MemberId"/> of the cart items /// </param> /// <param name="cart"> /// The <see cref="Cart"/> with <see cref="Cart.Items"/> ordered by /// <see cref="SortCartItems"/> to compare against /// </param> /// <returns> /// True if the items are all equal, false otherwise. /// </returns> private bool EnsureCartMatchesConfirmedCart(List<CartItem> items, Guid memberId, Cart cart) { items = SortCartItems(items); items.ForEach(i => i.MemberId = memberId); return items.SequenceEqual(cart.Items, CartItem.CartItemComparer); }
/// <summary> /// Transforms the items in the <see cref="cart"/> to /// <see cref="ConfirmOrderCartItemViewModel"/>s /// </summary> /// <param name="cart"> /// The <see cref="Cart"/> whose items should be transformed /// </param> /// <returns> /// A <see cref="List{T}"/> of <see cref="ConfirmOrderCartItemViewModel"/> for /// the <see cref="cart"/> /// </returns> private List<ConfirmOrderCartItemViewModel> GetConfirmOrderCartItems(Cart cart) { List<ConfirmOrderCartItemViewModel> cartItems = cart.Items. Select( ci => new ConfirmOrderCartItemViewModel { ProductId = ci.ProductId, IsNew = ci.IsNew, ItemPrice = ci.IsNew ? ci.Product.NewWebPrice : ci.Product.UsedWebPrice.Value, Name = ci.Product.Name, PlatformName = ci.Product is PhysicalGameProduct ? ((PhysicalGameProduct)ci.Product).Platform.PlatformName : "", Quantity = ci.Quantity } ).ToList(); return cartItems; }
public void SetSessionCartQty_WhenCalled_SetsSessionCartQuantityToCartCount() { Cart cart = new Cart { MemberId = UserId, Items = new List<CartItem> { new CartItem(), new CartItem(), new CartItem() } }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); dbStub. Setup(db => db.Carts). Returns(cartDbSetStub.Object); Mock<ControllerContext> contextMock = new Mock<ControllerContext>(); contextMock. Setup(c => c.HttpContext.User.Identity). Returns<IIdentity>(null); contextMock. SetupGet(c => c.HttpContext.Session[CartController.CART_QTY_SESSION_KEY]). Returns(null); contextMock. SetupSet(c => c.HttpContext.Session[CartController.CART_QTY_SESSION_KEY] = It.IsAny<object>()). Verifiable(); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub. Setup(id => id.GetUserId(It.IsAny<IIdentity>())). Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, shippingCostService: null) { ControllerContext = contextMock.Object }; controller.SetSessionCartQty(); Assert.That( () => contextMock.VerifySet(c => c.HttpContext.Session[CartController.CART_QTY_SESSION_KEY] = cart.Items.Count, Times.Once), Throws.Nothing); }
public async void RemoveItem_CatchesOnSave() { Game game = new Game() { Id = GameId, Name = "game" }; GameProduct gameProduct = new PhysicalGameProduct() { Id = Id, BoxArtImageURL = "boxart", NewWebPrice = 79.99m, UsedWebPrice = 44.99m, Platform = new Platform { PlatformName = "PS4", }, Game = game }; CartItem cartItem = new CartItem() { ProductId = gameProduct.Id }; Cart cart = new Cart { MemberId = UserId, Items = new List<CartItem>() { cartItem } }; Member member = new Member() { UserId = UserId, Cart = cart }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); Mock<DbSet<Member>> memberDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Member> { member }.AsQueryable()); Mock<DbSet<GameProduct>> gameProductDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<GameProduct> { gameProduct }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); gameProductDbSetStub.Setup(db => db.FindAsync(gameProduct.Id)).ReturnsAsync(gameProduct); memberDbSetStub.Setup(db => db.Find(member.UserId)).Returns(member); gameProductDbSetStub.SetupForInclude(); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); dbStub.Setup(db => db.GameProducts).Returns(gameProductDbSetStub.Object); dbStub.Setup(db => db.Members).Returns(memberDbSetStub.Object); dbStub.Setup(db => db.SaveChangesAsync()).Throws<DbUpdateException>(); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<HttpSessionStateBase> sessionStub = new Mock<HttpSessionStateBase>(); contextStub.Setup(s => s.HttpContext.Session).Returns(sessionStub.Object); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, shippingCostService: null) { ControllerContext = contextStub.Object }; var result = await controller.RemoveItem(gameProduct.Id, cartItem.IsNew) as RedirectToRouteResult; Assert.That(result != null); Assert.That(result.RouteValues["action"], Is.EqualTo("Index")); }
public void RemoveItem_NullCart() { Cart cart = new Cart { MemberId = new Guid("45B0752E-998B-477A-AAAD-3ED535BA3559"), Items = new List<CartItem>(), }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, shippingCostService: null) { ControllerContext = contextStub.Object }; Assert.That(async () => await controller.RemoveItem(Id, true), Throws.InstanceOf<HttpException>().And.Matches<HttpException>(ex => ex.GetHttpCode() == 404)); }
public async void Index_ItemsInCart_ReturnsMatchingModel() { PhysicalGameProduct gameProduct = new PhysicalGameProduct() { Id = Id, BoxArtImageURL = "boxart", NewWebPrice = 12m, UsedWebPrice = 8m, Platform = new Platform { PlatformName = "XBAX", } }; Cart cart = new Cart { MemberId = UserId, Items = new List<CartItem> { new CartItem { Product = gameProduct, ProductId = gameProduct.Id, IsNew = true, MemberId = UserId, Quantity = 1 }, new CartItem { Product = gameProduct, ProductId = gameProduct.Id, IsNew = false, MemberId = UserId, Quantity = 2 } } }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, new ShippingCostService()) { ControllerContext = contextStub.Object }; var result = await controller.Index() as ViewResult; Assert.That(result != null); Assert.That(result.Model, Is.InstanceOf<CartViewModel>()); var model = (CartViewModel)result.Model; Assert.That(model.Cart.Items.Count, Is.EqualTo(2)); Assert.That(model.Cart.Items.FirstOrDefault(i => i.IsNew).ProductId, Is.EqualTo(Id)); Assert.That(model.Cart.Items.FirstOrDefault(i => !i.IsNew).ProductId, Is.EqualTo(Id)); Assert.That(model.Cart.Items.FirstOrDefault(i => i.IsNew).Quantity, Is.EqualTo(1)); Assert.That(model.Cart.Items.FirstOrDefault(i => !i.IsNew).Quantity, Is.EqualTo(2)); }
public void AddItem_NullCart() { Game game = new Game() { Id = GameId, Name = "game" }; GameProduct gameProduct = new PhysicalGameProduct() { Id = Id, BoxArtImageURL = "boxart", NewWebPrice = 79.99m, UsedWebPrice = 44.99m, Platform = new Platform { PlatformName = "PS4", }, Game = game }; Cart cart = new Cart { MemberId = new Guid("45B0752E-998B-477A-AAAD-3ED535BA3559"), Items = new List<CartItem>(), }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); Mock<DbSet<GameProduct>> gameProductDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<GameProduct> { gameProduct }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); gameProductDbSetStub.Setup(db => db.FindAsync(gameProduct.Id)).ReturnsAsync(gameProduct); gameProductDbSetStub.SetupForInclude(); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); dbStub.Setup(db => db.GameProducts).Returns(gameProductDbSetStub.Object); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, shippingCostService: null) { ControllerContext = contextStub.Object }; Assert.That(async () => await controller.AddItem(gameProduct.Id, true), Throws.InstanceOf<HttpException>().And.Matches<HttpException>(ex => ex.GetHttpCode() == 404)); }
public async void UpdateQuantity_ItemIsInCart_NotEnoughNewInventory_ReturnsUpdatedModel() { PhysicalGameProduct gameProduct = new PhysicalGameProduct() { Id = Id, BoxArtImageURL = "boxart", SKUNameSuffix = "GameProductName", Game = new Game { Name = "GameName" }, NewWebPrice = 12m, UsedWebPrice = 8m, Platform = new Platform { PlatformName = "XBAX", }, LocationInventories = new List<ProductLocationInventory> { new ProductLocationInventory { NewOnHand = 5, UsedOnHand = 2 } } }; Cart cart = new Cart { MemberId = UserId, Items = new List<CartItem> { new CartItem { Product = gameProduct, ProductId = gameProduct.Id, IsNew = true, MemberId = UserId, Quantity = 1 } } }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, new ShippingCostService()) { ControllerContext = contextStub.Object }; var result = await controller.UpdateQuantity(gameProduct.Id, true, 8) as ViewResult; Assert.That(result != null); Assert.That(result.Model, Is.InstanceOf<CartViewModel>()); var model = (CartViewModel)result.Model; Assert.That(model.Cart.Items.Count, Is.EqualTo(1)); Assert.That(model.Cart.Items.FirstOrDefault().Quantity, Is.EqualTo(8)); }
public void UpdateQuantity_ItemIsNotInCart_Throws404Exception() { Guid gameProductId = new Guid("976ACE77-D87C-4EBE-83A0-46F911F6490E"); PhysicalGameProduct gameProduct = new PhysicalGameProduct() { Id = Id, BoxArtImageURL = "boxart", NewWebPrice = 12m, UsedWebPrice = 8m, Platform = new Platform { PlatformName = "XBAX", } }; Cart cart = new Cart { MemberId = UserId, Items = new List<CartItem> { new CartItem { Product = gameProduct, ProductId = gameProduct.Id, IsNew = true, MemberId = UserId, Quantity = 1 } } }; Mock<IVeilDataAccess> dbStub = TestHelpers.GetVeilDataAccessFake(); Mock<DbSet<Cart>> cartDbSetStub = TestHelpers.GetFakeAsyncDbSet(new List<Cart> { cart }.AsQueryable()); cartDbSetStub.Setup(db => db.FindAsync(cart.MemberId)).ReturnsAsync(cart); dbStub.Setup(db => db.Carts).Returns(cartDbSetStub.Object); Mock<ControllerContext> contextStub = new Mock<ControllerContext>(); contextStub.Setup(c => c.HttpContext.User.Identity).Returns<IIdentity>(null); contextStub.Setup(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true); Mock<IGuidUserIdGetter> idGetterStub = new Mock<IGuidUserIdGetter>(); idGetterStub.Setup(id => id.GetUserId(It.IsAny<IIdentity>())).Returns(UserId); CartController controller = new CartController(dbStub.Object, idGetterStub.Object, shippingCostService: null) { ControllerContext = contextStub.Object }; Assert.That(async () => await controller.UpdateQuantity(gameProductId, true, 2), Throws.InstanceOf<HttpException>().And.Matches<HttpException>(ex => ex.GetHttpCode() == 404)); }
public void SetupBase() { memberId = new Guid("59EF92BE-D71F-49ED-992D-DF15773DAF98"); addressId = new Guid("53BE47E4-0C74-4D49-97BB-7246A7880B39"); creditCardId = new Guid("D9A69026-E3DA-4748-816B-293D9BE3E43F"); cartProduct1Id = new Guid("3882D242-A62A-4E99-BA11-D6EF340C2EE8"); cartProduct2Id = new Guid("7413D131-7337-42DC-A7E4-1155EB91E8C9"); memberAddress = new MemberAddress { Address = new Address { City = "Waterloo", PostalCode = "N2L 6R2", StreetAddress = "445 Wes Graham Way" }, CountryCode = "CA", Country = new Country { CountryCode = "CA", CountryName = "Canada", FederalTaxRate = 0.05m }, ProvinceCode = "ON", Province = new Province { CountryCode = "CA", ProvinceCode = "ON", ProvincialTaxRate = 0.08m }, MemberId = memberId, Id = addressId }; game = new Game { Name = "A game" }; platform = new Platform { PlatformCode = "XONE", PlatformName = "Xbox One" }; cartProduct1 = new PhysicalGameProduct { Id = cartProduct1Id, NewWebPrice = 60.00m, ProductAvailabilityStatus = AvailabilityStatus.Available, ReleaseDate = new DateTime(635835582902643008L, DateTimeKind.Local), UsedWebPrice = 10.00m, Game = game, Platform = platform }; cartProduct2 = new PhysicalGameProduct { Id = cartProduct2Id, NewWebPrice = 59.99m, ProductAvailabilityStatus = AvailabilityStatus.Available, ReleaseDate = new DateTime(635837213100050176L, DateTimeKind.Local), Game = game, Platform = platform }; newProduct1CartItem = new CartItem { IsNew = true, MemberId = memberId, Product = cartProduct1, ProductId = cartProduct1.Id, Quantity = 1 }; usedProduct1CartItem = new CartItem { IsNew = false, MemberId = memberId, Product = cartProduct1, ProductId = cartProduct1.Id, Quantity = 1 }; newProduct2CartItem = new CartItem { IsNew = true, MemberId = memberId, Product = cartProduct2, ProductId = cartProduct2.Id, Quantity = 1 }; validNotSavedShippingDetails = new WebOrderCheckoutDetails { Address = new Address { City = "Waterloo", PostalCode = "N2L 6R2", POBoxNumber = "123", StreetAddress = "445 Wes Graham Way" }, ProvinceCode = "ON", CountryCode = "CA" }; validAddressViewModel = new AddressViewModel { City = "Waterloo", CountryCode = "CA", ProvinceCode = "ON", POBoxNumber = "1234", PostalCode = "N2L 6R2", StreetAddress = "445 Wes Graham Way" }; memberCreditCard = new MemberCreditCard { Id = creditCardId, CardholderName = "John Doe", ExpiryMonth = 11, ExpiryYear = 2015, Last4Digits = "4242", Member = member, MemberId = memberId, StripeCardId = "cardToken" }; member = new Member { UserId = memberId, CreditCards = new List<MemberCreditCard> { memberCreditCard } }; memberUser = new User { FirstName = "John", LastName = "Doe", Id = memberId, PhoneNumber = "800-555-0199", }; validNotSavedShippingBillingDetails = new WebOrderCheckoutDetails { Address = new Address { City = "Waterloo", PostalCode = "N2L 6R2", POBoxNumber = "123", StreetAddress = "445 Wes Graham Way" }, ProvinceCode = "ON", CountryCode = "CA", StripeCardToken = "card_token" }; validSavedShippingBillingDetails = new WebOrderCheckoutDetails { MemberCreditCardId = creditCardId, MemberAddressId = addressId }; cartWithNewAndUsed = new Cart { Items = new List<CartItem> { newProduct1CartItem, usedProduct1CartItem }, Member = member, MemberId = memberId }; }