using Bunit; using Bunit.TestDoubles; using Fluxor; using Fluxor.Blazor.Web.ReduxDevTools; using Koogle.Application.DTOs; using Koogle.Application.Interfaces; using Koogle.Application.Services; using Koogle.Web.Components; using Koogle.Web.Components.Pages; using Koogle.Web.Store.AuthState; using Koogle.Web.Store.ClubState; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using MudBlazor; using MudBlazor.Services; using System.Security.Claims; using Koogle.Tests.Common; using Microsoft.AspNetCore.Antiforgery; namespace Koogle.Tests.Components; /// /// Base class for Blazor component tests with common setup. /// public abstract class BlazorTestBase : TestContext { protected Mock UserServiceMock { get; } protected Mock ClubContextMock { get; } protected Mock DispatcherMock { get; } //protected Mock HttpContextAccessor { get; } protected Mock Antiforgery { get; } protected Mock ClubServiceMock { get; } protected BlazorTestBase() { UserServiceMock = new Mock(); ClubContextMock = new Mock(); DispatcherMock = new Mock(); ClubServiceMock = new Mock(); Antiforgery = new Mock(); // Must add services BEFORE getting NavigationManager SetupServices(); } private void SetupServices() { // Register MudBlazor services first Services.AddMudServices(options => { options.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomRight; }); Services.AddFluxor(options => { options.ScanAssemblies(typeof(Routes).Assembly) .UseReduxDevTools(); }); // Register mocks Services.AddSingleton(Antiforgery.Object); Services.AddSingleton(ClubServiceMock.Object); Services.AddSingleton(UserServiceMock.Object); Services.AddSingleton(ClubContextMock.Object); Services.AddSingleton(DispatcherMock.Object); Services.AddMockHttpClient(); // Setup default club context ClubContextMock.Setup(c => c.ClubId).Returns(Guid.NewGuid()); ClubContextMock.Setup(c => c.ClubName).Returns("Test Club"); } /// /// Configures an authenticated user for the test. /// protected void SetupAuthenticatedUser( string? userName = null, string? userId = null, params string[] roles) { var authContext = this.AddTestAuthorization(); authContext.SetAuthorized(userName ?? "testuser"); if (roles.Length > 0) { authContext.SetRoles(roles); } if (!string.IsNullOrEmpty(userId)) { authContext.SetClaims(new Claim(ClaimTypes.NameIdentifier, userId)); } } /// /// Configures an unauthenticated user for the test. /// protected void SetupAnonymousUser() { var authContext = this.AddTestAuthorization(); authContext.SetNotAuthorized(); } /// /// Sets up a mock Fluxor state. /// protected Mock> SetupFluxorState(T initialState) where T : class { var stateMock = new Mock>(); stateMock.Setup(s => s.Value).Returns(initialState); Services.AddSingleton(stateMock.Object); return stateMock; } /// /// Creates a default AuthState for testing. /// protected AuthState CreateAuthState( bool isAuthenticated = true, string? displayName = null, string? email = null, IReadOnlyList? roles = null) { if (!isAuthenticated) { return AuthState.Initial; } return AuthState.Initial with { IsAuthenticated = true, IsLoading = false, CurrentUser = new UserDto { ProfileId = Guid.NewGuid(), IdentityUserId = Guid.NewGuid(), DisplayName = displayName ?? "Test User", Identity = new ApplicationUserDto { Id = Guid.NewGuid(), Email = email ?? "test@example.com", UserName = email ?? "test@example.com" } }, Roles = roles ?? [], Error = null }; } /// /// Creates a default ClubState for testing. /// protected ClubState CreateClubState(IReadOnlyList? clubs = null) { return ClubState.Initial with { Clubs = clubs ?? [], IsLoading = false }; } /// /// Creates a test UserDto for testing. /// protected UserDto CreateUserDto( string? displayName = null, string? email = null) { return new UserDto { ProfileId = Guid.NewGuid(), IdentityUserId = Guid.NewGuid(), DisplayName = displayName ?? "Test User", Identity = new ApplicationUserDto { Id = Guid.NewGuid(), Email = email ?? "test@example.com", UserName = email ?? "test@example.com" } }; } }