2024-11-18 05:05:52 +01:00
|
|
|
|
using Guestbooky.API.Configurations;
|
|
|
|
|
using Guestbooky.API.Controllers;
|
2024-10-05 00:27:04 +02:00
|
|
|
|
using Guestbooky.API.DTOs.Auth;
|
|
|
|
|
using Guestbooky.Application.UseCases.AuthenticateUser;
|
|
|
|
|
using Guestbooky.Application.UseCases.RefreshToken;
|
|
|
|
|
using MediatR;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Moq;
|
|
|
|
|
using System.Net;
|
|
|
|
|
|
|
|
|
|
namespace Guestbooky.UnitTests.API.Controllers;
|
|
|
|
|
|
|
|
|
|
public class AuthControllerTests
|
|
|
|
|
{
|
|
|
|
|
private readonly Mock<IMediator> _mediatorMock;
|
|
|
|
|
private readonly Mock<ILogger<AuthController>> _loggerMock;
|
2024-11-18 05:05:52 +01:00
|
|
|
|
private readonly APISettings _settings;
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
public AuthControllerTests()
|
|
|
|
|
{
|
|
|
|
|
_mediatorMock = new Mock<IMediator>();
|
|
|
|
|
_loggerMock = new Mock<ILogger<AuthController>>();
|
2024-11-18 05:05:52 +01:00
|
|
|
|
_settings = new APISettings() { RunningEnvironment = Guestbooky.API.Enums.RunningEnvironment.Development };
|
2024-10-05 00:27:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task Login_ReturnsOk_WhenAuthenticated()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
2024-11-18 05:05:52 +01:00
|
|
|
|
var httpContextMock = new Mock<HttpContext>();
|
|
|
|
|
var httpResponseMock = new Mock<HttpResponse>();
|
|
|
|
|
var headers = new HeaderDictionary();
|
|
|
|
|
var cookies = new Mock<IResponseCookies>();
|
|
|
|
|
|
|
|
|
|
httpResponseMock.SetupProperty(r => r.StatusCode);
|
|
|
|
|
httpResponseMock.SetupGet(r => r.Headers).Returns(headers);
|
|
|
|
|
httpResponseMock.SetupGet(r => r.Cookies).Returns(cookies.Object);
|
|
|
|
|
httpContextMock.SetupGet(h => h.Response).Returns(httpResponseMock.Object);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var controller = new AuthController(_mediatorMock.Object, _loggerMock.Object, _settings)
|
|
|
|
|
{
|
|
|
|
|
ControllerContext = new ControllerContext()
|
|
|
|
|
{
|
|
|
|
|
HttpContext = httpContextMock.Object
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
var requestDto = new LoginRequestDto("testuser", "password");
|
|
|
|
|
|
|
|
|
|
_mediatorMock.Setup(m => m.Send(It.IsAny<AuthenticateUserCommand>(), default))
|
|
|
|
|
.ReturnsAsync(new AuthenticateUserResult(true, "testToken", "testRefreshToken"));
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await controller.Login(requestDto, default);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
2024-11-18 05:05:52 +01:00
|
|
|
|
|
2024-10-05 00:27:04 +02:00
|
|
|
|
var responseDto = Assert.IsType<LoginResponseDto>(okResult.Value);
|
2024-11-18 05:05:52 +01:00
|
|
|
|
cookies.Verify(c => c.Append("token", It.IsAny<string>(), It.IsAny<CookieOptions>()), Times.Once);
|
2024-10-05 00:27:04 +02:00
|
|
|
|
Assert.Equal("testToken", responseDto.Token);
|
|
|
|
|
Assert.Equal("testRefreshToken", responseDto.RefreshToken);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task Login_ReturnsUnauthorized_WhenNotAuthenticated()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
2024-11-18 05:05:52 +01:00
|
|
|
|
var controller = new AuthController(_mediatorMock.Object, _loggerMock.Object, _settings);
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
var requestDto = new LoginRequestDto("testuser", "wrongpassword");
|
|
|
|
|
|
|
|
|
|
_mediatorMock.Setup(m => m.Send(It.IsAny<AuthenticateUserCommand>(), default))
|
|
|
|
|
.ReturnsAsync(new AuthenticateUserResult(false, string.Empty, string.Empty));
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await controller.Login(requestDto, default);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.IsType<UnauthorizedResult>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task Login_ReturnsProblemDetails_WhenExceptionIsThrown()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
2024-11-18 05:05:52 +01:00
|
|
|
|
var controller = new AuthController(_mediatorMock.Object, _loggerMock.Object, _settings);
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
var requestDto = new LoginRequestDto("testuser", "password");
|
|
|
|
|
|
|
|
|
|
_mediatorMock.Setup(m => m.Send(It.IsAny<AuthenticateUserCommand>(), default))
|
|
|
|
|
.ThrowsAsync(new Exception());
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await controller.Login(requestDto, default);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
var objectResult = Assert.IsType<ObjectResult>(result);
|
|
|
|
|
Assert.Equal(500, objectResult.StatusCode);
|
|
|
|
|
var problemDetails = Assert.IsType<ProblemDetails>(objectResult.Value);
|
|
|
|
|
Assert.StartsWith("An error occurred on the server:", problemDetails.Detail);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task RefreshToken_ReturnsOk_WhenTokenMatches()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
2024-11-18 05:05:52 +01:00
|
|
|
|
var controller = new AuthController(_mediatorMock.Object, _loggerMock.Object, _settings);
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
var requestDto = new RefreshTokenRequestDto("refresh");
|
|
|
|
|
|
|
|
|
|
_mediatorMock.Setup(m => m.Send(It.IsAny<RefreshTokenCommand>(), default))
|
|
|
|
|
.ReturnsAsync(new RefreshTokenResult(true, "testToken", "testRefreshToken"));
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await controller.RefreshToken(requestDto, default);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
var okResult = Assert.IsType<OkObjectResult>(result);
|
|
|
|
|
var responseDto = Assert.IsType<RefreshTokenResponseDto>(okResult.Value);
|
|
|
|
|
Assert.Equal("testToken", responseDto.Token);
|
|
|
|
|
Assert.Equal("testRefreshToken", responseDto.RefreshToken);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task RefreshToken_ReturnsUnauthorized_WhenTokenNotMatched()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
2024-11-18 05:05:52 +01:00
|
|
|
|
var controller = new AuthController(_mediatorMock.Object, _loggerMock.Object, _settings);
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
var requestDto = new RefreshTokenRequestDto("refresh");
|
|
|
|
|
|
|
|
|
|
_mediatorMock.Setup(m => m.Send(It.IsAny<RefreshTokenCommand>(), default))
|
|
|
|
|
.ReturnsAsync(new RefreshTokenResult(false, string.Empty, string.Empty, "error"));
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await controller.RefreshToken(requestDto, default);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
var objectResult = Assert.IsType<UnauthorizedObjectResult>(result);
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
var problemDetails = Assert.IsType<ProblemDetails>(objectResult.Value);
|
|
|
|
|
Assert.Equal("error", problemDetails.Detail);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task RefreshToken_ReturnsProblemDetails_WhenExceptionIsThrown()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
2024-11-18 05:05:52 +01:00
|
|
|
|
var controller = new AuthController(_mediatorMock.Object, _loggerMock.Object, _settings);
|
2024-10-05 00:27:04 +02:00
|
|
|
|
|
|
|
|
|
var requestDto = new RefreshTokenRequestDto("refresh");
|
|
|
|
|
|
|
|
|
|
_mediatorMock.Setup(m => m.Send(It.IsAny<RefreshTokenCommand>(), default))
|
|
|
|
|
.ThrowsAsync(new Exception());
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await controller.RefreshToken(requestDto, default);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
var objectResult = Assert.IsType<ObjectResult>(result);
|
|
|
|
|
Assert.Equal(500, objectResult.StatusCode);
|
|
|
|
|
var problemDetails = Assert.IsType<ProblemDetails>(objectResult.Value);
|
|
|
|
|
Assert.StartsWith("An error occurred on the server:", problemDetails.Detail);
|
|
|
|
|
}
|
|
|
|
|
}
|