using LANCommander.SDK.Abstractions; using LANCommander.SDK.Extensions; using LANCommander.SDK.Providers; using LANCommander.SDK.Services; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.DependencyInjection; namespace LANCommander.Server.Tests; public class ApplicationFixture : ApplicationFactory { public static ApplicationFixture Instance; /// Server-side service provider (the in-memory app under test). public IServiceProvider ServiceProvider { get; set; } /// Client-side SDK service provider, wired to talk to the in-memory server. public IServiceProvider ClientServiceProvider { get; set; } /// HttpClient whose handler routes to the in-memory server. public HttpClient HttpClient { get; } public Uri ServerAddress { get; } public AuthenticationClient AuthenticationClient { get; } public GameClient GameClient { get; } public SaveClient SaveClient { get; } public TagClient TagClient { get; } public ApplicationFixture(ApplicationFactory factory) { if (Instance != null) return; ServiceProvider = factory.Services; HttpClient = factory.CreateClient(); ServerAddress = HttpClient.BaseAddress!; // Build a separate SDK client container (mirrors the launcher's composition) whose // injected HttpClient is the in-memory test handler, so all API calls route to the // server under test instead of hitting the network. var services = new ServiceCollection(); services.AddLogging(); services.AddOptions().Configure(_ => { }); services.AddSingleton(NoopRefresher.Instance); services.AddLANCommanderClient(); services.AddSingleton(HttpClient); ClientServiceProvider = services.BuildServiceProvider(); ClientServiceProvider.GetRequiredService().SetServerAddress(ServerAddress); AuthenticationClient = ClientServiceProvider.GetRequiredService(); GameClient = ClientServiceProvider.GetRequiredService(); SaveClient = ClientServiceProvider.GetRequiredService(); TagClient = ClientServiceProvider.GetRequiredService(); Instance = this; } /// Authenticates against the in-memory server and stores the token for subsequent client calls. public Task AuthenticateAsync(string username, string password) => AuthenticationClient.AuthenticateAsync(username, password, ServerAddress); private sealed class NoopRefresher : IServerConfigurationRefresher { public static readonly NoopRefresher Instance = new(); public Task RefreshAsync(CancellationToken cancellationToken = default) => Task.CompletedTask; } } [CollectionDefinition("Application")] public class ApplicationCollection : ICollectionFixture> { }