diff --git a/web/backend/Features/Features.Users.Tests/Queries/GetPublicUserProfileByIdHandlerTests.cs b/web/backend/Features/Features.Users.Tests/Queries/GetPublicUserProfileByIdHandlerTests.cs new file mode 100644 index 00000000..fc732a7c --- /dev/null +++ b/web/backend/Features/Features.Users.Tests/Queries/GetPublicUserProfileByIdHandlerTests.cs @@ -0,0 +1,65 @@ +using Domain.Entities; +using Domain.Exceptions; +using Features.Users.Dtos; +using Features.Users.Queries.GetPublicUserProfileById; +using Features.Users.Repository; +using FluentAssertions; +using Moq; + +namespace Features.Users.Tests.Queries; + +public class GetPublicUserProfileByIdHandlerTests +{ + private readonly GetPublicUserProfileByIdHandler _handler; + private readonly Mock _repoMock = new(); + + public GetPublicUserProfileByIdHandlerTests() + { + _handler = new GetPublicUserProfileByIdHandler(_repoMock.Object); + } + + [Fact] + public async Task Handle_ReturnsPublicProfile_WhenFound() + { + UserAccount user = new() + { + UserAccountId = Guid.NewGuid(), + Username = "test", + FirstName = "Jane", + LastName = "Doe", + Email = "jane@example.com", + DateOfBirth = new DateTime(1990, 1, 1), + CreatedAt = new DateTime(2024, 1, 1), + }; + _repoMock.Setup(r => r.GetByIdAsync(user.UserAccountId)).ReturnsAsync(user); + + PublicUserProfileDto result = await _handler.Handle( + new GetPublicUserProfileByIdQuery(user.UserAccountId), + CancellationToken.None + ); + + result + .Should() + .Be( + new PublicUserProfileDto( + user.UserAccountId, + user.Username, + user.FirstName, + user.LastName, + user.CreatedAt + ) + ); + } + + [Fact] + public async Task Handle_Throws_WhenNotFound() + { + Guid id = Guid.NewGuid(); + _repoMock.Setup(r => r.GetByIdAsync(id)).ReturnsAsync((UserAccount?)null); + + Func> act = async () => + await _handler.Handle(new GetPublicUserProfileByIdQuery(id), CancellationToken.None); + + await act.Should().ThrowAsync(); + } +} diff --git a/web/backend/Features/Features.Users/Controllers/UserController.cs b/web/backend/Features/Features.Users/Controllers/UserController.cs index eeff6436..a6ba7c57 100644 --- a/web/backend/Features/Features.Users/Controllers/UserController.cs +++ b/web/backend/Features/Features.Users/Controllers/UserController.cs @@ -2,6 +2,7 @@ using Domain.Entities; using Domain.Exceptions; using Features.Users.Dtos; using Features.Users.Queries.GetAllUsers; +using Features.Users.Queries.GetPublicUserProfileById; using Features.Users.Queries.GetUserById; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -50,7 +51,7 @@ public class UserController(IMediator mediator) : ControllerBase [HttpGet("{id:guid}/profile")] public async Task> GetPublicProfile(Guid id) { - UserAccount user = await mediator.Send(new GetUserByIdQuery(id)); - return Ok(user.ToPublicProfileDto()); + PublicUserProfileDto profile = await mediator.Send(new GetPublicUserProfileByIdQuery(id)); + return Ok(profile); } } diff --git a/web/backend/Features/Features.Users/Queries/GetPublicUserProfileById/GetPublicUserProfileByIdHandler.cs b/web/backend/Features/Features.Users/Queries/GetPublicUserProfileById/GetPublicUserProfileByIdHandler.cs new file mode 100644 index 00000000..47965586 --- /dev/null +++ b/web/backend/Features/Features.Users/Queries/GetPublicUserProfileById/GetPublicUserProfileByIdHandler.cs @@ -0,0 +1,23 @@ +using Domain.Entities; +using Domain.Exceptions; +using Features.Users.Dtos; +using Features.Users.Repository; +using MediatR; + +namespace Features.Users.Queries.GetPublicUserProfileById; + +public class GetPublicUserProfileByIdHandler(IUserListRepository repository) + : IRequestHandler +{ + /// Thrown when no user account exists with the given ID. + public async Task Handle( + GetPublicUserProfileByIdQuery request, + CancellationToken cancellationToken + ) + { + UserAccount? user = await repository.GetByIdAsync(request.UserAccountId); + if (user is null) + throw new NotFoundException($"User with ID {request.UserAccountId} not found"); + return user.ToPublicProfileDto(); + } +} diff --git a/web/backend/Features/Features.Users/Queries/GetPublicUserProfileById/GetPublicUserProfileByIdQuery.cs b/web/backend/Features/Features.Users/Queries/GetPublicUserProfileById/GetPublicUserProfileByIdQuery.cs new file mode 100644 index 00000000..b4dfa53f --- /dev/null +++ b/web/backend/Features/Features.Users/Queries/GetPublicUserProfileById/GetPublicUserProfileByIdQuery.cs @@ -0,0 +1,6 @@ +using Features.Users.Dtos; +using MediatR; + +namespace Features.Users.Queries.GetPublicUserProfileById; + +public record GetPublicUserProfileByIdQuery(Guid UserAccountId) : IRequest;