110 lines
3.3 KiB
C#
110 lines
3.3 KiB
C#
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
using Microsoft.AspNetCore.TestHost;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Shogi.BackEnd.Identity;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
|
|
namespace Shogi.AcceptanceTests.TestSetup;
|
|
|
|
/// <summary>
|
|
/// Integration test fixture using WebApplicationFactory for in-process testing.
|
|
/// </summary>
|
|
public class AatTestFixture : WebApplicationFactory<Program>, IAsyncLifetime
|
|
{
|
|
protected static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
|
|
|
|
private const string TestPassword = "TestPassword123!";
|
|
|
|
public HttpClient HttpClient { get; private set; } = null!;
|
|
public HttpClient OtherHttpClient { get; private set; } = null!;
|
|
|
|
protected override void ConfigureWebHost(IWebHostBuilder builder)
|
|
{
|
|
builder.UseEnvironment("Development");
|
|
|
|
builder.ConfigureTestServices(services =>
|
|
{
|
|
// Remove all EF Core and database provider related services
|
|
var descriptorsToRemove = services
|
|
.Where(d => d.ServiceType.Namespace != null &&
|
|
(d.ServiceType.Namespace.StartsWith("Microsoft.EntityFrameworkCore") ||
|
|
d.ServiceType == typeof(ApplicationDbContext) ||
|
|
d.ServiceType == typeof(DbContextOptions<ApplicationDbContext>)))
|
|
.ToList();
|
|
|
|
foreach (var descriptor in descriptorsToRemove)
|
|
{
|
|
services.Remove(descriptor);
|
|
}
|
|
|
|
// Add DbContext with InMemory database
|
|
services.AddDbContext<ApplicationDbContext>(options =>
|
|
options.UseInMemoryDatabase("IntegrationTestDb_" + Guid.NewGuid().ToString()));
|
|
});
|
|
}
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
this.HttpClient = this.CreateClient();
|
|
this.OtherHttpClient = this.CreateClient();
|
|
|
|
// Ensure the in-memory database is created
|
|
using (var scope = this.Services.CreateScope())
|
|
{
|
|
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
|
await db.Database.EnsureCreatedAsync();
|
|
}
|
|
|
|
await this.SetupTestAccountsAndLogin();
|
|
}
|
|
|
|
private async Task SetupTestAccountsAndLogin()
|
|
{
|
|
// Register and login first test account
|
|
await RegisterAndLogin(this.HttpClient, "aat-account@test.com", TestPassword);
|
|
|
|
// Register and login second test account
|
|
await RegisterAndLogin(this.OtherHttpClient, "aat-account-2@test.com", TestPassword);
|
|
}
|
|
|
|
private static async Task RegisterAndLogin(HttpClient client, string email, string password)
|
|
{
|
|
// Try to register (may already exist)
|
|
await client.PostAsJsonAsync(
|
|
new Uri("register", UriKind.Relative),
|
|
new { email, password },
|
|
options: SerializerOptions);
|
|
|
|
// Login
|
|
var loginResponse = await client.PostAsJsonAsync(
|
|
new Uri("login", UriKind.Relative),
|
|
new { email, password },
|
|
options: SerializerOptions);
|
|
|
|
if (loginResponse.IsSuccessStatusCode)
|
|
{
|
|
var tokenResponse = await loginResponse.Content.ReadFromJsonAsync<LoginResponse>(SerializerOptions);
|
|
if (tokenResponse?.AccessToken != null)
|
|
{
|
|
client.DefaultRequestHeaders.Authorization =
|
|
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
|
|
}
|
|
}
|
|
}
|
|
|
|
async Task IAsyncLifetime.DisposeAsync()
|
|
{
|
|
this.HttpClient?.Dispose();
|
|
this.OtherHttpClient?.Dispose();
|
|
await base.DisposeAsync();
|
|
}
|
|
|
|
private class LoginResponse
|
|
{
|
|
public string AccessToken { get; set; } = string.Empty;
|
|
}
|
|
}
|