KoogleApp/test/Koogle.Tests/Components/HomePageTests.cs

198 lines
6.7 KiB
C#

using Bunit;
using Bunit.TestDoubles;
using Fluxor;
using Koogle.Application.DTOs;
using Koogle.Application.Interfaces;
using Koogle.Web.Store.AuthState;
using Koogle.Web.Store.ClubState;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using MudBlazor;
using MudBlazor.Services;
using System.Security.Claims;
namespace Koogle.Tests.Components;
/// <summary>
/// Tests for the Home page component.
/// </summary>
public class HomePageTests : IDisposable
{
private readonly TestContext _ctx;
private readonly Mock<IUserService> _userServiceMock;
private readonly Mock<ICurrentClubContext> _clubContextMock;
private readonly Mock<IDispatcher> _dispatcherMock;
private readonly Mock<IState<AuthState>> _authStateMock;
private readonly Mock<IState<ClubState>> _clubStateMock;
private readonly Mock<IAuthorizationService> _authorizationServiceMock;
public HomePageTests()
{
_ctx = new TestContext();
_userServiceMock = new Mock<IUserService>();
_clubContextMock = new Mock<ICurrentClubContext>();
_dispatcherMock = new Mock<IDispatcher>();
// Setup default club context
_clubContextMock.Setup(c => c.ClubId).Returns(Guid.NewGuid());
_clubContextMock.Setup(c => c.ClubName).Returns("Test Club");
// Setup Fluxor states - required by Home page and child components
_authStateMock = new Mock<IState<AuthState>>();
_authStateMock.Setup(s => s.Value).Returns(AuthState.Initial);
_clubStateMock = new Mock<IState<ClubState>>();
_clubStateMock.Setup(s => s.Value).Returns(ClubState.Initial);
// Setup authorization service mock
_authorizationServiceMock = new Mock<IAuthorizationService>();
_authorizationServiceMock
.Setup(s => s.AuthorizeAsync(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<object?>(),
It.IsAny<string>()))
.ReturnsAsync(AuthorizationResult.Success());
// Register all services before any rendering
_ctx.Services.AddMudServices(options =>
{
options.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomRight;
});
_ctx.Services.AddSingleton(_userServiceMock.Object);
_ctx.Services.AddSingleton(_clubContextMock.Object);
_ctx.Services.AddSingleton(_dispatcherMock.Object);
_ctx.Services.AddSingleton(_authStateMock.Object);
_ctx.Services.AddSingleton(_clubStateMock.Object);
_ctx.Services.AddSingleton(_authorizationServiceMock.Object);
// Additional Fluxor services required by components
_ctx.Services.AddSingleton(new Mock<IActionSubscriber>().Object);
_ctx.Services.AddSingleton(new Mock<IStore>().Object);
// ASP.NET Core services needed by child components
var httpContextAccessorMock = new Mock<IHttpContextAccessor>();
httpContextAccessorMock.Setup(x => x.HttpContext).Returns(new DefaultHttpContext());
_ctx.Services.AddSingleton(httpContextAccessorMock.Object);
// Stub complex components to avoid deep dependency chains
_ctx.ComponentFactories.AddStub<Koogle.Web.Components.Shared.LogoutButton>();
}
public void Dispose()
{
_ctx.Dispose();
}
[Fact]
public void HomePage_RendersWelcomeMessage_WhenAuthorized()
{
// Arrange
var authContext = _ctx.AddTestAuthorization();
authContext.SetAuthorized("testuser");
// Setup authenticated auth state
_authStateMock.Setup(s => s.Value).Returns(CreateAuthState());
// Act
var cut = _ctx.RenderComponent<Koogle.Web.Components.Pages.Home>();
// Assert
cut.Markup.Should().Contain("Hello, world!");
cut.Markup.Should().Contain("Welcome to your new app");
}
[Fact]
public void HomePage_SetsPageTitle()
{
// Arrange
var authContext = _ctx.AddTestAuthorization();
authContext.SetAuthorized("testuser");
// Setup authenticated auth state
_authStateMock.Setup(s => s.Value).Returns(CreateAuthState());
// Act
var cut = _ctx.RenderComponent<Koogle.Web.Components.Pages.Home>();
// Assert
var pageTitle = cut.FindComponent<Microsoft.AspNetCore.Components.Web.PageTitle>();
pageTitle.Should().NotBeNull();
}
[Fact]
public void HomePage_DisplaysCurrentClub_WhenAuthorized()
{
// Arrange
var authContext = _ctx.AddTestAuthorization();
authContext.SetAuthorized("testuser");
_authStateMock.Setup(s => s.Value).Returns(CreateAuthState());
_clubContextMock.Setup(c => c.ClubName).Returns("Kegel Freunde 2025");
// Act
var cut = _ctx.RenderComponent<Koogle.Web.Components.Pages.Home>();
// Assert - AuthTest component shows current club name
cut.Markup.Should().Contain("Kegel Freunde 2025");
}
[Fact]
public void HomePage_ShowsUserDisplayName_WhenAuthenticated()
{
// Arrange
var authContext = _ctx.AddTestAuthorization();
authContext.SetAuthorized("testuser");
var authState = CreateAuthState("Max Mustermann");
_authStateMock.Setup(s => s.Value).Returns(authState);
// Act
var cut = _ctx.RenderComponent<Koogle.Web.Components.Pages.Home>();
// Assert - AuthTest component shows user display name
cut.Markup.Should().Contain("Max Mustermann");
}
[Fact]
public void HomePage_ShowsAuthTestComponent()
{
// Arrange
var authContext = _ctx.AddTestAuthorization();
authContext.SetAuthorized("testuser");
_authStateMock.Setup(s => s.Value).Returns(CreateAuthState());
// Act
var cut = _ctx.RenderComponent<Koogle.Web.Components.Pages.Home>();
// Assert - AuthTest component header is rendered
cut.Markup.Should().Contain("AuthTest-Component");
}
private static AuthState CreateAuthState(string displayName = "Test User")
{
return AuthState.Initial with
{
IsAuthenticated = true,
IsLoading = false,
CurrentUser = new UserDto
{
ProfileId = Guid.NewGuid(),
IdentityUserId = Guid.NewGuid(),
DisplayName = displayName,
Identity = new ApplicationUserDto
{
Id = Guid.NewGuid(),
Email = "test@example.com",
UserName = "test@example.com"
}
},
Roles = [],
Error = null
};
}
}