mirror of
https://github.com/Govor-team/Govor.git
synced 2026-07-21 19:54:55 +00:00
330 lines
11 KiB
C#
330 lines
11 KiB
C#
using AutoFixture;
|
||
using Govor.Application.Exceptions.FriendsService;
|
||
using Govor.Application.Interfaces.Friends;
|
||
using Govor.Application.Services.Friends;
|
||
using Govor.Core.Models;
|
||
using Govor.Core.Repositories.Friendships;
|
||
using Govor.Core.Repositories.Users;
|
||
using Govor.Data.Repositories.Exceptions;
|
||
using Moq;
|
||
|
||
namespace Govor.API.Tests.UnitTests.Services.Friends;
|
||
|
||
[TestFixture]
|
||
public class FriendRequestServiceTests
|
||
{
|
||
private Fixture _fixture;
|
||
private Mock<IUsersRepository> _usersRepositoryMock;
|
||
private Mock<IFriendshipsRepository> _friendshipsRepositoryMock;
|
||
private IFriendRequestService _service;
|
||
|
||
[SetUp]
|
||
public void SetUp()
|
||
{
|
||
_fixture = new Fixture();
|
||
_fixture.Behaviors
|
||
.OfType<ThrowingRecursionBehavior>()
|
||
.ToList()
|
||
.ForEach(b => _fixture.Behaviors.Remove(b));
|
||
_fixture.Behaviors.Add(new OmitOnRecursionBehavior());
|
||
|
||
_usersRepositoryMock = new Mock<IUsersRepository>();
|
||
_friendshipsRepositoryMock = new Mock<IFriendshipsRepository>();
|
||
|
||
_service = new FriendRequestService(_friendshipsRepositoryMock.Object);
|
||
}
|
||
|
||
// SendFriendRequestAsync
|
||
[Test]
|
||
public void SendFriendRequestAsync_SendingToSelf_ThrowsInvalidOperationException()
|
||
{
|
||
// Arrange
|
||
var userId = Guid.NewGuid();
|
||
|
||
// Act & Assert
|
||
var ex = Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||
_service.SendFriendRequestAsync(userId, userId));
|
||
|
||
Assert.That(ex.Message, Is.EqualTo("Cannot send a request to self user"));
|
||
}
|
||
|
||
[Test]
|
||
public void SendFriendRequestAsync_RequestAlreadyExists_ThrowsRequestAlreadySentException()
|
||
{
|
||
// Arrange
|
||
var fromUserId = Guid.NewGuid();
|
||
var toUserId = Guid.NewGuid();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(repo => repo.Exist(fromUserId, toUserId))
|
||
.Returns(true);
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<RequestAlreadySentException>(() =>
|
||
_service.SendFriendRequestAsync(fromUserId, toUserId));
|
||
}
|
||
|
||
[Test]
|
||
public async Task SendFriendRequestAsync_ValidRequest_CallsAddAsync()
|
||
{
|
||
// Arrange
|
||
var fromUserId = Guid.NewGuid();
|
||
var toUserId = Guid.NewGuid();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(repo => repo.Exist(fromUserId, toUserId))
|
||
.Returns(false);
|
||
|
||
// Act
|
||
await _service.SendFriendRequestAsync(fromUserId, toUserId);
|
||
|
||
// Assert
|
||
_friendshipsRepositoryMock.Verify(repo =>
|
||
repo.AddAsync(It.Is<Friendship>(f =>
|
||
f.RequesterId == fromUserId &&
|
||
f.AddresseeId == toUserId &&
|
||
f.Status == FriendshipStatus.Pending &&
|
||
f.Id != Guid.Empty
|
||
)),
|
||
Times.Once);
|
||
}
|
||
|
||
// AcceptFriendRequestAsync
|
||
[Test]
|
||
public async Task AcceptFriendRequestAsync_ValidRequest_CallsUpdateAsync()
|
||
{
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Pending)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
// Act: вызываем именно Accept, не Send
|
||
await _service.AcceptFriendRequestAsync(friendship.Id, friendship.AddresseeId);
|
||
|
||
// Assert
|
||
_friendshipsRepositoryMock.Verify(r => r.UpdateAsync(It.Is<Friendship>(f =>
|
||
f.Id == friendship.Id &&
|
||
f.RequesterId == friendship.RequesterId &&
|
||
f.AddresseeId == friendship.AddresseeId &&
|
||
f.Status == FriendshipStatus.Accepted
|
||
)), Times.Once);
|
||
}
|
||
|
||
[Test]
|
||
public void AcceptFriendRequestAsync_Throws_InvalidOperationException_IfStatusNotEqualPending()
|
||
{
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Accepted)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<InvalidOperationException>(async () => await _service.AcceptFriendRequestAsync(friendship.Id, friendship.AddresseeId));
|
||
}
|
||
[Test]
|
||
public void AcceptFriendRequestAsync_Throws_UnauthorizedAccessException_IfCurrentUserIdIsNotAddressee()
|
||
{
|
||
// Arrange
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Pending)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
var wrongUserId = Guid.NewGuid(); // не совпадает с AddresseeId
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
|
||
await _service.AcceptFriendRequestAsync(friendship.Id, wrongUserId));
|
||
}
|
||
|
||
[Test]
|
||
public void AcceptFriendRequestAsync_Throws_InvalidOperationException_IfFriendshipNotFound()
|
||
{
|
||
// Arrange
|
||
var requestId = Guid.NewGuid();
|
||
var userId = Guid.NewGuid();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(requestId))
|
||
.ThrowsAsync(new NotFoundByKeyException<Guid>(requestId));
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||
await _service.AcceptFriendRequestAsync(requestId, userId));
|
||
}
|
||
|
||
[Test]
|
||
public async Task AcceptFriendRequestAsync_ChangesStatusToAccepted()
|
||
{
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Pending)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
Friendship updatedFriendship = null;
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.UpdateAsync(It.IsAny<Friendship>()))
|
||
.Callback<Friendship>(f => updatedFriendship = f)
|
||
.Returns(Task.CompletedTask);
|
||
|
||
await _service.AcceptFriendRequestAsync(friendship.Id, friendship.AddresseeId);
|
||
|
||
Assert.That(updatedFriendship.Status, Is.EqualTo(FriendshipStatus.Accepted));
|
||
}
|
||
|
||
// RejectFriend
|
||
[Test]
|
||
public async Task RejectFriendRequestAsync_ValidRequest_CallsRemoveAsync()
|
||
{
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Pending)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
await _service.RejectFriendRequestAsync(friendship.Id, friendship.AddresseeId);
|
||
|
||
// Assert
|
||
_friendshipsRepositoryMock.Verify(r => r.UpdateAsync(It.Is<Friendship>(f =>
|
||
f.Id == friendship.Id &&
|
||
f.RequesterId == friendship.RequesterId &&
|
||
f.AddresseeId == friendship.AddresseeId &&
|
||
f.Status == FriendshipStatus.Rejected
|
||
)), Times.Once);
|
||
}
|
||
|
||
[Test]
|
||
public void RejectFriendRequestAsync_Throws_InvalidOperationException_IfStatusNotEqualPendingOrReject()
|
||
{
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Accepted)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<InvalidOperationException>(async () => await _service.RejectFriendRequestAsync(friendship.Id, friendship.AddresseeId));
|
||
}
|
||
|
||
[Test]
|
||
public void RejectFriendRequestAsync_Throws_UnauthorizedAccessException_IfCurrentUserIdIsNotAddressee()
|
||
{
|
||
// Arrange
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Pending)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
var wrongUserId = Guid.NewGuid(); // не совпадает с AddresseeId
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<UnauthorizedAccessException>(async () =>
|
||
await _service.RejectFriendRequestAsync(friendship.Id, wrongUserId));
|
||
}
|
||
|
||
[Test]
|
||
public void RejectFriendRequestAsync_Throws_InvalidOperationException_IfFriendshipNotFound()
|
||
{
|
||
// Arrange
|
||
var requestId = Guid.NewGuid();
|
||
var userId = Guid.NewGuid();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(requestId))
|
||
.ThrowsAsync(new NotFoundByKeyException<Guid>(requestId));
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||
await _service.RejectFriendRequestAsync(requestId, userId));
|
||
}
|
||
|
||
[Test]
|
||
public async Task RejectFriendRequestAsync_ChangesStatusToAccepted()
|
||
{
|
||
var friendship = _fixture.Build<Friendship>()
|
||
.With(f => f.Status, FriendshipStatus.Pending)
|
||
.Create();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.GetByIdAsync(friendship.Id))
|
||
.ReturnsAsync(friendship);
|
||
|
||
Friendship updatedFriendship = null;
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.UpdateAsync(It.IsAny<Friendship>()))
|
||
.Callback<Friendship>(f => updatedFriendship = f)
|
||
.Returns(Task.CompletedTask);
|
||
|
||
await _service.RejectFriendRequestAsync(friendship.Id, friendship.AddresseeId);
|
||
|
||
Assert.That(updatedFriendship.Status, Is.EqualTo(FriendshipStatus.Rejected));
|
||
}
|
||
|
||
// GetIncomingRequestsAsync
|
||
[Test]
|
||
public async Task GetIncomingRequestsAsync_ReturnsFriendships_IfFriendshipsExists()
|
||
{
|
||
// Arrange
|
||
var userId = Guid.NewGuid();
|
||
|
||
var friendships = _fixture.CreateMany<Friendship>().ToList();
|
||
|
||
var user = _fixture.Build<User>()
|
||
.With(u => u.Id, userId)
|
||
.With(u => u.ReceivedFriendRequests, friendships)
|
||
.Create();
|
||
|
||
friendships.ForEach(f =>
|
||
{
|
||
f.AddresseeId = userId;
|
||
f.Addressee = user;
|
||
f.Status = FriendshipStatus.Pending;
|
||
});
|
||
|
||
_friendshipsRepositoryMock.Setup(f => f.FindByUserIdAsync(userId))
|
||
.ReturnsAsync(friendships);
|
||
|
||
// Act
|
||
var result = await _service.GetIncomingRequestsAsync(userId);
|
||
|
||
// Assert
|
||
Assert.That(result.Count, Is.EqualTo(friendships.Count));
|
||
Assert.That(result.Select(u => u.Id), Is.EquivalentTo(friendships.Select(f => f.Id)));
|
||
}
|
||
|
||
[Test]
|
||
public void GetIncomingRequestsAsync_ThrowsInvalidOperationException_WhenUserNotFound()
|
||
{
|
||
// Arrange
|
||
var userId = Guid.NewGuid();
|
||
|
||
_friendshipsRepositoryMock
|
||
.Setup(r => r.FindByUserIdAsync(userId))
|
||
.ThrowsAsync(new NotFoundByKeyException<Guid>(userId));
|
||
|
||
// Act & Assert
|
||
Assert.ThrowsAsync<InvalidOperationException>(async () =>
|
||
await _service.GetIncomingRequestsAsync(userId));
|
||
}
|
||
} |