- 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.
170 lines
5.3 KiB
C#
170 lines
5.3 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using System.Net.Http.Headers;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Xunit;
|
|
using IamService.API.Application.Common;
|
|
using IamService.Domain.AggregatesModel.UserAggregate;
|
|
|
|
namespace IamService.FunctionalTests.Controllers;
|
|
|
|
/// <summary>
|
|
/// EN: Functional tests for UsersController endpoints.
|
|
/// VI: Functional tests cho các endpoints của UsersController.
|
|
/// </summary>
|
|
public class UsersControllerTests : IClassFixture<CustomWebApplicationFactory>
|
|
{
|
|
private readonly HttpClient _client;
|
|
private readonly CustomWebApplicationFactory _factory;
|
|
|
|
public UsersControllerTests(CustomWebApplicationFactory factory)
|
|
{
|
|
_factory = factory;
|
|
_client = factory.CreateClient(new WebApplicationFactoryClientOptions
|
|
{
|
|
AllowAutoRedirect = false
|
|
});
|
|
}
|
|
|
|
private async Task<string> GetAccessTokenAsync()
|
|
{
|
|
// Register and login a user
|
|
var email = $"user_{Guid.NewGuid()}@example.com";
|
|
var password = "Password123!";
|
|
|
|
await _client.PostAsJsonAsync("/api/v1/auth/register", new
|
|
{
|
|
Email = email,
|
|
Password = password,
|
|
FirstName = "Test",
|
|
LastName = "User"
|
|
});
|
|
|
|
// Activate user
|
|
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);
|
|
}
|
|
|
|
// Get token
|
|
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);
|
|
var result = await response.Content.ReadFromJsonAsync<TokenResponse>();
|
|
return result?.access_token ?? throw new Exception("Failed to get token");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetUsers_WithoutAuth_ShouldReturn401()
|
|
{
|
|
// Act
|
|
var response = await _client.GetAsync("/api/v1/users");
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetUsers_WithAuth_ShouldReturn200()
|
|
{
|
|
// Arrange
|
|
var token = await GetAccessTokenAsync();
|
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
|
|
|
// Act
|
|
var response = await _client.GetAsync("/api/v1/users");
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetMe_WithAuth_ShouldReturnCurrentUser()
|
|
{
|
|
// Arrange
|
|
var token = await GetAccessTokenAsync();
|
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
|
|
|
// Act
|
|
var response = await _client.GetAsync("/api/v1/users/me");
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
var result = await response.Content.ReadFromJsonAsync<ApiResponse<CurrentUserDto>>();
|
|
Assert.NotNull(result);
|
|
Assert.True(result.Success);
|
|
Assert.NotNull(result.Data);
|
|
Assert.NotEmpty(result.Data.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetMe_WithoutAuth_ShouldReturn401()
|
|
{
|
|
// Act
|
|
var response = await _client.GetAsync("/api/v1/users/me");
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetUserById_WithValidId_ShouldReturnUser()
|
|
{
|
|
// Arrange
|
|
var email = $"getbyid_{Guid.NewGuid()}@example.com";
|
|
var password = "Password123!";
|
|
|
|
// Register user
|
|
var registerResponse = await _client.PostAsJsonAsync("/api/v1/auth/register", new
|
|
{
|
|
Email = email,
|
|
Password = password,
|
|
FirstName = "GetById",
|
|
LastName = "Test"
|
|
});
|
|
var registerResult = await registerResponse.Content.ReadFromJsonAsync<ApiResponse<RegisterResult>>();
|
|
var userId = registerResult?.Data?.UserId;
|
|
|
|
// Get auth token
|
|
var token = await GetAccessTokenAsync();
|
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
|
|
|
// Act
|
|
var response = await _client.GetAsync($"/api/v1/users/{userId}");
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetUserById_WithInvalidId_ShouldReturn404()
|
|
{
|
|
// Arrange
|
|
var token = await GetAccessTokenAsync();
|
|
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
|
var randomId = Guid.NewGuid();
|
|
|
|
// Act
|
|
var response = await _client.GetAsync($"/api/v1/users/{randomId}");
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
|
}
|
|
|
|
private record TokenResponse(string access_token, string token_type, int expires_in);
|
|
private record RegisterResult(Guid UserId, string Email);
|
|
}
|