KoogleApp/test/GoodWood.Tests/Components/BlazorTestBase.cs

190 lines
5.5 KiB
C#

using Bunit;
using Bunit.TestDoubles;
using Fluxor;
using Fluxor.Blazor.Web.ReduxDevTools;
using GoodWood.Application.DTOs;
using GoodWood.Application.Interfaces;
using GoodWood.Application.Services;
using GoodWood.Web.Components;
using GoodWood.Web.Components.Pages;
using GoodWood.Web.Store.AuthState;
using GoodWood.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 GoodWood.Tests.Common;
using Microsoft.AspNetCore.Antiforgery;
namespace GoodWood.Tests.Components;
/// <summary>
/// Base class for Blazor component tests with common setup.
/// </summary>
public abstract class BlazorTestBase : TestContext
{
protected Mock<IUserService> UserServiceMock { get; }
protected Mock<ICurrentClubContext> ClubContextMock { get; }
protected Mock<IDispatcher> DispatcherMock { get; }
//protected Mock<IHttpContextAccessor> HttpContextAccessor { get; }
protected Mock<IAntiforgery> Antiforgery { get; }
protected Mock<IClubService> ClubServiceMock { get; }
protected BlazorTestBase()
{
UserServiceMock = new Mock<IUserService>();
ClubContextMock = new Mock<ICurrentClubContext>();
DispatcherMock = new Mock<IDispatcher>();
ClubServiceMock = new Mock<IClubService>();
Antiforgery = new Mock<IAntiforgery>();
// 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");
}
/// <summary>
/// Configures an authenticated user for the test.
/// </summary>
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));
}
}
/// <summary>
/// Configures an unauthenticated user for the test.
/// </summary>
protected void SetupAnonymousUser()
{
var authContext = this.AddTestAuthorization();
authContext.SetNotAuthorized();
}
/// <summary>
/// Sets up a mock Fluxor state.
/// </summary>
protected Mock<IState<T>> SetupFluxorState<T>(T initialState) where T : class
{
var stateMock = new Mock<IState<T>>();
stateMock.Setup(s => s.Value).Returns(initialState);
Services.AddSingleton(stateMock.Object);
return stateMock;
}
/// <summary>
/// Creates a default AuthState for testing.
/// </summary>
protected AuthState CreateAuthState(
bool isAuthenticated = true,
string? displayName = null,
string? email = null,
IReadOnlyList<string>? 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
};
}
/// <summary>
/// Creates a default ClubState for testing.
/// </summary>
protected ClubState CreateClubState(IReadOnlyList<ClubDto>? clubs = null)
{
return ClubState.Initial with
{
Clubs = clubs ?? [],
IsLoading = false
};
}
/// <summary>
/// Creates a test UserDto for testing.
/// </summary>
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"
}
};
}
}