From 89f14c134fc6db422e86883e8543f72223768edc Mon Sep 17 00:00:00 2001 From: Artemy <109195690+stalcker2288969@users.noreply.github.com> Date: Sun, 6 Jul 2025 14:22:50 +0700 Subject: [PATCH] VerifyFriendshipTests --- .../Services/VerifyFriendshipTests.cs | 96 +++++++++++++++++++ .../ConfigurationProgramExtensions.cs | 4 + Govor.Application/Services/MessageService.cs | 11 +-- .../Services/VerifierFriendship.cs | 39 +++++--- 4 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 Govor.API.Tests/UnitTests/Services/VerifyFriendshipTests.cs diff --git a/Govor.API.Tests/UnitTests/Services/VerifyFriendshipTests.cs b/Govor.API.Tests/UnitTests/Services/VerifyFriendshipTests.cs new file mode 100644 index 0000000..721f69b --- /dev/null +++ b/Govor.API.Tests/UnitTests/Services/VerifyFriendshipTests.cs @@ -0,0 +1,96 @@ +using AutoFixture; +using Govor.Application.Exceptions.VerifyFriendship; +using Govor.Application.Services; +using Govor.Core.Models; +using Govor.Core.Repositories.Friendships; +using Govor.Data.Repositories.Exceptions; +using Microsoft.Extensions.Logging; +using Moq; + +namespace Govor.API.Tests.UnitTests.Services; + +[TestFixture] +public class VerifyFriendshipTests +{ + private Fixture _fixture; + private Mock> _mockLogger; + private Mock _mockFriendships; + private VerifyFriendship _service; + + [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>(); + _mockFriendships = new Mock(); + + _service = new VerifyFriendship(_mockFriendships.Object, _mockLogger.Object); + } + + // Test for VerifyAsync action + [Test] + public async Task VerifyAsync_Success() + { + // Arrange + var friendship1 = _fixture.Create(); + friendship1.Status = FriendshipStatus.Accepted; + _mockFriendships.Setup(f => f.FindByUserIdAsync(friendship1.RequesterId)) + .ReturnsAsync([friendship1]); + // Act + await _service.VerifyAsync(friendship1.RequesterId, friendship1.AddresseeId); + // Assert + _mockFriendships.Verify(f => f.FindByUserIdAsync(friendship1.RequesterId), Times.Once()); + Assert.That(await _service.TryVerifyAsync(friendship1.RequesterId, friendship1.AddresseeId), Is.EqualTo(true)); + } + + [Test] + public async Task VerifyAsync_IDsEmpty() + { + // Arrange + var friendship1 = _fixture.Create(); + friendship1.RequesterId = Guid.Empty; + friendship1.AddresseeId = Guid.Empty; + + // Act & Assert + Assert.ThrowsAsync(() => _service.VerifyAsync(friendship1.RequesterId, friendship1.AddresseeId)); + Assert.That(await _service.TryVerifyAsync(friendship1.RequesterId, friendship1.AddresseeId), Is.EqualTo(false)); + } + + [Test] + public async Task VerifyAsync_ThrowsNotFoundByKeyException_ThrowsFriendshipException() + { + // Arrange + var friendship1 = _fixture.Create(); + friendship1.Status = FriendshipStatus.Accepted; + + _mockFriendships.Setup(f => f.FindByUserIdAsync(friendship1.RequesterId)) + .ThrowsAsync(new NotFoundByKeyException(friendship1.RequesterId)); + + // Act & Assert + Assert.ThrowsAsync(async () => await _service.VerifyAsync(friendship1.RequesterId, friendship1.AddresseeId)); + _mockFriendships.Verify(f => f.FindByUserIdAsync(friendship1.RequesterId), Times.Once()); + Assert.That(await _service.TryVerifyAsync(friendship1.RequesterId, friendship1.AddresseeId), Is.EqualTo(false)); + } + + [Test] + public async Task VerifyAsync_ReturnsEmptyFriendships_ThrowsFriendshipException() + { + // Arrange + var friendship1 = _fixture.Create(); + friendship1.Status = FriendshipStatus.Accepted; + + _mockFriendships.Setup(f => f.FindByUserIdAsync(friendship1.RequesterId)) + .ReturnsAsync(new List()); + + // Act & Assert + Assert.ThrowsAsync(async () => await _service.VerifyAsync(friendship1.RequesterId, friendship1.AddresseeId)); + _mockFriendships.Verify(f => f.FindByUserIdAsync(friendship1.RequesterId), Times.Once()); + Assert.That(await _service.TryVerifyAsync(friendship1.RequesterId, friendship1.AddresseeId), Is.EqualTo(false)); + } +} \ No newline at end of file diff --git a/Govor.API/Extensions/ConfigurationProgramExtensions.cs b/Govor.API/Extensions/ConfigurationProgramExtensions.cs index 15281fe..985c5b7 100644 --- a/Govor.API/Extensions/ConfigurationProgramExtensions.cs +++ b/Govor.API/Extensions/ConfigurationProgramExtensions.cs @@ -6,6 +6,7 @@ using Govor.Application.Interfaces; using Govor.Application.Interfaces.AdminsStuff; using Govor.Application.Interfaces.Authentication; using Govor.Application.Interfaces.Infrastructure.Extensions; +using Govor.Application.Interfaces.Messages; using Govor.Application.Services; using Govor.Core.Infrastructure.Extensions; using Govor.Core.Infrastructure.Validators; @@ -46,6 +47,9 @@ public static class ConfigurationProgramExtensions services.AddMemoryCache(); services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); } public static void AddRepositories(this IServiceCollection services) diff --git a/Govor.Application/Services/MessageService.cs b/Govor.Application/Services/MessageService.cs index 7131404..d423fdb 100644 --- a/Govor.Application/Services/MessageService.cs +++ b/Govor.Application/Services/MessageService.cs @@ -114,14 +114,17 @@ public class MessageService : IMessageService // TODO: Add a time limit for editing messages? e.g., if (message.SentAt < DateTime.UtcNow.AddMinutes(-15)) throw new Exception("Edit time limit exceeded"); - // Keep a copy of the original message state for the result, if needed by Hub for notifications var originalMessageForNotification = new Message { Id = message.Id, SenderId = message.SenderId, RecipientId = message.RecipientId, RecipientType = message.RecipientType, - // Populate other fields if necessary for the notification + SentAt = message.SentAt, + ReplyToMessageId = message.ReplyToMessageId, + Reactions = message.Reactions, + MediaAttachments = message.MediaAttachments, + MessageViews = message.MessageViews, }; message.EncryptedContent = editParams.NewContent; @@ -160,20 +163,16 @@ public class MessageService : IMessageService // } } - // Keep a copy of the original message state for the result, if needed by Hub for notifications var originalMessageForNotification = new Message { Id = message.Id, SenderId = message.SenderId, RecipientId = message.RecipientId, RecipientType = message.RecipientType, - // Populate other fields if necessary for the notification }; await _messagesRepository.RemoveAsync(deleteParams.MessageId); - // TODO: Delete associated media attachments from storage if they are no longer referenced. - _logger.LogInformation("Message {MessageId} deleted successfully by user {DeleterId}", deleteParams.MessageId, deleteParams.DeleterId); return new DeleteMessageResult(true, null, originalMessageForNotification); } diff --git a/Govor.Application/Services/VerifierFriendship.cs b/Govor.Application/Services/VerifierFriendship.cs index 9729110..7fc3c1a 100644 --- a/Govor.Application/Services/VerifierFriendship.cs +++ b/Govor.Application/Services/VerifierFriendship.cs @@ -2,11 +2,11 @@ using Govor.Application.Exceptions.VerifyFriendship; using Govor.Application.Interfaces; using Govor.Core.Models; using Govor.Core.Repositories.Friendships; +using Govor.Data.Repositories.Exceptions; using Microsoft.Extensions.Logging; namespace Govor.Application.Services; - public class VerifyFriendship : IVerifyFriendship { private readonly IFriendshipsRepository _friendshipsRepository; @@ -21,23 +21,38 @@ public class VerifyFriendship : IVerifyFriendship public async Task VerifyAsync(Guid targetUserId, Guid friendUserId) { - if (targetUserId == Guid.Empty || friendUserId == Guid.Empty) + try { - _logger?.LogWarning("Invalid user IDs provided: targetUserId={TargetUserId}, friendUserId={FriendUserId}", targetUserId, friendUserId); - throw new ArgumentException("User IDs cannot be empty.", nameof(targetUserId)); - } + if (targetUserId == Guid.Empty || friendUserId == Guid.Empty) + { + _logger?.LogWarning( + "Invalid user IDs provided: targetUserId={TargetUserId}, friendUserId={FriendUserId}", targetUserId, + friendUserId); + throw new ArgumentException("User IDs cannot be empty.", nameof(targetUserId)); + } - var friendships = await _friendshipsRepository.FindByUserIdAsync(targetUserId); - var friendship = friendships.Where(f => f.AddresseeId == friendUserId || f.RequesterId == friendUserId)?.FirstOrDefault(); - - if (friendship == null || friendship.Status != FriendshipStatus.Accepted) + var friendships = await _friendshipsRepository.FindByUserIdAsync(targetUserId); + var friendship = friendships.Where(f => f.AddresseeId == friendUserId || f.RequesterId == friendUserId) + ?.FirstOrDefault(); + + if (friendship == null || friendship.Status != FriendshipStatus.Accepted) + { + var errorMessage = string.Format(FriendshipNotAcceptedError, targetUserId, friendUserId); + _logger?.LogError(errorMessage); + throw new FriendshipException(errorMessage); + } + + _logger?.LogInformation( + "Friendship verified successfully for targetUserId={TargetUserId}, friendUserId={FriendUserId}", + targetUserId, friendUserId); + } + catch (NotFoundByKeyException ex) { var errorMessage = string.Format(FriendshipNotAcceptedError, targetUserId, friendUserId); _logger?.LogError(errorMessage); + throw new FriendshipException(errorMessage); } - - _logger?.LogInformation("Friendship verified successfully for targetUserId={TargetUserId}, friendUserId={FriendUserId}", targetUserId, friendUserId); } public async Task TryVerifyAsync(Guid targetUserId, Guid friendUserId) @@ -47,7 +62,7 @@ public class VerifyFriendship : IVerifyFriendship await VerifyAsync(targetUserId, friendUserId); return true; } - catch (FriendshipException ex) + catch (Exception ex) { return false; }