first commit
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Bunit;
|
||||
using SufiChain.SufiBlazor.Components;
|
||||
using SufiChain.SufiBlazor.Components.Forms;
|
||||
using Xunit;
|
||||
|
||||
namespace SufiChain.SufiBlazor.Tests.Components.Forms;
|
||||
|
||||
public class SbCheckboxTests : BunitContext
|
||||
{
|
||||
private IRenderedComponent<SbCheckbox> RenderCheckbox(
|
||||
Action<ComponentParameterCollectionBuilder<SbCheckbox>>? configure = null)
|
||||
{
|
||||
return Render<SbCheckbox>(p =>
|
||||
{
|
||||
configure?.Invoke(p);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersCheckboxStructure()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox();
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.NotNull(label);
|
||||
Assert.NotNull(cut.Find("input.sb-checkbox__input"));
|
||||
Assert.NotNull(cut.Find(".sb-checkbox__box"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersLabelWhenProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Label, "Accept terms"));
|
||||
|
||||
// Assert
|
||||
var labelSpan = cut.Find(".sb-checkbox__label");
|
||||
Assert.NotNull(labelSpan);
|
||||
Assert.Contains("Accept terms", labelSpan.TextContent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotRenderLabelSpanWhenLabelAndChildContentEmpty()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox();
|
||||
|
||||
// Assert - no label span when both Label and ChildContent are null/empty
|
||||
Assert.Empty(cut.FindAll(".sb-checkbox__label"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersChildContentInsteadOfLabelWhenBothProvided()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = Render<SbCheckbox>(p => p
|
||||
.Add(x => x.Label, "Ignore me")
|
||||
.AddChildContent(b => b.AddMarkupContent(0, "<span>Custom content</span>")));
|
||||
|
||||
// Assert - ChildContent takes precedence
|
||||
var labelSpan = cut.Find(".sb-checkbox__label");
|
||||
Assert.NotNull(labelSpan);
|
||||
Assert.Contains("Custom content", labelSpan.InnerHtml);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersCheckedClassAndCheckIconWhenValueTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Value, true));
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.Contains("sb-checkbox--checked", label.ClassList);
|
||||
Assert.NotNull(cut.Find(".sb-checkbox__check"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersIndeterminateClassAndIconWhenIndeterminateTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p
|
||||
.Add(x => x.Value, false)
|
||||
.Add(x => x.Indeterminate, true));
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.Contains("sb-checkbox--indeterminate", label.ClassList);
|
||||
Assert.NotNull(cut.Find(".sb-checkbox__indeterminate"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RendersDisabledClassWhenDisabledTrue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Disabled, true));
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.Contains("sb-checkbox--disabled", label.ClassList);
|
||||
var input = cut.Find("input");
|
||||
Assert.True(input.GetAttribute("disabled") != null || input.OuterHtml.Contains("disabled"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesColorClass()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Color, SbColor.Success));
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.Contains("sb-checkbox--success", label.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokesValueChangedWhenChecked()
|
||||
{
|
||||
// Arrange
|
||||
var received = false;
|
||||
var cut = RenderCheckbox(p => p
|
||||
.Add(x => x.Value, false)
|
||||
.Add(x => x.ValueChanged, EventCallback.Factory.Create<bool>(this, v => received = v)));
|
||||
|
||||
// Act - SbCheckbox uses @onchange
|
||||
var input = cut.Find("input.sb-checkbox__input");
|
||||
await cut.InvokeAsync(() => input!.Change(true));
|
||||
|
||||
// Assert
|
||||
Assert.True(received);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvokesValueChangedWhenUnchecked()
|
||||
{
|
||||
// Arrange
|
||||
var received = true;
|
||||
var cut = RenderCheckbox(p => p
|
||||
.Add(x => x.Value, true)
|
||||
.Add(x => x.ValueChanged, EventCallback.Factory.Create<bool>(this, v => received = v)));
|
||||
|
||||
// Act
|
||||
var input = cut.Find("input.sb-checkbox__input");
|
||||
await cut.InvokeAsync(() => input!.Change(false));
|
||||
|
||||
// Assert
|
||||
Assert.False(received);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DoesNotInvokeValueChangedWhenDisabled()
|
||||
{
|
||||
// Arrange
|
||||
var received = (bool?)null;
|
||||
var cut = RenderCheckbox(p => p
|
||||
.Add(x => x.Value, false)
|
||||
.Add(x => x.Disabled, true)
|
||||
.Add(x => x.ValueChanged, EventCallback.Factory.Create<bool>(this, v => received = v)));
|
||||
|
||||
// Act
|
||||
var input = cut.Find("input.sb-checkbox__input");
|
||||
await cut.InvokeAsync(() => input!.Change(true));
|
||||
|
||||
// Assert - callback should not be invoked when disabled
|
||||
Assert.Null(received);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasCorrectAriaCheckedWhenChecked()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Value, true));
|
||||
|
||||
// Assert
|
||||
var input = cut.Find("input");
|
||||
Assert.Equal("true", input.GetAttribute("aria-checked"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasCorrectAriaCheckedWhenUnchecked()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Value, false));
|
||||
|
||||
// Assert
|
||||
var input = cut.Find("input");
|
||||
Assert.Equal("false", input.GetAttribute("aria-checked"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HasAriaCheckedMixedWhenIndeterminate()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p
|
||||
.Add(x => x.Value, false)
|
||||
.Add(x => x.Indeterminate, true));
|
||||
|
||||
// Assert
|
||||
var input = cut.Find("input");
|
||||
Assert.Equal("mixed", input.GetAttribute("aria-checked"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesCustomClass()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Class, "my-checkbox"));
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.Contains("my-checkbox", label.ClassList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesInlineStyle()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Style, "margin: 8px;"));
|
||||
|
||||
// Assert
|
||||
var label = cut.Find("label.sb-checkbox");
|
||||
Assert.Contains("margin: 8px", label.GetAttribute("style"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesIdToInput()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.Id, "agree-checkbox"));
|
||||
|
||||
// Assert
|
||||
var input = cut.Find("input");
|
||||
Assert.Equal("agree-checkbox", input.GetAttribute("id"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliesAdditionalAttributes()
|
||||
{
|
||||
// Arrange & Act
|
||||
var cut = RenderCheckbox(p => p.Add(x => x.AdditionalAttributes, new Dictionary<string, object>
|
||||
{
|
||||
{ "data-testid", "accept-checkbox" },
|
||||
{ "aria-label", "Accept terms and conditions" }
|
||||
}));
|
||||
|
||||
// Assert
|
||||
var input = cut.Find("input");
|
||||
Assert.Equal("accept-checkbox", input.GetAttribute("data-testid"));
|
||||
Assert.Equal("Accept terms and conditions", input.GetAttribute("aria-label"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user