public async Task CheckoutAsync_When_CartIsValid_Then_CartIsCheckedOut()
        {
            // Arrange
            fixture.Customize <Cart>().Set(x => x.IsCheckedOut, false);
            fixture.Customize <CartItem>().Set(x => x.ProductId, 2);
            fixture.Customize <CartItem>().Set(x => x.Quantity, 10);
            fixture.Customize <Product>().Set(x => x.Stock, int.MaxValue);

            var cart    = fixture.Generate <Cart>();
            var product = fixture.Generate <Product>();

            dataProvider.Setup(x => x.ProvideAsync())
            .ReturnsAsync(new List <Cart> {
                cart
            });

            var repository = new InMemoryCartRepository(dataProvider.Object);

            // Act
            await repository.CheckoutAsync(cart.Name, (x) => Task.FromResult(product));

            // Assert
            cart.IsCheckedOut.Should().BeTrue();
            product.Stock.Should().Be(int.MaxValue - cart.Items.Sum(x => x.Quantity));
        }
        public async Task CheckoutAsync_When_CartNotFound_Then_ExceptionsIsThrown()
        {
            // Arrange
            dataProvider.Setup(x => x.ProvideAsync())
            .ReturnsAsync(Enumerable.Empty <Cart>());

            var repository = new InMemoryCartRepository(dataProvider.Object);

            // Act
            await repository.CheckoutAsync(string.Empty, null);

            // Assert Exception
        }
        public async Task CheckoutAsync_When_ProductNotFound_Then_ExceptionsIsThrown()
        {
            // Arrange
            fixture.Customize <Cart>().Set(x => x.IsCheckedOut, false);
            var cart = fixture.Generate <Cart>();

            dataProvider.Setup(x => x.ProvideAsync())
            .ReturnsAsync(new List <Cart> {
                cart
            });

            var repository = new InMemoryCartRepository(dataProvider.Object);

            // Act
            await repository.CheckoutAsync(cart.Name, (x) => throw new ProdcutNotFoundException());

            // Assert Exception
        }
        public async Task CheckoutAsync_When_InsufficientStock_Then_ExceptionsIsThrown()
        {
            // Arrange
            fixture.Customize <Cart>().Set(x => x.IsCheckedOut, false);
            fixture.Customize <CartItem>().Set(x => x.ProductId, 2);
            fixture.Customize <CartItem>().Set(x => x.Quantity, 10);

            var cart = fixture.Generate <Cart>();

            dataProvider.Setup(x => x.ProvideAsync())
            .ReturnsAsync(new List <Cart> {
                cart
            });

            var repository = new InMemoryCartRepository(dataProvider.Object);

            // Act
            await repository.CheckoutAsync(cart.Name,
                                           (x) => Task.FromResult(fixture.Generate <Product>(constraints: new { Stock = 15 })));
        }