- Added debug middleware for /connect/* endpoints to log request and response details for better troubleshooting. - Updated OAuth2 configuration to include "offline_access" scope and disabled access token encryption for development. - Improved DbContext registration in tests by removing all related registrations and ensuring in-memory database setup for testing purposes. - Addressed issues with the /connect/token endpoint not responding, outlining next steps for debugging and fixing the OpenIddict configuration.
180 lines
5.4 KiB
C#
180 lines
5.4 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Xunit;
|
|
using IamService.API.Application.Commands.Auth;
|
|
using IamService.API.Application.Common;
|
|
using IamService.Domain.AggregatesModel.UserAggregate;
|
|
|
|
namespace IamService.FunctionalTests.Controllers;
|
|
|
|
/// <summary>
|
|
/// EN: Functional tests for AuthController endpoints.
|
|
/// VI: Functional tests cho các endpoints của AuthController.
|
|
/// </summary>
|
|
public class AuthControllerTests : IClassFixture<CustomWebApplicationFactory>
|
|
{
|
|
private readonly HttpClient _client;
|
|
private readonly CustomWebApplicationFactory _factory;
|
|
|
|
public AuthControllerTests(CustomWebApplicationFactory factory)
|
|
{
|
|
_factory = factory;
|
|
_client = factory.CreateClient(new WebApplicationFactoryClientOptions
|
|
{
|
|
AllowAutoRedirect = false
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Register_WithValidData_ShouldReturn201()
|
|
{
|
|
// Arrange
|
|
var request = new RegisterUserCommand(
|
|
$"test_{Guid.NewGuid()}@example.com",
|
|
"Password123!",
|
|
"John",
|
|
"Doe");
|
|
|
|
// Act
|
|
var response = await _client.PostAsJsonAsync("/api/v1/auth/register", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
|
|
|
|
var result = await response.Content.ReadFromJsonAsync<ApiResponse<RegisterUserCommandResult>>();
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.Data);
|
|
Assert.Equal(request.Email, result.Data.Email);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Register_WithInvalidEmail_ShouldReturn400()
|
|
{
|
|
// Arrange
|
|
var request = new
|
|
{
|
|
Email = "invalid-email",
|
|
Password = "Password123!",
|
|
FirstName = "John",
|
|
LastName = "Doe"
|
|
};
|
|
|
|
// Act
|
|
var response = await _client.PostAsJsonAsync("/api/v1/auth/register", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Register_WithWeakPassword_ShouldReturn400()
|
|
{
|
|
// Arrange
|
|
var request = new
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "weak",
|
|
FirstName = "John",
|
|
LastName = "Doe"
|
|
};
|
|
|
|
// Act
|
|
var response = await _client.PostAsJsonAsync("/api/v1/auth/register", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Register_WithDuplicateEmail_ShouldReturn409()
|
|
{
|
|
// Arrange
|
|
var email = $"duplicate_{Guid.NewGuid()}@example.com";
|
|
var request = new RegisterUserCommand(email, "Password123!", "John", "Doe");
|
|
|
|
// First registration
|
|
await _client.PostAsJsonAsync("/api/v1/auth/register", request);
|
|
|
|
// Act - Second registration with same email
|
|
var response = await _client.PostAsJsonAsync("/api/v1/auth/register", request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Token_WithValidCredentials_ShouldReturnTokens()
|
|
{
|
|
// Arrange - Register user first
|
|
var email = $"login_{Guid.NewGuid()}@example.com";
|
|
var password = "Password123!";
|
|
|
|
await _client.PostAsJsonAsync("/api/v1/auth/register", new
|
|
{
|
|
Email = email,
|
|
Password = password,
|
|
FirstName = "Login",
|
|
LastName = "Test"
|
|
});
|
|
|
|
// Activate user (in real scenario, need to verify email first)
|
|
using var scope = _factory.Services.CreateScope();
|
|
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
|
var user = await userManager.FindByEmailAsync(email);
|
|
if (user != null)
|
|
{
|
|
user.Activate();
|
|
await userManager.UpdateAsync(user);
|
|
}
|
|
|
|
// Act - Login
|
|
var tokenRequest = new FormUrlEncodedContent(new Dictionary<string, string>
|
|
{
|
|
["grant_type"] = "password",
|
|
["username"] = email,
|
|
["password"] = password,
|
|
["scope"] = "openid profile email offline_access"
|
|
});
|
|
|
|
var response = await _client.PostAsync("/connect/token", tokenRequest);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
var result = await response.Content.ReadFromJsonAsync<TokenResponse>();
|
|
Assert.NotNull(result);
|
|
Assert.NotEmpty(result.access_token);
|
|
Assert.Equal("Bearer", result.token_type);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Token_WithInvalidCredentials_ShouldReturn400()
|
|
{
|
|
// Arrange
|
|
var tokenRequest = new FormUrlEncodedContent(new Dictionary<string, string>
|
|
{
|
|
["grant_type"] = "password",
|
|
["username"] = "nonexistent@example.com",
|
|
["password"] = "WrongPassword123!",
|
|
["scope"] = "openid"
|
|
});
|
|
|
|
// Act
|
|
var response = await _client.PostAsync("/connect/token", tokenRequest);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
private record TokenResponse(
|
|
string access_token,
|
|
string token_type,
|
|
int expires_in,
|
|
string? refresh_token,
|
|
string? scope);
|
|
}
|