Files
sufi-blazor/tests/Theming/SbThemeProviderTests.cs
T
2026-05-18 15:53:59 +03:30

135 lines
4.1 KiB
C#

using Bunit;
using SufiChain.SufiBlazor.Theming;
using Xunit;
namespace SufiChain.SufiBlazor.Tests.Theming;
public class SbThemeProviderTests : BunitContext
{
[Fact]
public void RendersWithDefaultLightTheme()
{
// Arrange & Act
var cut = Render<SbThemeProvider>(parameters => parameters
.AddChildContent("<p>Test Content</p>"));
// Assert
var rootElement = cut.Find(".sb-theme-root");
Assert.NotNull(rootElement);
Assert.Contains("sb-theme-light", rootElement.ClassList);
Assert.DoesNotContain("sb-theme-dark", rootElement.ClassList);
}
[Fact]
public void RendersWithDarkThemeWhenIsDarkIsTrue()
{
// Arrange & Act
var cut = Render<SbThemeProvider>(parameters => parameters
.Add(p => p.IsDark, true)
.AddChildContent("<p>Test Content</p>"));
// Assert
var rootElement = cut.Find(".sb-theme-root");
Assert.Contains("sb-theme-dark", rootElement.ClassList);
Assert.DoesNotContain("sb-theme-light", rootElement.ClassList);
}
[Fact]
public void RendersWithLtrDirectionByDefault()
{
// Arrange & Act
var cut = Render<SbThemeProvider>(parameters => parameters
.AddChildContent("<p>Test Content</p>"));
// Assert
var rootElement = cut.Find(".sb-theme-root");
Assert.Equal("ltr", rootElement.GetAttribute("dir"));
Assert.DoesNotContain("sb-rtl", rootElement.ClassList);
}
[Fact]
public void RendersWithRtlDirectionWhenDirectionIsRtl()
{
// Arrange & Act
var cut = Render<SbThemeProvider>(parameters => parameters
.Add(p => p.Direction, SbDirection.Rtl)
.AddChildContent("<p>Test Content</p>"));
// Assert
var rootElement = cut.Find(".sb-theme-root");
Assert.Equal("rtl", rootElement.GetAttribute("dir"));
Assert.Contains("sb-rtl", rootElement.ClassList);
}
[Fact]
public void RendersChildContent()
{
// Arrange
const string expectedContent = "Hello SufiBlazor";
// Act
var cut = Render<SbThemeProvider>(parameters => parameters
.AddChildContent($"<p>{expectedContent}</p>"));
// Assert
cut.MarkupMatches($"""<div class="sb-theme-root sb-theme-light" dir="ltr"><p>{expectedContent}</p></div>""");
}
[Fact]
public void AppliesCustomClass()
{
// Arrange & Act
var cut = Render<SbThemeProvider>(parameters => parameters
.Add(p => p.Class, "my-custom-class")
.AddChildContent("<p>Test</p>"));
// Assert
var rootElement = cut.Find(".sb-theme-root");
Assert.Contains("my-custom-class", rootElement.ClassList);
}
[Fact]
public void CascadesThemeContext()
{
// Arrange
SbThemeContext? capturedContext = null;
Action<SbThemeContext> onCaptured = ctx => capturedContext = ctx;
// Act
var cut = Render<SbThemeProvider>(parameters => parameters
.Add(p => p.IsDark, true)
.Add(p => p.Direction, SbDirection.Rtl)
.AddChildContent(builder =>
{
builder.OpenComponent<CascadeContextCapture>(0);
builder.AddAttribute(1, "OnContextCaptured", onCaptured);
builder.CloseComponent();
}));
// Assert
Assert.NotNull(capturedContext);
Assert.True(capturedContext!.IsDark);
Assert.Equal(SbDirection.Rtl, capturedContext.Direction);
}
/// <summary>
/// Helper component to capture cascaded theme context.
/// </summary>
private sealed class CascadeContextCapture : Microsoft.AspNetCore.Components.ComponentBase
{
[Microsoft.AspNetCore.Components.CascadingParameter]
public SbThemeContext? ThemeContext { get; set; }
[Microsoft.AspNetCore.Components.Parameter]
public Action<SbThemeContext>? OnContextCaptured { get; set; }
protected override void OnParametersSet()
{
if (ThemeContext != null)
{
OnContextCaptured?.Invoke(ThemeContext);
}
}
}
}