190 lines
5.5 KiB
C#
190 lines
5.5 KiB
C#
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;
|
|
|
|
/// <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"
|
|
}
|
|
};
|
|
}
|
|
}
|