255 lines
7.3 KiB
C#
255 lines
7.3 KiB
C#
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"));
|
|
}
|
|
}
|