Files
pos-system/services/iam-service-net/tests/IamService.FunctionalTests/Controllers/AuthControllerTests.cs
Ho Ngoc Hai 079b24f683 feat(api): Enhance OAuth2 token endpoint and debugging capabilities
- 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.
2026-01-12 18:22:47 +07:00

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);
}