Add initial implementation of API, database, and user management components.
This commit is contained in:
104
MikrocopTests/AuthServiceTests.cs
Normal file
104
MikrocopTests/AuthServiceTests.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using MikrocopApi.Dtos;
|
||||
using MikrocopApi.Exceptions;
|
||||
using MikrocopApi.Services;
|
||||
using MikrocopDb.Entities;
|
||||
using MikrocopDb.Repositories;
|
||||
using Moq;
|
||||
|
||||
namespace MikrocopTests;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class AuthServiceTests
|
||||
{
|
||||
[Test]
|
||||
public async Task LoginAsync_ReturnsToken_WhenCredentialsAreValid()
|
||||
{
|
||||
var user = CreateUser();
|
||||
var repositoryMock = new Mock<IUserRepository>(MockBehavior.Strict);
|
||||
var hashingServiceMock = new Mock<IPasswordHashingService>(MockBehavior.Strict);
|
||||
var jwtTokenServiceMock = new Mock<IJwtTokenService>(MockBehavior.Strict);
|
||||
var request = new LoginRequestDto { UserName = user.UserName, Password = "ValidPassword!123" };
|
||||
var expectedExpiry = DateTime.UtcNow.AddHours(1);
|
||||
|
||||
repositoryMock
|
||||
.Setup(x => x.GetByUserNameAsync(request.UserName, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(user);
|
||||
hashingServiceMock
|
||||
.Setup(x => x.VerifyPassword(request.Password, user.PasswordHash, user.PasswordSalt))
|
||||
.Returns(true);
|
||||
jwtTokenServiceMock
|
||||
.Setup(x => x.Generate(user))
|
||||
.Returns(("token-value", expectedExpiry));
|
||||
|
||||
var sut = new AuthService(repositoryMock.Object, hashingServiceMock.Object, jwtTokenServiceMock.Object);
|
||||
|
||||
var result = await sut.LoginAsync(request);
|
||||
|
||||
Assert.That(result.AccessToken, Is.EqualTo("token-value"));
|
||||
Assert.That(result.ExpiresAtUtc, Is.EqualTo(expectedExpiry));
|
||||
Assert.That(result.TokenType, Is.EqualTo("Bearer"));
|
||||
repositoryMock.VerifyAll();
|
||||
hashingServiceMock.VerifyAll();
|
||||
jwtTokenServiceMock.VerifyAll();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoginAsync_ThrowsUnauthorized_WhenUserDoesNotExist()
|
||||
{
|
||||
var repositoryMock = new Mock<IUserRepository>(MockBehavior.Strict);
|
||||
var hashingServiceMock = new Mock<IPasswordHashingService>(MockBehavior.Strict);
|
||||
var jwtTokenServiceMock = new Mock<IJwtTokenService>(MockBehavior.Strict);
|
||||
var request = new LoginRequestDto { UserName = "missing", Password = "ValidPassword!123" };
|
||||
|
||||
repositoryMock
|
||||
.Setup(x => x.GetByUserNameAsync(request.UserName, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync((UserEntity?)null);
|
||||
|
||||
var sut = new AuthService(repositoryMock.Object, hashingServiceMock.Object, jwtTokenServiceMock.Object);
|
||||
|
||||
Assert.ThrowsAsync<UnauthorizedException>(() => sut.LoginAsync(request));
|
||||
repositoryMock.VerifyAll();
|
||||
hashingServiceMock.VerifyNoOtherCalls();
|
||||
jwtTokenServiceMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoginAsync_ThrowsUnauthorized_WhenPasswordIsInvalid()
|
||||
{
|
||||
var user = CreateUser();
|
||||
var repositoryMock = new Mock<IUserRepository>(MockBehavior.Strict);
|
||||
var hashingServiceMock = new Mock<IPasswordHashingService>(MockBehavior.Strict);
|
||||
var jwtTokenServiceMock = new Mock<IJwtTokenService>(MockBehavior.Strict);
|
||||
var request = new LoginRequestDto { UserName = user.UserName, Password = "WrongPassword!123" };
|
||||
|
||||
repositoryMock
|
||||
.Setup(x => x.GetByUserNameAsync(request.UserName, It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(user);
|
||||
hashingServiceMock
|
||||
.Setup(x => x.VerifyPassword(request.Password, user.PasswordHash, user.PasswordSalt))
|
||||
.Returns(false);
|
||||
|
||||
var sut = new AuthService(repositoryMock.Object, hashingServiceMock.Object, jwtTokenServiceMock.Object);
|
||||
|
||||
Assert.ThrowsAsync<UnauthorizedException>(() => sut.LoginAsync(request));
|
||||
repositoryMock.VerifyAll();
|
||||
hashingServiceMock.VerifyAll();
|
||||
jwtTokenServiceMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
private static UserEntity CreateUser()
|
||||
{
|
||||
return new UserEntity
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserName = "test-user",
|
||||
FullName = "Test User",
|
||||
Email = "test@example.com",
|
||||
MobileNumber = "+38640111222",
|
||||
Language = "en",
|
||||
Culture = "en-US",
|
||||
PasswordHash = "hash",
|
||||
PasswordSalt = "salt"
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user