106 lines
3.0 KiB
C#
106 lines
3.0 KiB
C#
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Shogi.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.ConfigureServices(services =>
|
|
{
|
|
// Remove the existing DbContext registration
|
|
var descriptor = services.SingleOrDefault(
|
|
d => d.ServiceType == typeof(DbContextOptions<ApplicationDbContext>));
|
|
|
|
if (descriptor != null)
|
|
{
|
|
services.Remove(descriptor);
|
|
}
|
|
|
|
// Add in-memory database for testing
|
|
services.AddDbContext<ApplicationDbContext>(options =>
|
|
{
|
|
options.UseInMemoryDatabase("IntegrationTestDb_" + Guid.NewGuid().ToString());
|
|
});
|
|
|
|
// Ensure the database is created and seeded
|
|
var sp = services.BuildServiceProvider();
|
|
using var scope = sp.CreateScope();
|
|
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
|
db.Database.EnsureCreated();
|
|
});
|
|
}
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
this.HttpClient = this.CreateClient();
|
|
this.OtherHttpClient = this.CreateClient();
|
|
|
|
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;
|
|
}
|
|
}
|