From 0a5573939eb8b6c77295ecc1ab50df39aa6a6b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Michalik?= Date: Wed, 8 Dec 2021 21:57:20 +0100 Subject: [PATCH] #6 On /TodoList show also TodoLists containing at least one Item that user is responsible for --- Todo.Tests/Builders/TestTodoListBuilder.cs | 12 +++- Todo.Tests/Todo.Tests.csproj | 1 + ...serOrUserIsResponsibleForAtLeastOneItem.cs | 64 +++++++++++++++++++ Todo/Data/ApplicationDbContext.cs | 3 +- Todo/Data/IApplicationDbContext.cs | 11 ++++ .../ApplicationDbContextConvenience.cs | 9 +-- 6 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 Todo.Tests/WhenFilteringTodoListByIsOwnedByUserOrUserIsResponsibleForAtLeastOneItem.cs create mode 100644 Todo/Data/IApplicationDbContext.cs diff --git a/Todo.Tests/Builders/TestTodoListBuilder.cs b/Todo.Tests/Builders/TestTodoListBuilder.cs index 9ad549ba..d911e43c 100644 --- a/Todo.Tests/Builders/TestTodoListBuilder.cs +++ b/Todo.Tests/Builders/TestTodoListBuilder.cs @@ -12,7 +12,7 @@ public class TestTodoListBuilder { private readonly string title; private readonly IdentityUser owner; - private readonly List<(string, Importance)> items = new List<(string, Importance)>(); + private readonly List<(string, Importance, string)> items = new(); public TestTodoListBuilder(IdentityUser owner, string title) { @@ -22,14 +22,20 @@ public TestTodoListBuilder(IdentityUser owner, string title) public TestTodoListBuilder WithItem(string itemTitle, Importance importance) { - items.Add((itemTitle, importance)); + items.Add((itemTitle, importance, null)); + return this; + } + + public TestTodoListBuilder WithItem(string itemTitle, Importance importance, string responsiblePartyId) + { + items.Add((itemTitle, importance, responsiblePartyId)); return this; } public TodoList Build() { var todoList = new TodoList(owner, title); - var todoItems = items.Select(itm => new TodoItem(todoList.TodoListId, owner.Id, itm.Item1, itm.Item2)); + var todoItems = items.Select(itm => new TodoItem(todoList.TodoListId, itm.Item3 ?? owner.Id, itm.Item1, itm.Item2)); todoItems.ToList().ForEach(tlItm => { todoList.Items.Add(tlItm); diff --git a/Todo.Tests/Todo.Tests.csproj b/Todo.Tests/Todo.Tests.csproj index 66618326..d5bfaf0c 100644 --- a/Todo.Tests/Todo.Tests.csproj +++ b/Todo.Tests/Todo.Tests.csproj @@ -11,6 +11,7 @@ + diff --git a/Todo.Tests/WhenFilteringTodoListByIsOwnedByUserOrUserIsResponsibleForAtLeastOneItem.cs b/Todo.Tests/WhenFilteringTodoListByIsOwnedByUserOrUserIsResponsibleForAtLeastOneItem.cs new file mode 100644 index 00000000..631fc140 --- /dev/null +++ b/Todo.Tests/WhenFilteringTodoListByIsOwnedByUserOrUserIsResponsibleForAtLeastOneItem.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Moq; +using Todo.Data; +using Todo.Data.Entities; +using Todo.Services; +using Todo.Tests.Builders; +using Xunit; + +namespace Todo.Tests +{ + public class WhenFilteringTodoListByIsOwnedByUserOrUserIsResponsibleForAtLeastOneItem + { + private static readonly IdentityUser TestUser = new("alice@example.com"); + private static readonly IdentityUser AnotherUser = new("ben@example.com"); + private static readonly TodoList TodoListOwnedByTestUser = new TestTodoListBuilder(TestUser, "shopping") + .WithItem("bread", Importance.High) + .WithItem("milk", Importance.Medium) + .Build(); + private static readonly TodoList TodoListOwnedByAnotherUser = new TestTodoListBuilder(AnotherUser, "shopping") + .WithItem("bread", Importance.High) + .WithItem("milk", Importance.Medium) + .Build(); + private static readonly TodoList TodoListOwnedByAnotherUserButWithItemThatTestUserIsResponsibleFor = new TestTodoListBuilder(AnotherUser, "shopping") + .WithItem("bread", Importance.High) + .WithItem("milk", Importance.Medium) + .WithItem("milk", Importance.Low, TestUser.Id) + .Build(); + private readonly IApplicationDbContext dbContext; + + public WhenFilteringTodoListByIsOwnedByUserOrUserIsResponsibleForAtLeastOneItem() + { + var data = new List + { + TodoListOwnedByTestUser, TodoListOwnedByAnotherUser, + TodoListOwnedByAnotherUserButWithItemThatTestUserIsResponsibleFor + }.AsQueryable(); + + var mockSet = new Mock>(); + mockSet.As>().Setup(m => m.Provider).Returns(data.Provider); + mockSet.As>().Setup(m => m.Expression).Returns(data.Expression); + mockSet.As>().Setup(m => m.ElementType).Returns(data.ElementType); + mockSet.As>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); + + var mockContext = new Mock(); + mockContext.Setup(c => c.TodoLists).Returns(mockSet.Object); + + dbContext = mockContext.Object; + } + + [Fact] + public void FilteredCollectionContainsOnlyTodoListsThatUserIsResponsibleFor() + { + var collectionOfTodoListsFiltered = dbContext.RelevantTodoLists(TestUser.Id); + + Assert.Equal(new List{TodoListOwnedByTestUser, + TodoListOwnedByAnotherUserButWithItemThatTestUserIsResponsibleFor}, collectionOfTodoListsFiltered); + } + } +} \ No newline at end of file diff --git a/Todo/Data/ApplicationDbContext.cs b/Todo/Data/ApplicationDbContext.cs index 4dd7ae40..0448c8b2 100644 --- a/Todo/Data/ApplicationDbContext.cs +++ b/Todo/Data/ApplicationDbContext.cs @@ -4,14 +4,13 @@ namespace Todo.Data { - public class ApplicationDbContext : IdentityDbContext + public class ApplicationDbContext : IdentityDbContext, IApplicationDbContext { public ApplicationDbContext(DbContextOptions options) : base(options) { } - public DbSet TodoLists { get; set; } public DbSet TodoItems { get; set; } diff --git a/Todo/Data/IApplicationDbContext.cs b/Todo/Data/IApplicationDbContext.cs new file mode 100644 index 00000000..3747765a --- /dev/null +++ b/Todo/Data/IApplicationDbContext.cs @@ -0,0 +1,11 @@ +using Microsoft.EntityFrameworkCore; +using Todo.Data.Entities; + +namespace Todo.Data +{ + public interface IApplicationDbContext + { + DbSet TodoLists { get; set; } + DbSet TodoItems { get; set; } + } +} \ No newline at end of file diff --git a/Todo/Services/ApplicationDbContextConvenience.cs b/Todo/Services/ApplicationDbContextConvenience.cs index 3549d4b3..1fd9314d 100644 --- a/Todo/Services/ApplicationDbContextConvenience.cs +++ b/Todo/Services/ApplicationDbContextConvenience.cs @@ -7,14 +7,15 @@ namespace Todo.Services { public static class ApplicationDbContextConvenience { - public static IQueryable RelevantTodoLists(this ApplicationDbContext dbContext, string userId) + public static IQueryable RelevantTodoLists(this IApplicationDbContext dbContext, string userId) { return dbContext.TodoLists.Include(tl => tl.Owner) .Include(tl => tl.Items) - .Where(tl => tl.Owner.Id == userId); + .Where(tl => tl.Owner.Id == userId || tl.Items + .Select(item => item.ResponsiblePartyId).Contains(userId)); } - public static TodoList SingleTodoList(this ApplicationDbContext dbContext, int todoListId) + public static TodoList SingleTodoList(this IApplicationDbContext dbContext, int todoListId) { return dbContext.TodoLists.Include(tl => tl.Owner) .Include(tl => tl.Items) @@ -22,7 +23,7 @@ public static TodoList SingleTodoList(this ApplicationDbContext dbContext, int t .Single(tl => tl.TodoListId == todoListId); } - public static TodoItem SingleTodoItem(this ApplicationDbContext dbContext, int todoItemId) + public static TodoItem SingleTodoItem(this IApplicationDbContext dbContext, int todoItemId) { return dbContext.TodoItems.Include(ti => ti.TodoList).Single(ti => ti.TodoItemId == todoItemId); }