using LANCommander.SDK.Enums; using LANCommander.Server.Data; using LANCommander.Server.Data.Models; using LANCommander.Server.Services; using LANCommander.Server.Settings.Enums; using Microsoft.Extensions.DependencyInjection; namespace LANCommander.Server.UI.Tests.Components; /// /// Shared fixture for bUnit component tests. Reuses the proven /// to stand up the real server dependency-injection container backed by a file-based SQLite /// database, seeds an admin user and a single test game, then exposes the real service provider so /// bUnit can resolve the server's scoped services (GameService, AntDesign, etc.) while rendering /// components in-process. /// /// Unlike this does NOT start Playwright — bUnit renders /// components synchronously in-process and needs only the DI container and seeded data. /// public class BUnitServerFixture : IAsyncLifetime { public UITestApplicationFactory Factory { get; private set; } = null!; /// /// ID of a game created via the service layer for edit component tests. /// public Guid TestGameId { get; private set; } public const string TestGameTitle = "Test Game"; public async Task InitializeAsync() { Factory = new UITestApplicationFactory(); // Trigger the factory to build the host and create the SQLite schema. _ = Factory.Services; using var scope = Factory.RealServices.CreateScope(); var roleService = scope.ServiceProvider.GetRequiredService(); var userService = scope.ServiceProvider.GetRequiredService(); await roleService.AddAsync(new Role { Name = RoleService.AdministratorRoleName }); var user = await userService.AddAsync(new User { UserName = TestConstants.AdminUserName }); await userService.ChangePassword(user.UserName, TestConstants.AdminPassword); await userService.AddToRoleAsync(user.UserName, RoleService.AdministratorRoleName); // Seed default storage locations so service initialization mirrors a real server. var storageLocationService = scope.ServiceProvider.GetRequiredService(); var archivePath = Path.Combine(Path.GetTempPath(), "LANCommander_BUnit_Archives"); Directory.CreateDirectory(archivePath); await storageLocationService.AddAsync(new StorageLocation { Path = archivePath, Type = StorageLocationType.Archive, Default = true }); var savePath = Path.Combine(Path.GetTempPath(), "LANCommander_BUnit_Saves"); Directory.CreateDirectory(savePath); await storageLocationService.AddAsync(new StorageLocation { Path = savePath, Type = StorageLocationType.Save, Default = true }); var mediaPath = Path.Combine(Path.GetTempPath(), "LANCommander_BUnit_Media"); Directory.CreateDirectory(mediaPath); await storageLocationService.AddAsync(new StorageLocation { Path = mediaPath, Type = StorageLocationType.Media, Default = true }); // Seed a test game via the service layer for edit component tests. var gameService = scope.ServiceProvider.GetRequiredService(); var game = await gameService.AddAsync(new Game { Title = TestGameTitle, Type = GameType.MainGame, Singleplayer = true }); TestGameId = game.Id; // Mark the provider as configured so the app behaves as a set-up server. DatabaseContext.Provider = DatabaseProvider.SQLite; } public async Task DisposeAsync() { DatabaseContext.Provider = DatabaseProvider.Unknown; await Factory.DisposeAsync(); } } /// /// xUnit collection definition that shares a single across all /// bUnit component test classes, keeping them isolated from the Playwright "Server" collection so /// the static is not contended. /// [CollectionDefinition("BUnit")] public class BUnitCollection : ICollectionFixture { }