VerifyFriendshipTests

This commit is contained in:
Artemy
2025-07-06 14:22:50 +07:00
parent bdcfd32b11
commit 89f14c134f
4 changed files with 132 additions and 18 deletions
@@ -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<ILogger<VerifyFriendship>> _mockLogger;
private Mock<IFriendshipsRepository> _mockFriendships;
private VerifyFriendship _service;
[SetUp]
public void SetUp()
{
_fixture = new Fixture();
_fixture.Behaviors
.OfType<ThrowingRecursionBehavior>()
.ToList()
.ForEach(b => _fixture.Behaviors.Remove(b));
_fixture.Behaviors.Add(new OmitOnRecursionBehavior());
_mockLogger = new Mock<ILogger<VerifyFriendship>>();
_mockFriendships = new Mock<IFriendshipsRepository>();
_service = new VerifyFriendship(_mockFriendships.Object, _mockLogger.Object);
}
// Test for VerifyAsync action
[Test]
public async Task VerifyAsync_Success()
{
// Arrange
var friendship1 = _fixture.Create<Friendship>();
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<Friendship>();
friendship1.RequesterId = Guid.Empty;
friendship1.AddresseeId = Guid.Empty;
// Act & Assert
Assert.ThrowsAsync<ArgumentException>(() => _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<Friendship>();
friendship1.Status = FriendshipStatus.Accepted;
_mockFriendships.Setup(f => f.FindByUserIdAsync(friendship1.RequesterId))
.ThrowsAsync(new NotFoundByKeyException<Guid>(friendship1.RequesterId));
// Act & Assert
Assert.ThrowsAsync<FriendshipException>(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<Friendship>();
friendship1.Status = FriendshipStatus.Accepted;
_mockFriendships.Setup(f => f.FindByUserIdAsync(friendship1.RequesterId))
.ReturnsAsync(new List<Friendship>());
// Act & Assert
Assert.ThrowsAsync<FriendshipException>(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));
}
}
@@ -6,6 +6,7 @@ using Govor.Application.Interfaces;
using Govor.Application.Interfaces.AdminsStuff; using Govor.Application.Interfaces.AdminsStuff;
using Govor.Application.Interfaces.Authentication; using Govor.Application.Interfaces.Authentication;
using Govor.Application.Interfaces.Infrastructure.Extensions; using Govor.Application.Interfaces.Infrastructure.Extensions;
using Govor.Application.Interfaces.Messages;
using Govor.Application.Services; using Govor.Application.Services;
using Govor.Core.Infrastructure.Extensions; using Govor.Core.Infrastructure.Extensions;
using Govor.Core.Infrastructure.Validators; using Govor.Core.Infrastructure.Validators;
@@ -46,6 +47,9 @@ public static class ConfigurationProgramExtensions
services.AddMemoryCache(); services.AddMemoryCache();
services.AddScoped<IPingHandlerService, PingHandlerService>(); services.AddScoped<IPingHandlerService, PingHandlerService>();
services.AddScoped<IMessageService, MessageService>();
services.AddScoped<IVerifyFriendship, VerifyFriendship>();
} }
public static void AddRepositories(this IServiceCollection services) public static void AddRepositories(this IServiceCollection services)
+5 -6
View File
@@ -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"); // 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 var originalMessageForNotification = new Message
{ {
Id = message.Id, Id = message.Id,
SenderId = message.SenderId, SenderId = message.SenderId,
RecipientId = message.RecipientId, RecipientId = message.RecipientId,
RecipientType = message.RecipientType, 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; 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 var originalMessageForNotification = new Message
{ {
Id = message.Id, Id = message.Id,
SenderId = message.SenderId, SenderId = message.SenderId,
RecipientId = message.RecipientId, RecipientId = message.RecipientId,
RecipientType = message.RecipientType, RecipientType = message.RecipientType,
// Populate other fields if necessary for the notification
}; };
await _messagesRepository.RemoveAsync(deleteParams.MessageId); 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); _logger.LogInformation("Message {MessageId} deleted successfully by user {DeleterId}", deleteParams.MessageId, deleteParams.DeleterId);
return new DeleteMessageResult(true, null, originalMessageForNotification); return new DeleteMessageResult(true, null, originalMessageForNotification);
} }
@@ -2,11 +2,11 @@ using Govor.Application.Exceptions.VerifyFriendship;
using Govor.Application.Interfaces; using Govor.Application.Interfaces;
using Govor.Core.Models; using Govor.Core.Models;
using Govor.Core.Repositories.Friendships; using Govor.Core.Repositories.Friendships;
using Govor.Data.Repositories.Exceptions;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Govor.Application.Services; namespace Govor.Application.Services;
public class VerifyFriendship : IVerifyFriendship public class VerifyFriendship : IVerifyFriendship
{ {
private readonly IFriendshipsRepository _friendshipsRepository; private readonly IFriendshipsRepository _friendshipsRepository;
@@ -21,23 +21,38 @@ public class VerifyFriendship : IVerifyFriendship
public async Task VerifyAsync(Guid targetUserId, Guid friendUserId) 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); if (targetUserId == Guid.Empty || friendUserId == Guid.Empty)
throw new ArgumentException("User IDs cannot be empty.", nameof(targetUserId)); {
_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 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<Guid> ex)
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); var errorMessage = string.Format(FriendshipNotAcceptedError, targetUserId, friendUserId);
_logger?.LogError(errorMessage); _logger?.LogError(errorMessage);
throw new FriendshipException(errorMessage); throw new FriendshipException(errorMessage);
} }
_logger?.LogInformation("Friendship verified successfully for targetUserId={TargetUserId}, friendUserId={FriendUserId}", targetUserId, friendUserId);
} }
public async Task<bool> TryVerifyAsync(Guid targetUserId, Guid friendUserId) public async Task<bool> TryVerifyAsync(Guid targetUserId, Guid friendUserId)
@@ -47,7 +62,7 @@ public class VerifyFriendship : IVerifyFriendship
await VerifyAsync(targetUserId, friendUserId); await VerifyAsync(targetUserId, friendUserId);
return true; return true;
} }
catch (FriendshipException ex) catch (Exception ex)
{ {
return false; return false;
} }