using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using FluentAssertions; using NSubstitute; using Xunit; using Knot.Shared.Kernel; using Knot.Modules.Chats.Domain; using Knot.Modules.Chats.Application.Abstractions; using Knot.Modules.Chats.Application.Messages.Send; namespace Knot.Modules.Chats.UnitTests.Messages; public class SendMessageCommandHandlerTests { private readonly IChatRepository _chatRepository; private readonly IMessageRepository _messageRepository; private readonly IChatsUnitOfWork _unitOfWork; private readonly SendMessageCommandHandler _handler; public SendMessageCommandHandlerTests() { _chatRepository = Substitute.For(); _messageRepository = Substitute.For(); _unitOfWork = Substitute.For(); _handler = new SendMessageCommandHandler(_chatRepository, _messageRepository, _unitOfWork); } [Fact] public async Task Handle_ShouldReturnFailure_WhenChatNotFound() { // Arrange var command = new SendMessageCommand(Guid.NewGuid(), Guid.NewGuid(), "Hello", "text"); _chatRepository.GetByIdAsync(command.ChatId, Arg.Any()) .Returns((Chat)null!); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.IsFailure.Should().BeTrue(); result.Error.Code.Should().Be(ChatErrors.ChatsNotFound.Code); } [Fact] public async Task Handle_ShouldReturnFailure_WhenSenderIsNotMember() { // Arrange var chat = Chat.Create("Test", ChatType.Group); var command = new SendMessageCommand(chat.Id, Guid.NewGuid(), "Hello", "text"); _chatRepository.GetByIdAsync(command.ChatId, Arg.Any()) .Returns(chat); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.IsFailure.Should().BeTrue(); result.Error.Code.Should().Be(ChatErrors.ChatsForbidden.Code); } [Fact] public async Task Handle_ShouldCreateMessage_WhenAuthorized() { // Arrange var senderId = Guid.NewGuid(); var chat = Chat.Create("Test", ChatType.Group); chat.AddMember(senderId, ChatRole.Member); var command = new SendMessageCommand(chat.Id, senderId, "Hello", "text"); _chatRepository.GetByIdAsync(command.ChatId, Arg.Any()) .Returns(chat); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.IsSuccess.Should().BeTrue(); result.Value.Should().NotBeEmpty(); _messageRepository.Received(1).Add(Arg.Is(m => m.ChatId == chat.Id && m.SenderId == senderId && m.Content == "Hello" && m.Type == "text")); await _unitOfWork.Received(1).SaveChangesAsync(Arg.Any()); } }