dotnet unit tests

This commit is contained in:
2026-06-10 23:37:08 +02:00
parent 8c5b90a961
commit 5794991b30
5 changed files with 426 additions and 0 deletions
@@ -134,6 +134,28 @@ public class AuthenticationServiceTests
Assert.Equal(AuthError.UserNotFound, result.Error);
}
[Fact]
public async Task LoginAsync_ShouldReturnFailure_WhenPasswordIsWrong()
{
var password = "ValidP@ss1!";
var user = new User
{
Id = 1,
Username = "testuser",
Email = "test@example.com",
Password = new PasswordHasher<User>().HashPassword(
new User { Username = "testuser", Email = "test@example.com", Password = password },
password)
};
var request = new LoginRequest(user.Email, "WrongPassword1!");
_userRepository.GetUserByEmailAsync(request.Email).Returns(user);
var result = await _sut.LoginAsync(request);
Assert.True(result.IsFailure);
Assert.Equal(AuthError.InvalidPassword, result.Error);
}
[Fact]
public async Task RefreshTokensAsync_ShouldReturnSuccess_WhenRefreshTokenIsValid()
{
@@ -0,0 +1,60 @@
using Application.Models;
using Application.Services;
using MailKit.Net.Smtp;
using Microsoft.Extensions.Configuration;
using MimeKit;
using NSubstitute;
namespace Application.UnitTest.Services;
public class EmailServiceTests
{
private readonly IConfiguration _configuration = Substitute.For<IConfiguration>();
private readonly ISmtpClient _smtpClient = Substitute.For<ISmtpClient>();
private readonly EmailService _sut;
public EmailServiceTests()
{
_configuration["EmailSettings:From"].Returns("sender@gmail.com");
_configuration["EmailSettings:SmtpServer"].Returns("smtp.gmail.com");
_configuration["EmailSettings:Password"].Returns("app-password");
_sut = new EmailService(_configuration, () => _smtpClient);
}
[Fact]
public void SendEmailAsync_ShouldConnectAndAuthenticate()
{
var request = new EmailRequest("recipient@example.com", "Test Subject", "<p>Hello</p>");
_sut.SendEmailAsync(request);
_smtpClient.Received(1).Connect("smtp.gmail.com", 465, true);
_smtpClient.Received(1).Authenticate("sender@gmail.com", "app-password");
_smtpClient.Received(1).Send(Arg.Any<MimeMessage>());
_smtpClient.Received(1).Disconnect(true);
}
[Fact]
public void SendEmailAsync_ShouldSendMessageWithCorrectDetails()
{
var request = new EmailRequest("recipient@example.com", "Welcome!", "<h1>Hi</h1>");
_sut.SendEmailAsync(request);
_smtpClient.Received(1).Send(Arg.Is<MimeMessage>(msg =>
msg.To.Mailboxes.Any(m => m.Address == "recipient@example.com") &&
msg.Subject == "Welcome!"));
}
[Fact]
public void SendEmailAsync_ShouldDisposeClient_AfterSending()
{
var request = new EmailRequest("recipient@example.com", "Subject", "Body");
_sut.SendEmailAsync(request);
_smtpClient.Received(1).Disconnect(true);
_smtpClient.Received(1).Dispose();
}
}
@@ -0,0 +1,170 @@
using System.IdentityModel.Tokens.Jwt;
using Application.Services;
using Domain.Entities;
using Domain.Interface;
using Microsoft.Extensions.Configuration;
using NSubstitute;
namespace Application.UnitTest.Services;
public class JwtServiceTests
{
private readonly IConfiguration _configuration = Substitute.For<IConfiguration>();
private readonly IUserRepository _userRepository = Substitute.For<IUserRepository>();
private readonly IUnitOfWork _unitOfWork = Substitute.For<IUnitOfWork>();
private readonly JwtService _sut;
public JwtServiceTests()
{
var section = Substitute.For<IConfigurationSection>();
section.Value.Returns("veryveryveryveryveryveryverysecretkey");
_configuration.GetSection("Jwt:Key").Returns(section);
_configuration["Jwt:Key"].Returns("veryveryveryveryveryveryverysecretkey");
_configuration["Jwt:Issuer"].Returns("https://localhost:7091");
_configuration["Jwt:Audience"].Returns("http://localhost:5184");
_sut = new JwtService(_configuration, _userRepository, _unitOfWork);
}
[Fact]
public async Task GenerateTokenAsync_ShouldReturnToken_WhenUserIsValid()
{
var user = new User
{
Id = 1,
Username = "testuser",
Email = "test@example.com",
Password = "hash"
};
_userRepository.GetUserRolesByEmailAsync(user.Email)
.Returns(["User"]);
var token = await _sut.GenerateTokenAsync(user);
Assert.NotNull(token);
Assert.NotEmpty(token);
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);
Assert.Equal("https://localhost:7091", jwtToken.Issuer);
Assert.Contains(jwtToken.Claims, c => c.Type == "email" && c.Value == user.Email);
Assert.Contains(jwtToken.Claims, c => c.Type == "UserId" && c.Value == "1");
Assert.Contains(jwtToken.Claims, c => c.Type == "username" && c.Value == user.Username);
Assert.Contains(jwtToken.Claims, c => c.Type == "role" && c.Value == "User");
}
[Fact]
public async Task GenerateTokenAsync_ShouldIncludeAllRoles()
{
var user = new User
{
Id = 2,
Username = "adminuser",
Email = "admin@example.com",
Password = "hash"
};
_userRepository.GetUserRolesByEmailAsync(user.Email)
.Returns(["Admin", "User"]);
var token = await _sut.GenerateTokenAsync(user);
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);
var roleClaims = jwtToken.Claims.Where(c => c.Type == "role").Select(c => c.Value).ToList();
Assert.Contains("Admin", roleClaims);
Assert.Contains("User", roleClaims);
}
[Fact]
public async Task GenerateAndSaveRefreshTokenAsync_ShouldUpdateUserAndCommit()
{
var user = new User
{
Id = 1,
Username = "testuser",
Email = "test@example.com",
Password = "hash"
};
var refreshToken = await _sut.GenerateAndSaveRefreshTokenAsync(user);
Assert.NotNull(refreshToken);
Assert.NotEmpty(refreshToken);
Assert.Equal(refreshToken, user.RefreshToken);
Assert.NotNull(user.RefreshTokenExpiryTime);
Assert.True(user.RefreshTokenExpiryTime > DateTime.UtcNow);
_userRepository.Received(1).Update(user);
await _unitOfWork.Received(1).CommitAsync();
}
[Fact]
public async Task ValidateRefreshTokenAsync_ShouldReturnNull_WhenUserNotFound()
{
_userRepository.GetUserByIdAsync(99).Returns((User?)null);
var result = await _sut.ValidateRefreshTokenAsync(99, "some-token");
Assert.Null(result);
}
[Fact]
public async Task ValidateRefreshTokenAsync_ShouldReturnNull_WhenTokenMismatch()
{
var user = new User
{
Id = 1,
Username = "testuser",
Email = "test@example.com",
Password = "hash",
RefreshToken = "stored-token",
RefreshTokenExpiryTime = DateTime.UtcNow.AddDays(1)
};
_userRepository.GetUserByIdAsync(1).Returns(user);
var result = await _sut.ValidateRefreshTokenAsync(1, "wrong-token");
Assert.Null(result);
}
[Fact]
public async Task ValidateRefreshTokenAsync_ShouldReturnNull_WhenTokenExpired()
{
var user = new User
{
Id = 1,
Username = "testuser",
Email = "test@example.com",
Password = "hash",
RefreshToken = "expired-token",
RefreshTokenExpiryTime = DateTime.UtcNow.AddDays(-1)
};
_userRepository.GetUserByIdAsync(1).Returns(user);
var result = await _sut.ValidateRefreshTokenAsync(1, "expired-token");
Assert.Null(result);
}
[Fact]
public async Task ValidateRefreshTokenAsync_ShouldReturnUser_WhenTokenValid()
{
var user = new User
{
Id = 1,
Username = "testuser",
Email = "test@example.com",
Password = "hash",
RefreshToken = "valid-token",
RefreshTokenExpiryTime = DateTime.UtcNow.AddDays(1)
};
_userRepository.GetUserByIdAsync(1).Returns(user);
var result = await _sut.ValidateRefreshTokenAsync(1, "valid-token");
Assert.NotNull(result);
Assert.Equal(1, result.Id);
}
}