Files
sufi-blazor/tests/Components/Forms/SbTextAreaTests.cs
T
2026-05-18 15:53:59 +03:30

388 lines
11 KiB
C#

using Microsoft.AspNetCore.Components;
using Bunit;
using SufiChain.SufiBlazor.Components.Forms;
using Xunit;
namespace SufiChain.SufiBlazor.Tests.Components.Forms;
public class SbTextAreaTests : BunitContext
{
private IRenderedComponent<SbTextArea> RenderTextArea(
Action<ComponentParameterCollectionBuilder<SbTextArea>>? configure = null)
{
return Render<SbTextArea>(p => configure?.Invoke(p));
}
[Fact]
public void RendersTextAreaStructure()
{
// Arrange & Act
var cut = RenderTextArea();
// Assert
var wrapper = cut.Find(".sb-textarea");
Assert.NotNull(wrapper);
var textarea = cut.Find("textarea.sb-textarea__input");
Assert.NotNull(textarea);
}
[Fact]
public void RendersLabelWhenProvided()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Label, "Description")
.Add(x => x.Id, "desc"));
// Assert
var label = cut.Find(".sb-textarea__label");
Assert.NotNull(label);
Assert.Contains("Description", label.TextContent);
Assert.Equal("desc", label.GetAttribute("for"));
}
[Fact]
public void DoesNotRenderLabelWhenEmpty()
{
// Arrange & Act
var cut = RenderTextArea();
// Assert
Assert.Empty(cut.FindAll(".sb-textarea__label"));
}
[Fact]
public void RendersRequiredIndicatorWhenRequiredTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Label, "Comment")
.Add(x => x.Required, true));
// Assert
var required = cut.Find(".sb-textarea__required");
Assert.NotNull(required);
Assert.Equal("*", required.TextContent);
Assert.Equal("true", required.GetAttribute("aria-hidden"));
}
[Fact]
public void AssociatesLabelWithTextAreaId()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Label, "Notes")
.Add(x => x.Id, "notes-field"));
// Assert
var label = cut.Find("label.sb-textarea__label");
var textarea = cut.Find("textarea");
Assert.Equal("notes-field", label.GetAttribute("for"));
Assert.Equal("notes-field", textarea.GetAttribute("id"));
}
[Fact]
public void RendersHelperTextWhenProvided()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.HelperText, "Enter a detailed description")
.Add(x => x.Id, "desc"));
// Assert
var helper = cut.Find(".sb-textarea__helper");
Assert.NotNull(helper);
Assert.Contains("Enter a detailed description", helper.TextContent);
Assert.Equal("desc-helper", helper.GetAttribute("id"));
}
[Fact]
public void HidesHelperTextWhenErrorTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.HelperText, "Helper text")
.Add(x => x.Error, true)
.Add(x => x.ErrorMessage, "Invalid input"));
// Assert
Assert.Empty(cut.FindAll(".sb-textarea__helper"));
}
[Fact]
public void RendersErrorMessageWhenErrorTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Error, true)
.Add(x => x.ErrorMessage, "This field is required")
.Add(x => x.Id, "desc"));
// Assert
var error = cut.Find(".sb-textarea__error");
Assert.NotNull(error);
Assert.Contains("This field is required", error.TextContent);
Assert.Equal("alert", error.GetAttribute("role"));
Assert.Equal("desc-error", error.GetAttribute("id"));
}
[Fact]
public void DoesNotRenderErrorMessageWhenErrorFalse()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.ErrorMessage, "Should not show"));
// Assert
Assert.Empty(cut.FindAll(".sb-textarea__error"));
}
[Fact]
public void DisplaysValue()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Value, "Hello world"));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("Hello world", textarea.GetAttribute("value"));
}
[Fact]
public void RendersPlaceholder()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Placeholder, "Type here..."));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("Type here...", textarea.GetAttribute("placeholder"));
}
[Fact]
public void AppliesRowsAttribute()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Rows, 5));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("5", textarea.GetAttribute("rows"));
}
[Fact]
public void AppliesMaxLengthAttribute()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.MaxLength, 500));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("500", textarea.GetAttribute("maxlength"));
}
[Fact]
public void RendersCharacterCountWhenShowCharacterCountAndMaxLengthSet()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Value, "Hi")
.Add(x => x.ShowCharacterCount, true)
.Add(x => x.MaxLength, 100));
// Assert
var counter = cut.Find(".sb-textarea__counter");
Assert.NotNull(counter);
Assert.Contains("2 / 100", counter.TextContent);
}
[Fact]
public void DoesNotRenderCharacterCountWhenShowCharacterCountFalse()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.MaxLength, 100)
.Add(x => x.ShowCharacterCount, false));
// Assert
Assert.Empty(cut.FindAll(".sb-textarea__counter"));
}
[Fact]
public void DoesNotRenderCharacterCountWhenMaxLengthNotSet()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.ShowCharacterCount, true));
// Assert
Assert.Empty(cut.FindAll(".sb-textarea__counter"));
}
[Fact]
public void RendersResizeHandleWhenResizableTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Resizable, true));
// Assert
Assert.NotNull(cut.Find(".sb-textarea__resize-handle"));
}
[Fact]
public void DoesNotRenderResizeHandleWhenResizableFalse()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Resizable, false));
// Assert
Assert.Empty(cut.FindAll(".sb-textarea__resize-handle"));
}
[Fact]
public void AppliesErrorClassWhenErrorTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Error, true));
// Assert
var wrapper = cut.Find(".sb-textarea");
Assert.Contains("sb-textarea--error", wrapper.ClassList);
}
[Fact]
public void AppliesDisabledClassWhenDisabledTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Disabled, true));
// Assert
var wrapper = cut.Find(".sb-textarea");
Assert.Contains("sb-textarea--disabled", wrapper.ClassList);
var textarea = cut.Find("textarea");
Assert.NotNull(textarea.GetAttribute("disabled"));
}
[Fact]
public void AppliesReadOnlyClassWhenReadOnlyTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.ReadOnly, true));
// Assert
var wrapper = cut.Find(".sb-textarea");
Assert.Contains("sb-textarea--readonly", wrapper.ClassList);
var textarea = cut.Find("textarea");
Assert.NotNull(textarea.GetAttribute("readonly"));
}
[Fact]
public void AppliesClassParameter()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Class, "my-textarea"));
// Assert
var wrapper = cut.Find(".sb-textarea");
Assert.Contains("my-textarea", wrapper.ClassList);
}
[Fact]
public void AppliesStyleParameter()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Style, "min-height: 100px;"));
// Assert
var wrapper = cut.Find(".sb-textarea");
Assert.Contains("min-height: 100px", wrapper.GetAttribute("style"));
}
[Fact]
public void SetsAriaInvalidWhenErrorTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.Error, true));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("true", textarea.GetAttribute("aria-invalid"));
}
[Fact]
public void SetsAriaDescribedByToHelperWhenHelperTextProvided()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Id, "desc")
.Add(x => x.HelperText, "Hint text"));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("desc-helper", textarea.GetAttribute("aria-describedby"));
}
[Fact]
public void SetsAriaDescribedByToErrorWhenErrorTrue()
{
// Arrange & Act
var cut = RenderTextArea(p => p
.Add(x => x.Id, "desc")
.Add(x => x.HelperText, "Hint")
.Add(x => x.Error, true)
.Add(x => x.ErrorMessage, "Error"));
// Assert - when error, aria-describedby points to error, not helper
var textarea = cut.Find("textarea");
Assert.Equal("desc-error", textarea.GetAttribute("aria-describedby"));
}
[Fact]
public async Task InvokesValueChangedOnInput()
{
// Arrange
string? received = null;
var cut = RenderTextArea(p => p
.Add(x => x.ValueChanged, EventCallback.Factory.Create<string?>(this, v => received = v)));
var textarea = cut.Find("textarea");
// Act
await cut.InvokeAsync(() => textarea!.Input("New text"));
// Assert
Assert.Equal("New text", received);
}
[Fact]
public async Task InvokesValueChangedOnChange()
{
// Arrange
string? received = null;
var cut = RenderTextArea(p => p
.Add(x => x.ValueChanged, EventCallback.Factory.Create<string?>(this, v => received = v)));
var textarea = cut.Find("textarea");
// Act
await cut.InvokeAsync(() => textarea!.Change("Changed text"));
// Assert
Assert.Equal("Changed text", received);
}
[Fact]
public void AppliesAdditionalAttributes()
{
// Arrange & Act
var cut = RenderTextArea(p => p.Add(x => x.AdditionalAttributes, new Dictionary<string, object>
{
{ "data-testid", "description-area" },
{ "aria-label", "Description field" }
}));
// Assert
var textarea = cut.Find("textarea");
Assert.Equal("description-area", textarea.GetAttribute("data-testid"));
Assert.Equal("Description field", textarea.GetAttribute("aria-label"));
}
}