Files
Govor/Govor.API.Tests/IntegrationTests/Hubs/FriendsHubTests.cs
T
2025-11-04 11:51:37 +07:00

345 lines
12 KiB
C#

using AutoFixture;
using AutoMapper;
using Govor.API.Common.SignalR.Helpers;
using Govor.API.Hubs;
using Govor.Application.Exceptions.FriendsService;
using Govor.Application.Interfaces.Friends;
using Govor.Application.Interfaces.Infrastructure.Extensions;
using Govor.Contracts.DTOs;
using Govor.Contracts.Responses.SignalR;
using Govor.Core.Models;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Moq;
namespace Govor.API.Tests.IntegrationTests.Hubs;
[TestFixture]
public class FriendsHubTests
{
private Mock<IFriendRequestCommandService> _friendRequestServiceMock = null!;
private Mock<IHubUserAccessor> _currentUserServiceMock = null!;
private Mock<IHubCallerClients> _clientsMock = null!;
private Mock<IClientProxy> _clientProxyMock = null!;
private Mock<ILogger<FriendsHub>> _loggerMock = null!;
private Mock<IMapper> _mapperMock = null!;
private FriendsHub _hub = null!;
private Fixture _fixture;
private readonly Guid _userId = Guid.NewGuid();
private readonly Guid _targetUserId = Guid.NewGuid();
[SetUp]
public void Setup()
{
_fixture = new Fixture();
_fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList().ForEach(b => _fixture.Behaviors.Remove(b));
_fixture.Behaviors.Add(new OmitOnRecursionBehavior());
_friendRequestServiceMock = new Mock<IFriendRequestCommandService>();
_currentUserServiceMock = new Mock<IHubUserAccessor>();
_clientsMock = new Mock<IHubCallerClients>();
_clientProxyMock = new Mock<IClientProxy>();
_loggerMock = new Mock<ILogger<FriendsHub>>();
_mapperMock = new Mock<IMapper>();
_currentUserServiceMock.Setup(x => x.GetUserId(
It.IsAny<HubCallerContext>(),
It.IsAny<bool>()))
.Returns(_userId);
_clientsMock.Setup(c => c.Group(It.IsAny<string>())).Returns(_clientProxyMock.Object);
_hub = new FriendsHub(
_loggerMock.Object,
_friendRequestServiceMock.Object,
_currentUserServiceMock.Object,
_mapperMock.Object)
{
Clients = _clientsMock.Object
};
}
// Tests for SendRequest action
[Test]
public async Task SendRequest_ShouldReturnCreated_WhenSuccess()
{
var friendship = _fixture.Build<Friendship>()
.With(f => f.Status, FriendshipStatus.Pending)
.With(f => f.RequesterId, _userId)
.With(f =>f.AddresseeId, _targetUserId)
.Create();
var dto = new FriendshipDto()
{
Id = friendship.Id,
Status = FriendshipStatus.Accepted,
AddresseeId = friendship.AddresseeId,
RequesterId = friendship.RequesterId,
};
_mapperMock.Setup(f => f.Map<FriendshipDto>(friendship))
.Returns(dto);
_friendRequestServiceMock.Setup(f => f.SendAsync(_userId, _targetUserId))
.ReturnsAsync(friendship);
// Act
var result = await _hub.SendRequest(_targetUserId);
// Assert
Assert.That(result, Is.Not.Null);
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Created));
_friendRequestServiceMock.Verify(s => s.SendAsync(_userId, _targetUserId), Times.Once);
_clientProxyMock.Verify(c => c.SendCoreAsync(
"FriendRequestReceived",
It.Is<object[]>(o => o[0]!.Equals(dto)),
default), Times.Once);
}
[Test]
public async Task SendRequest_ShouldReturnBadRequest_WhenInvalidOperation()
{
// Arrange
_friendRequestServiceMock
.Setup(s => s.SendAsync(_userId, _targetUserId))
.ThrowsAsync(new InvalidOperationException("Invalid"));
// Act
var result = await _hub.SendRequest(_targetUserId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.BadRequest));
Assert.That(result.ErrorMessage, Is.EqualTo("Invalid"));
}
[Test]
public async Task SendRequest_ShouldReturnConflict_WhenAlreadySent()
{
// Arrange
_friendRequestServiceMock
.Setup(s => s.SendAsync(_userId, _targetUserId))
.ThrowsAsync(new RequestAlreadySentException(_userId, _targetUserId));
// Act
var result = await _hub.SendRequest(_targetUserId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Conflict));
Assert.That(result.ErrorMessage, Is.EqualTo($"Request was already sent from {_userId} to {_targetUserId}"));
}
[Test]
public async Task SendRequest_ShouldReturnUnauthorized_WhenCurrentUserIsNotAuthenticated()
{
// Arrange
_currentUserServiceMock.Setup(x => x.GetUserId(It.IsAny<HubCallerContext>(), It.IsAny<bool>()))
.Throws(new UnauthorizedAccessException("userId claim is missing or invalid"));
// Act
var result = await _hub.SendRequest(_targetUserId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Unauthorized));
Assert.That(result.ErrorMessage, Is.EqualTo("userId claim is missing or invalid"));
}
[Test]
public async Task SendRequest_ShouldReturnError_WhenSomeExceptionOccurs()
{
// Arrange
_friendRequestServiceMock
.Setup(s => s.SendAsync(_userId, _targetUserId))
.ThrowsAsync(new Exception("error"));
// Act
var result = await _hub.SendRequest(_targetUserId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.ServerError));
Assert.That(result.ErrorMessage, Is.EqualTo("Unexpected error! Please try later!"));
}
// Test for AcceptRequest action
[Test]
public async Task AcceptRequest_ShouldReturnOk_WhenSuccess()
{
// Arrange
var friendship = _fixture.Build<Friendship>()
.With(f => f.Status, FriendshipStatus.Pending)
.Create();
var dto = new FriendshipDto()
{
Id = friendship.Id,
Status = FriendshipStatus.Accepted,
AddresseeId = friendship.AddresseeId,
RequesterId = friendship.RequesterId
};
_mapperMock.Setup(f => f.Map<FriendshipDto>(friendship))
.Returns(dto);
_friendRequestServiceMock.Setup(f => f.AcceptAsync(friendship.Id, _userId))
.ReturnsAsync(friendship);
// Act
var result = await _hub.AcceptRequest(friendship.Id);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Success));
_friendRequestServiceMock.Verify(s => s.AcceptAsync(friendship.Id, _userId), Times.Once);
_clientProxyMock.Verify(c => c.SendCoreAsync(
"FriendRequestAccepted",
It.Is<object[]>(o => o.Length == 1 && o[0] == dto),
default), Times.Once);
}
[Test]
public async Task AcceptRequest_ShouldReturnBadRequest_InvalidOperation()
{
// Arrange
var friendshipId = Guid.NewGuid();
_friendRequestServiceMock
.Setup(s => s.AcceptAsync(friendshipId, _userId))
.ThrowsAsync(new InvalidOperationException("Invalid"));
// Act
var result = await _hub.AcceptRequest(friendshipId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.BadRequest));
Assert.That(result.ErrorMessage, Is.EqualTo("Invalid"));
}
[Test]
public async Task AcceptRequest_ShouldReturnUnauthorized_UnauthorizedAccess()
{
// Arrange
var friendshipId = Guid.NewGuid();
_friendRequestServiceMock
.Setup(s => s.AcceptAsync(friendshipId, _userId))
.ThrowsAsync(new UnauthorizedAccessException("userId claim is missing or invalid"));
// Act
var result = await _hub.AcceptRequest(friendshipId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Unauthorized));
Assert.That(result.ErrorMessage, Is.EqualTo("userId claim is missing or invalid"));
}
[Test]
public async Task AcceptRequest_ShouldReturnError_WhenSomeExceptionOccurs()
{
// Arrange
var friendshipId = Guid.NewGuid();
_friendRequestServiceMock
.Setup(s => s.AcceptAsync(friendshipId, _userId))
.ThrowsAsync(new Exception("error"));
// Act
var result = await _hub.AcceptRequest(friendshipId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.ServerError));
Assert.That(result.ErrorMessage, Is.EqualTo("Unexpected error! Please try later!"));
}
// Test for RejectRequest action
[Test]
public async Task RejectRequest_ShouldReturnOk_WhenSuccess()
{
// Arrange
var friendship = _fixture.Build<Friendship>()
.With(f => f.Status, FriendshipStatus.Pending)
.Create();
var dto = new FriendshipDto()
{
Id = friendship.Id,
Status = FriendshipStatus.Accepted,
AddresseeId = friendship.AddresseeId,
RequesterId = friendship.RequesterId
};
_mapperMock.Setup(f => f.Map<FriendshipDto>(friendship))
.Returns(dto);
_friendRequestServiceMock.Setup(f => f.RejectAsync(friendship.Id, _userId))
.ReturnsAsync(friendship);
// Act
var result = await _hub.RejectRequest(friendship.Id);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Success));
_friendRequestServiceMock.Verify(s => s.RejectAsync(friendship.Id, _userId), Times.Once);
_clientProxyMock.Verify(c => c.SendCoreAsync(
"FriendRequestRejected",
It.Is<object[]>(o => o[0]!.Equals(dto)),
default), Times.Once);
}
[Test]
public async Task RejectRequest_ShouldReturnBadRequest_InvalidOperation()
{
// Arrange
var friendshipId = Guid.NewGuid();
_friendRequestServiceMock
.Setup(s => s.RejectAsync(friendshipId, _userId))
.ThrowsAsync(new InvalidOperationException("Invalid"));
// Act
var result = await _hub.RejectRequest(friendshipId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.BadRequest));
Assert.That(result.ErrorMessage, Is.EqualTo("Invalid"));
}
[Test]
public async Task RejectRequest_ShouldReturnUnauthorized_UnauthorizedAccess()
{
// Arrange
var friendshipId = Guid.NewGuid();
_friendRequestServiceMock
.Setup(s => s.RejectAsync(friendshipId, _userId))
.ThrowsAsync(new UnauthorizedAccessException("userId claim is missing or invalid"));
// Act
var result = await _hub.RejectRequest(friendshipId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.Unauthorized));
Assert.That(result.ErrorMessage, Is.EqualTo("userId claim is missing or invalid"));
}
[Test]
public async Task RejectRequest_ShouldReturnError_WhenSomeExceptionOccurs()
{
// Arrange
var friendshipId = Guid.NewGuid();
_friendRequestServiceMock
.Setup(s => s.RejectAsync(friendshipId, _userId))
.ThrowsAsync(new Exception("error"));
// Act
var result = await _hub.RejectRequest(friendshipId);
// Assert
Assert.That(result.Status, Is.EqualTo(HubResultStatus.ServerError));
Assert.That(result.ErrorMessage, Is.EqualTo("Unexpected error! Please try later!"));
}
[TearDown]
public void TearDown()
{
_hub?.Dispose();
}
}