using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Yavsc.Tests.Shared;
namespace Yavsc.Org.Tests;
///
/// WebApplicationFactory-based fixture for integration tests that need
/// to override services registered by the production Program.
/// Uses the in-memory so tests can hit real
/// HTTP endpoints without sockets or self-signed certificates.
///
/// Currently overrides so that
/// [Authorize("AdministratorOnly")] (and any other policy
/// requiring a role) is satisfied by sending an
/// X-Test-Role: Administrator header, without a real login.
/// Also adds which installs
/// so that User.GetUserId()
/// in user code sees a logged-in identity derived from the same
/// header.
///
public class TestWebApplicationFactory : WebApplicationFactory
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
// UseEnvironment("Testing") puts the host in a dedicated
// configuration environment so AddConfiguration("org") in
// Program.Main loads the optional appsettings-org.Testing.json
// file (which overrides the connection string and SMTP section
// for the test host). See that file for the values.
// We don't use "Development" because that environment is also
// used by the dev launcher and would change the signing
// credential path in IdentityServer; "Testing" is unambiguous.
builder.UseEnvironment("Testing");
builder.ConfigureTestServices(services =>
{
// Replace the production IAuthorizationPolicyProvider with
// the test one. The default registered by AddAuthorization
// becomes irrelevant: any GetPolicyAsync call is routed here.
services.AddSingleton();
// Register the test middleware and its startup filter.
// The startup filter wraps the production pipeline so
// TestUserMiddleware runs after UseAuthentication/Authorization.
services.AddTransient();
services.AddTransient();
});
}
}