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"
}
};
}
}