using FluentAssertions; using NSubstitute; using Knot.Modules.Identity.Application.Abstractions; using Knot.Modules.Identity.Application.Users.Login; using Knot.Modules.Identity.Domain; using Knot.Shared.Kernel; using Knot.Modules.Identity.Application.Users.Auth; using Xunit; using System.Threading; using System.Threading.Tasks; namespace Knot.Modules.Identity.UnitTests; public class LoginUserCommandHandlerTests { private readonly IUserRepository _userRepository; private readonly IJwtTokenProvider _tokenProvider; private readonly LoginUserCommandHandler _handler; public LoginUserCommandHandlerTests() { _userRepository = Substitute.For(); _tokenProvider = Substitute.For(); _handler = new LoginUserCommandHandler(_userRepository, _tokenProvider); } [Fact] public async Task Handle_ShouldReturnToken_WhenCredentialsAreValid() { // Arrange var password = "password123"; var passwordHash = BCrypt.Net.BCrypt.HashPassword(password); var user = User.Create("testuser", passwordHash, "Test User", null, null); var command = new LoginUserCommand("testuser", password); _userRepository.GetByUsernameAsync(command.Username, Arg.Any()) .Returns(user); _tokenProvider.Generate(user).Returns("valid-jwt-token"); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.IsSuccess.Should().BeTrue(); result.Value.Token.Should().Be("valid-jwt-token"); result.Value.User.Username.Should().Be("testuser"); } [Fact] public async Task Handle_ShouldReturnFailure_WhenUserDoesNotExist() { // Arrange var command = new LoginUserCommand("nonexistent", "password123"); _userRepository.GetByUsernameAsync(command.Username, Arg.Any()) .Returns((User)null!); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.IsFailure.Should().BeTrue(); result.Error.Code.Should().Be(IdentityErrors.IdentityInvalidCredentials.Code); } [Fact] public async Task Handle_ShouldReturnFailure_WhenPasswordIsInvalid() { // Arrange var correctPassword = "correctPassword"; var passwordHash = BCrypt.Net.BCrypt.HashPassword(correctPassword); var user = User.Create("testuser", passwordHash, "Test User", null, null); var command = new LoginUserCommand("testuser", "wrongPassword"); _userRepository.GetByUsernameAsync(command.Username, Arg.Any()) .Returns(user); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.IsFailure.Should().BeTrue(); result.Error.Code.Should().Be(IdentityErrors.IdentityInvalidCredentials.Code); } }