From 55584ce505a1c50bb65772ed03904fa69f30bc39 Mon Sep 17 00:00:00 2001 From: evan-scales Date: Mon, 22 Jan 2024 21:24:56 -0500 Subject: [PATCH] 201: API for getting post users --- FU.API/FU.API.Tests/PostServiceTests.cs | 111 +++++++++++++++++++ FU.API/FU.API/Controllers/PostsController.cs | 19 ++++ FU.API/FU.API/Helpers/Mapper.cs | 3 + FU.API/FU.API/Interfaces/IPostService.cs | 2 + FU.API/FU.API/Services/PostService.cs | 13 +++ 5 files changed, 148 insertions(+) create mode 100644 FU.API/FU.API.Tests/PostServiceTests.cs diff --git a/FU.API/FU.API.Tests/PostServiceTests.cs b/FU.API/FU.API.Tests/PostServiceTests.cs new file mode 100644 index 00000000..84399078 --- /dev/null +++ b/FU.API/FU.API.Tests/PostServiceTests.cs @@ -0,0 +1,111 @@ +namespace FU.API.Tests; + +using FU.API.Data; +using FU.API.Models; +using FU.API.Services; +using Microsoft.EntityFrameworkCore; + +public class PostServiceTests +{ + private readonly DbContextOptions _contextOptions; + + // adapted from https://github.com/dotnet/EntityFramework.Docs/blob/main/samples/core/Testing/TestingWithoutTheDatabase/InMemoryBloggingControllerTest.cs + public PostServiceTests() + { + _contextOptions = new DbContextOptionsBuilder() + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .Options; + } + + private AppDbContext CreateContext() + { + var context = new AppDbContext(_contextOptions); + + var testUsers = CreateTestUsers(); + var testChat = CreateTestChat(testUsers); + context.Set().Add(testChat); + context.Set().AddRange(testUsers); + + var post = new Post() + { + Id = 1, + Title = "TestTitle", + GameId = 1, + CreatorId = testUsers[0].UserId, + Creator = testUsers[0], + ChatId = testChat.Id, + Chat = testChat, + }; + + context.Set().Add(post); + context.SaveChanges(); + + return context; + } + + // Test for GetPostUsers method + + [Theory] + [InlineData(1, 1, true)] + [InlineData(1, 2, true)] + [InlineData(1, 5, false)] + public async void GetPostUsers_WithValidPostId_CheckUserJoined(int postId, int checkUserId, bool expectedJoined) + { + // Arrange + var context = CreateContext(); + var chatService = new ChatService(context); + var postService = new PostService(context, chatService); + + // Act + var postUsers = await postService.GetPostUsers(postId); + + // Assert + var joined = postUsers.Any(u => u.UserId == checkUserId); + Assert.Equal(expectedJoined, joined); + Assert.Equal(4, postUsers.Count()); + } + + private List CreateTestUsers() + { + return new List() + { + new ApplicationUser() + { + UserId = 1, + Username = "User1", + }, + new ApplicationUser() + { + UserId = 2, + Username = "User2", + }, + new ApplicationUser() + { + UserId = 3, + Username = "User3", + }, + new ApplicationUser() + { + UserId = 4, + Username = "User4", + }, + }; + } + + private Chat CreateTestChat(List users) + { + return new Chat() + { + Id = 1, + ChatType = ChatType.Post, + ChatName = "Title1", + CreatorId = 1, + Members = users.Select(u => new ChatMembership() + { + ChatId = 1, + UserId = u.UserId, + User = u, + }).ToList(), + }; + } +} diff --git a/FU.API/FU.API/Controllers/PostsController.cs b/FU.API/FU.API/Controllers/PostsController.cs index d942b7ee..b3edc0bc 100644 --- a/FU.API/FU.API/Controllers/PostsController.cs +++ b/FU.API/FU.API/Controllers/PostsController.cs @@ -92,4 +92,23 @@ public async Task LeavePost(int postId) return NoContent(); } + + [HttpGet] + [Route("{postId}/users")] + [AllowAnonymous] + public async Task GetPostUsers(int postId) + { + var post = await _postService.GetPost(postId); + + if (post is null) + { + return NotFound(); + } + + var users = await _postService.GetPostUsers(post.Id); + + var response = users.ToProfiles(); + + return Ok(response); + } } \ No newline at end of file diff --git a/FU.API/FU.API/Helpers/Mapper.cs b/FU.API/FU.API/Helpers/Mapper.cs index 84f1d97f..74e5198a 100644 --- a/FU.API/FU.API/Helpers/Mapper.cs +++ b/FU.API/FU.API/Helpers/Mapper.cs @@ -25,6 +25,9 @@ public static UserProfile ToProfile(this ApplicationUser appUser) }; } + public static IEnumerable ToProfiles(this IEnumerable appUsers) => + appUsers.Select(appUser => appUser.ToProfile()); + public static MessageResponseDTO ToDto(this Message message) { return new MessageResponseDTO() diff --git a/FU.API/FU.API/Interfaces/IPostService.cs b/FU.API/FU.API/Interfaces/IPostService.cs index 19e3d16e..3c2260a5 100644 --- a/FU.API/FU.API/Interfaces/IPostService.cs +++ b/FU.API/FU.API/Interfaces/IPostService.cs @@ -11,4 +11,6 @@ public interface IPostService : ICommonService Task JoinPost(int postId, ApplicationUser user); Task LeavePost(int postId, ApplicationUser user); + + Task> GetPostUsers(int postId); } diff --git a/FU.API/FU.API/Services/PostService.cs b/FU.API/FU.API/Services/PostService.cs index 1a494ade..b1c34c53 100644 --- a/FU.API/FU.API/Services/PostService.cs +++ b/FU.API/FU.API/Services/PostService.cs @@ -5,6 +5,7 @@ namespace FU.API.Services; using FU.API.Interfaces; using FU.API.Models; using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; public class PostService : CommonService, IPostService { @@ -67,6 +68,18 @@ public async Task CreatePost(Post post) .FirstOrDefaultAsync(); } + public async Task> GetPostUsers(int postId) + { + return await _dbContext.Posts + .Where(p => p.Id == postId) + .Include(p => p.Chat) + .ThenInclude(c => c.Members) + .ThenInclude(cm => cm.User) + .SelectMany(p => p.Chat.Members) + .Select(cm => cm.User) + .ToListAsync(); + } + public async Task JoinPost(int postId, ApplicationUser user) { var post = await _dbContext.Posts