public async Task ItRemovesTheIngredient()
        {
            var original = new Recipe(name: nameof(ItRemovesTheIngredient));

            var toDelete = original.AddIngredient(new Ingredient(Guid.NewGuid().ToString()),
                                                  UnitOfMeasure.Cup, 2M);

            original.AddIngredient(new Ingredient(Guid.NewGuid().ToString()), UnitOfMeasure.Pint, 5M);

            await AppFixture.InsertAsync(original);

            var request = new RemoveIngredientRequest
            {
                RecipeModelKey           = new ModelUpdateIdentifier(original),
                RecipeIngredientModelKey = new ModelUpdateIdentifier(toDelete)
            };

            await AppFixture.SendAsync(request);

            var saved = await AppFixture.ExecuteDbContextAsync(async db =>
            {
                return(await db.Recipes.Where(x => x.Id == original.Id).Include(x => x.RecipeIngredients)
                       .FirstOrDefaultAsync());
            });

            saved.RecipeIngredients.Should().HaveCount(1);
            saved.RecipeIngredients[0].UnitOfMeasure.Should().Be(UnitOfMeasure.Pint);
        }
        public async Task ItAddsAnIngredient()
        {
            var ingredientName = Guid.NewGuid().ToString();

            var recipe = new Recipe(name: nameof(ItAddsAnIngredient));
            await AppFixture.InsertAsync(recipe);

            var result = await AppFixture.SendAsync(new AddIngredientRequest
            {
                RecipeKey     = new ModelUpdateIdentifier(recipe),
                Name          = ingredientName,
                Quantity      = 42M,
                UnitOfMeasure = UnitOfMeasure.Pint
            });

            var saved = await AppFixture.ExecuteDbContextAsync(db => db.RecipeIngredients
                                                               .Include(ri => ri.Ingredient)
                                                               .Include(ri => ri.Recipe)
                                                               .Where(ri => ri.Key == result.Key)
                                                               .FirstOrDefaultAsync());

            saved.Ingredient.Name.Should().Be(ingredientName);
            saved.Recipe.Key.Should().Be(recipe.Key);
            saved.UnitOfMeasure.Should().Be(UnitOfMeasure.Pint);
            saved.Quantity.Should().Be(42M);
        }
Beispiel #3
0
        public async Task CanSaveASimpleRecipe()
        {
            var recipe = new Recipe(name: "Chocolate Milk")
            {
                PrepTime = Duration.FromMinutes(3),
                CookTime = Duration.Zero
            };

            var milk           = new Ingredient("Milk");
            var chocolateSauce = new Ingredient("Chocolate Sauce");

            recipe.AddIngredient(milk, UnitOfMeasure.Cup, 1M);
            recipe.AddIngredient(chocolateSauce, UnitOfMeasure.Tablespoon, 2M);

            await AppFixture.InsertAsync(recipe);

            var saved = await AppFixture.ExecuteDbContextAsync(db =>
                                                               db.Recipes
                                                               .Include(r => r.RecipeIngredients)
                                                               .ThenInclude(ri => ri.Ingredient)
                                                               .Where(r => r.Key == recipe.Key)
                                                               .FirstOrDefaultAsync());

            saved.Name.Should().Be("Chocolate Milk");
            saved.PrepTime.Should().Be(Duration.FromMinutes(3));
            saved.CookTime.Should().Be(Duration.Zero);
            saved.RecipeIngredients.Should().HaveCount(2)
            .And.SatisfyRespectively(
                first =>
            {
                first.Id.Should().BeGreaterThan(0);
                first.Key.Should().NotBe(Guid.Empty);
                first.Quantity.Should().Be(1M);
                first.UnitOfMeasure.Should().Be(UnitOfMeasure.Cup);
                first.Ingredient.Should().Be(milk);
            },
                second =>
            {
                second.Id.Should().BeGreaterThan(0);
                second.Key.Should().NotBe(Guid.Empty);
                second.Quantity.Should().Be(2M);
                second.UnitOfMeasure.Should().Be(UnitOfMeasure.Tablespoon);
                second.Ingredient.Should().Be(chocolateSauce);
            });
        }
Beispiel #4
0
        public async Task ItSoftDeletesRecords()
        {
            var original = new Recipe(name: nameof(ItSoftDeletesRecords));
            await AppFixture.InsertAsync(original);

            await AppFixture.ExecuteDbContextAsync(async db =>
            {
                var saved = await db.Recipes.FindAsync(original.Id);
                saved.Should().NotBeNull("we just saved it");

                saved.SoftDelete();
                // db.Remove(saved);
            });

            var deleted = await AppFixture.FindAsync <Recipe>(original.Key);

            deleted.Should().BeNull("Recipe {0} was soft-deleted", original.Key);
        }
Beispiel #5
0
        public async Task ItTreatsVersionAsConcurrencyToken()
        {
            var original = new Recipe(name: nameof(ItTreatsVersionAsConcurrencyToken));
            await AppFixture.InsertAsync(original);

            FluentActions.Invoking(async() =>
            {
                await AppFixture.ExecuteDbContextAsync(async db =>
                {
                    var saved  = await db.Recipes.FirstOrDefaultAsync(x => x.Key == original.Key);
                    saved.Name = "Sally";

                    // record is updated by another user while this context is working with the entity
                    // so when it goes to save, the version numbers will no longer match
                    await db.Database.ExecuteSqlInterpolatedAsync(
                        $"update recipes set version = version + 1 where key = {original.Key}");
                });
            }).Should().Throw <DbUpdateConcurrencyException>();
        }
        public async Task ItDeletesRecipeAndIngredients()
        {
            var recipe     = new Recipe(name: nameof(ItDeletesRecipeAndIngredients));
            var ingredient = new Ingredient(Guid.NewGuid().ToString());

            recipe.AddIngredient(ingredient, UnitOfMeasure.Cup, 10M);
            await AppFixture.InsertAsync(recipe);

            await AppFixture.SendAsync(new RemoveRecipeRequest()
            {
                RecipeKey = new ModelUpdateIdentifier(recipe)
            });

            var deleted = await AppFixture.ExecuteDbContextAsync(db => db.GetRecipe(recipe.Key));

            deleted.Should().BeNull(because: "it was soft-deleted");

            var deletedIngredient = await AppFixture.FindAsync <RecipeIngredient>(ingredient.Key);

            deletedIngredient.Should().BeNull(because: "it was soft-deleted");
        }
Beispiel #7
0
        public async Task ItBumpsTheVersionAndEditTime()
        {
            var original = new Recipe(name: nameof(ItBumpsTheVersionAndEditTime));

            await AppFixture.InsertAsync(original);

            await AppFixture.ExecuteDbContextAsync(async db =>
            {
                var saved  = await db.Recipes.FirstOrDefaultAsync(x => x.Key == original.Key);
                saved.Name = "Milk";
            });

            var updated = await AppFixture.FindAsync <Recipe>(original.Key);

            updated.Name.Should().Be("Milk");
            updated.Version.Should().Be(2);

            updated.UpdatedAt.ToUnixTimeMilliseconds().Should()
            .BeGreaterThan(original.UpdatedAt.ToUnixTimeMilliseconds(),
                           because: "updated timestamps should be bumped on change");
            updated.CreatedAt.Should().Be(original.CreatedAt, because: "created timestamps are never changed");
        }