diff --git a/Govor.API.Tests/UnitTests/Services/UserGroupsServiceTests.cs b/Govor.API.Tests/UnitTests/Services/UserGroupsServiceTests.cs new file mode 100644 index 0000000..4849ed8 --- /dev/null +++ b/Govor.API.Tests/UnitTests/Services/UserGroupsServiceTests.cs @@ -0,0 +1,70 @@ +using AutoFixture; +using Govor.Application.Interfaces; +using Govor.Application.Services; +using Govor.Core.Models; +using Govor.Core.Repositories.Groups; +using Govor.Data.Repositories.Exceptions; +using Moq; + +namespace Govor.API.Tests.UnitTests.Services; + +[TestFixture] +public class UserGroupsServiceTests +{ + private Fixture _fixture; + private Mock _repositoryMock; + private IUserGroupsService _service; + + [SetUp] + public void SetUp() + { + _fixture = new Fixture(); + + _fixture.Behaviors + .OfType() + .ToList() + .ForEach(b => _fixture.Behaviors.Remove(b)); + + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + _repositoryMock = new Mock(); + + _service = new UserGroupsService(_repositoryMock.Object); + } + + [Test] + public async Task GetUserGroups_ShouldReturnAllUserGroups() + { + // Arrange + var chats = _fixture.CreateMany(); + var userId = chats.First().Members.First().Id; + + _repositoryMock.Setup(r => r.GetByUserIdAsync(userId)) + .ReturnsAsync([chats.First()]); + + // Act + var result = await _service.GetUserGroupsAsync(userId); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result.Count(), Is.EqualTo(1)); + Assert.That(result, Is.EquivalentTo([chats.First()])); + } + + [Test] + public async Task GetUserGroups_ButGroupDoesNotExist_ShouldReturnEmptyList() + { + // Arrange + var userId = _fixture.Create(); + + _repositoryMock.Setup(r => r.GetByUserIdAsync(userId)) + .ThrowsAsync(new NotFoundByKeyException(userId)); + + // Act + var result = await _service.GetUserGroupsAsync(userId); + + // Assert + Assert.That(result, Is.Not.Null); + Assert.That(result.Count(), Is.EqualTo(0)); + } +} \ No newline at end of file diff --git a/Govor.API/Extensions/ConfigurationProgramExtensions.cs b/Govor.API/Extensions/ConfigurationProgramExtensions.cs index c727014..d9d49f8 100644 --- a/Govor.API/Extensions/ConfigurationProgramExtensions.cs +++ b/Govor.API/Extensions/ConfigurationProgramExtensions.cs @@ -52,6 +52,7 @@ public static class ConfigurationProgramExtensions services.AddScoped(); services.AddScoped(); + services.AddScoped(); } public static void AddRepositories(this IServiceCollection services) diff --git a/Govor.API/Hubs/ChatsHub.cs b/Govor.API/Hubs/ChatsHub.cs index 8c5eb3e..792c7f4 100644 --- a/Govor.API/Hubs/ChatsHub.cs +++ b/Govor.API/Hubs/ChatsHub.cs @@ -1,4 +1,5 @@ using Govor.API.Services; +using Govor.Application.Interfaces; using Govor.Application.Interfaces.Messages; using Govor.Application.Interfaces.Messages.Parameters; using Govor.Contracts.Requests.SignalR; @@ -14,6 +15,7 @@ public class ChatsHub : Hub { private readonly ILogger _logger; private readonly IMessageService _messageService; + private readonly IUserGroupsService _userService; public ChatsHub(ILogger logger, IMessageService messageService) { @@ -34,13 +36,12 @@ public class ChatsHub : Hub // Add user to their own group (for private messages and notifications) await Groups.AddToGroupAsync(Context.ConnectionId, userId.ToString()); _logger.LogInformation("User {UserId} connected with ConnectionId {ConnectionId} and added to their group", userId, Context.ConnectionId); - - // TODO: Add user to their chat groups - this might require fetching user's groups from a service - // var userGroups = await _userService.GetUserGroupsAsync(userId); - // foreach (var group in userGroups) - // { - // await Groups.AddToGroupAsync(Context.ConnectionId, $"group_{group.Id}"); - // } + + var userGroups = await _userService.GetUserGroupsAsync(userId); + foreach (var group in userGroups) + { + await Groups.AddToGroupAsync(Context.ConnectionId, $"group_{group.Id}"); + } await base.OnConnectedAsync(); } @@ -54,12 +55,12 @@ public class ChatsHub : Hub await Groups.RemoveFromGroupAsync(Context.ConnectionId, userId.ToString()); _logger.LogInformation("User {UserId} disconnected with ConnectionId {ConnectionId} and removed from their group", userId, Context.ConnectionId); - // TODO: Remove user from their chat groups - // var userGroups = await _userService.GetUserGroupsAsync(userId); // This might be problematic if the service relies on the user being connected - // foreach (var group in userGroups) - // { - // await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"group_{group.Id}"); - // } + + var userGroups = await _userService.GetUserGroupsAsync(userId); // This might be problematic if the service relies on the user being connected + foreach (var group in userGroups) + { + await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"group_{group.Id}"); + } } else if (exception != null) { diff --git a/Govor.Application/Interfaces/IUserGroupsService.cs b/Govor.Application/Interfaces/IUserGroupsService.cs new file mode 100644 index 0000000..1e51276 --- /dev/null +++ b/Govor.Application/Interfaces/IUserGroupsService.cs @@ -0,0 +1,8 @@ +using Govor.Core.Models; + +namespace Govor.Application.Interfaces; + +public interface IUserGroupsService +{ + Task> GetUserGroupsAsync(Guid userId); +} \ No newline at end of file diff --git a/Govor.Application/Services/UserGroupsService.cs b/Govor.Application/Services/UserGroupsService.cs new file mode 100644 index 0000000..04b04c0 --- /dev/null +++ b/Govor.Application/Services/UserGroupsService.cs @@ -0,0 +1,28 @@ +using Govor.Application.Interfaces; +using Govor.Core.Models; +using Govor.Core.Repositories.Groups; +using Govor.Data.Repositories.Exceptions; + +namespace Govor.Application.Services; + +public class UserGroupsService : IUserGroupsService +{ + private readonly IGroupsRepository _groupRep; + + public UserGroupsService(IGroupsRepository groupsRepository) + { + _groupRep = groupsRepository; + } + + public async Task> GetUserGroupsAsync(Guid userId) + { + try + { + return await _groupRep.GetByUserIdAsync(userId); + } + catch (NotFoundByKeyException ex) + { + return new List(); + } + } +} \ No newline at end of file