diff --git a/Govor.API.Tests/UnitTests/Services/FriendsServiceTests.cs b/Govor.API.Tests/UnitTests/Services/FriendsServiceTests.cs new file mode 100644 index 0000000..407bfba --- /dev/null +++ b/Govor.API.Tests/UnitTests/Services/FriendsServiceTests.cs @@ -0,0 +1,177 @@ +using AutoFixture; +using Govor.Application.Exceptions.FriendsService; +using Govor.Application.Interfaces; +using Govor.Application.Services; +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; + +[TestFixture] +public class FriendsServiceTests +{ + private Fixture _fixture; + private Mock _usersRepositoryMock; + private Mock _friendshipsRepositoryMock; + private IFriendsService _service; + + [SetUp] + public void SetUp() + { + _fixture = new Fixture(); + _fixture.Behaviors + .OfType() + .ToList() + .ForEach(b => _fixture.Behaviors.Remove(b)); + _fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + _usersRepositoryMock = new Mock(); + _friendshipsRepositoryMock = new Mock(); + + _service = new FriendsService(_usersRepositoryMock.Object, _friendshipsRepositoryMock.Object); + } + + // SearchUsersAsync + [Test] + public async Task SearchUsersAsync_ReturnsUsers_IfNotAlreadyFriends() + { + // Arrange + var userId = _fixture.Create(); + var user = _fixture.Create(); + user.Id = Guid.NewGuid(); + + _usersRepositoryMock + .Setup(u => u.SearchPotentialFriendsAsync(userId, It.IsAny())) + .ReturnsAsync(new List { user }); + + _friendshipsRepositoryMock + .Setup(f => f.FindByUserIdAsync(userId)) + .ReturnsAsync(new List()); // No friends + + // Act + var result = await _service.SearchUsersAsync("test", userId); + + // Assert + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0].Id, Is.EqualTo(user.Id)); + } + + [Test] + public void SearchUsersAsync_Throws_SearchUsersException_IfThrowsNotFoundByKeyException_String_Guid() + { + // Arrange + _usersRepositoryMock + .Setup(u => u.SearchPotentialFriendsAsync(It.IsAny(), It.IsAny())) + .ThrowsAsync(new NotFoundByKeyException<(string,Guid)>(("test",Guid.NewGuid()),"test")); + + // Axt & Assert + Assert.ThrowsAsync(async () => await _service.SearchUsersAsync("test", Guid.NewGuid())); + } + + [Test] + public async Task SearchUsersAsync_ReturnsUsersWithoutFriendships_IfThrowsNotFoundByKeyException_Guid() + { + // Arrange + var userId = _fixture.Create(); + var user = _fixture.Create(); + user.Id = Guid.NewGuid(); + + _usersRepositoryMock + .Setup(u => u.SearchPotentialFriendsAsync(userId, It.IsAny())) + .ReturnsAsync(new List { user }); + + _friendshipsRepositoryMock + .Setup(f => f.FindByUserIdAsync(userId)) + .ThrowsAsync(new NotFoundByKeyException(userId, "test")); + + // Act + var result = await _service.SearchUsersAsync("test", userId); + + // Assert + Assert.That(result, Has.Count.EqualTo(1)); + Assert.That(result[0].Id, Is.EqualTo(user.Id)); + } + + [Test] + public async Task SearchUsersAsync_Throws_UnauthorizedAccessException_IfThrowsSomeExceptionInUsersRepository() + { + // Arrange + _usersRepositoryMock + .Setup(u => u.SearchPotentialFriendsAsync(It.IsAny(), It.IsAny())) + .ThrowsAsync(new Exception("test")); + + // Act & Assert + Assert.ThrowsAsync(async () => await _service.SearchUsersAsync("test", Guid.NewGuid())); + } + + [Test] + public async Task SearchUsersAsync_Throws_UnauthorizedAccessException_IfThrowsSomeExceptionInFriendshipsRepository() + { + // Arrange + _friendshipsRepositoryMock + .Setup(u => u.FindByUserIdAsync(It.IsAny())) + .ThrowsAsync(new Exception("test")); + + // Act & Assert + Assert.ThrowsAsync(async () => await _service.SearchUsersAsync("test", Guid.NewGuid())); + } + + // SendFriendRequestAsync + + [Test] + public void SendFriendRequestAsync_SendingToSelf_ThrowsInvalidOperationException() + { + // Arrange + var userId = Guid.NewGuid(); + + // Act + Assert + var ex = Assert.ThrowsAsync(() => + _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(() => + _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(f => + f.RequesterId == fromUserId && + f.AddresseeId == toUserId && + f.Status == FriendshipStatus.Pending && + f.Id != Guid.Empty + )), + Times.Once); + } +}