using AutoFixture; using Govor.API.Common.SignalR.Helpers; using Govor.API.Hubs; using Govor.Application.Interfaces.UserOnlineStatus; using Govor.Core.Models.Users; using Govor.Core.Repositories.Users; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using Moq; namespace Govor.API.Tests.Hubs; [TestFixture] [TestOf(typeof(PresenceHub))] public class PresenceHubTests { /* private Mock> _mockLogger; private Mock _mockUserNotification; private Mock _mockOnlineUserStore; private Mock _mockHubUserAccessor; private Mock _mockUserRepository; private Mock _clientsMock = null!; private Mock _clientProxyMock = null!; private Mock _mockContext = null!; private Mock _groupManagerMock = null!; private Fixture _fixture; private PresenceHub _hub; private Guid _userId; [SetUp] public void SetUp() { _fixture = new Fixture(); _fixture.Behaviors.OfType().ToList().ForEach(b => _fixture.Behaviors.Remove(b)); _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); _mockLogger = new Mock>(); _mockUserNotification = new Mock(); _mockOnlineUserStore = new Mock(); _mockHubUserAccessor = new Mock(); _mockUserRepository = new Mock(); _clientsMock = new Mock(); _clientProxyMock = new Mock(); _userId = Guid.NewGuid(); _mockHubUserAccessor.Setup(h => h.GetUserId( It.IsAny(), It.IsAny())) .Returns(_userId); _clientsMock.Setup(c => c.Group(It.IsAny())).Returns(_clientProxyMock.Object); _mockContext = new Mock(); _mockContext.Setup(c => c.ConnectionId).Returns("test-connection"); _groupManagerMock = new Mock(); _groupManagerMock.Setup(g => g.AddToGroupAsync(It.IsAny(), It.IsAny(), default)) .Returns(Task.CompletedTask); _hub = new PresenceHub( _mockLogger.Object, _mockUserNotification.Object, _mockOnlineUserStore.Object, _mockHubUserAccessor.Object, _mockUserRepository.Object) { Clients = _clientsMock.Object, Context = _mockContext.Object, Groups = _groupManagerMock.Object, }; } // Tests for OnConnectedAsync action [Test] public async Task OnConnectedAsync_SetsUserOnlineAndNotifiesFriends() { // Arrange _mockUserRepository.Setup(f => f.ExistsByIdAsync(_userId)) .ReturnsAsync(true); var friendsIds = _fixture.CreateMany().ToList(); _mockUserNotification.Setup(n => n.GetNotifiedUsers(_userId)) .ReturnsAsync(friendsIds); // Act await _hub.OnConnectedAsync(); // Assert _mockOnlineUserStore.Verify(store => store.SetOnlineUser(_userId), Times.Once); _clientsMock.Verify(c => c.Group(It.IsAny()), Times.Exactly(friendsIds.Count)); foreach (var friendId in friendsIds) { _clientProxyMock.Verify(proxy => proxy.SendCoreAsync("UserOnline", It.Is(args => args.Length == 1 && (Guid)args[0] == _userId), It.IsAny()), Times.Exactly(friendsIds.Count)); } } [Test] public async Task OnConnectedAsync_UserIdInvalidOrNotExists_AbortsConnection() { // Arrange _mockHubUserAccessor.Setup(h => h.GetUserId(It.IsAny(), false)) .Returns(Guid.Empty); // Act await _hub.OnConnectedAsync(); // Assert _mockOnlineUserStore.Verify(store => store.SetOnlineUser(It.IsAny()), Times.Never); _mockContext.Verify(c => c.Abort(), Times.Once); } [Test] public async Task OnConnectedAsync_UserNotExists_AbortsConnection() { // Arrange _mockUserRepository.Setup(f => f.ExistsByIdAsync(_userId)) .ReturnsAsync(false); // Act await _hub.OnConnectedAsync(); // Assert _mockOnlineUserStore.Verify(store => store.SetOnlineUser(It.IsAny()), Times.Never); _mockContext.Verify(c => c.Abort(), Times.Once); } // Tests for OnDisconnectedAsync action [Test] public async Task OnDisconnectedAsync_SetsUserOffline_UpdatesWasOnline_NotifiesFriends() { // Arrange var user = new User { Id = _userId, WasOnline = DateTime.MinValue }; var friendsIds = _fixture.CreateMany().ToList(); _mockUserRepository.Setup(r => r.FindByIdAsync(_userId)) .ReturnsAsync(user); _mockUserNotification.Setup(n => n.GetNotifiedUsers(_userId)) .ReturnsAsync(friendsIds); // Act await _hub.OnDisconnectedAsync(null!); // Assert _mockOnlineUserStore.Verify(store => store.SetOfflineUser(_userId), Times.Once); _mockUserRepository.Verify(r => r.UpdateAsync(It.Is(u => u.Id == _userId && u.WasOnline > DateTime.MinValue)), Times.Once); _clientsMock.Verify(c => c.Group(It.IsAny()), Times.AtLeastOnce); foreach (var friendId in friendsIds) { _clientProxyMock.Verify(proxy => proxy.SendCoreAsync("UserOffline", It.Is(args => args.Length == 1 && (Guid)args[0] == _userId), It.IsAny()), Times.Exactly(friendsIds.Count)); } } [Test] public async Task OnDisconnectedAsync_UserIdEmpty_LogsAndSkips() { // Arrange _mockHubUserAccessor.Setup(h => h.GetUserId(It.IsAny(), true)) .Returns(Guid.Empty); // Act await _hub.OnDisconnectedAsync(null!); // Assert _mockOnlineUserStore.Verify(s => s.SetOfflineUser(It.IsAny()), Times.Never); _mockUserRepository.Verify(r => r.UpdateAsync(It.IsAny()), Times.Never); _clientProxyMock.Verify(proxy => proxy.SendCoreAsync("UserOffline", It.Is(args => args.Length == 1 && (Guid)args[0] == _userId), It.IsAny()), Times.Never); } [TearDown] public void TearDown() { _hub?.Dispose(); } */ }