diff --git a/Radzen.Blazor.Tests/AccordionTests.cs b/Radzen.Blazor.Tests/AccordionTests.cs new file mode 100644 index 00000000..956928c4 --- /dev/null +++ b/Radzen.Blazor.Tests/AccordionTests.cs @@ -0,0 +1,195 @@ +using Bunit; +using Microsoft.AspNetCore.Components; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class AccordionTests + { + [Fact] + public void Accordion_Renders_CssClasses() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-accordion", component.Markup); + } + + [Fact] + public void Accordion_Renders_AccordionItems() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Test Item"); + builder.AddAttribute(2, "ChildContent", (RenderFragment)(contentBuilder => + { + contentBuilder.AddContent(0, "Item Content"); + })); + builder.CloseComponent(); + }); + }); + + Assert.Contains("Test Item", component.Markup); + Assert.Contains("Item Content", component.Markup); + } + + [Fact] + public void Accordion_Renders_ItemWithIcon() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Orders"); + builder.AddAttribute(2, "Icon", "account_balance_wallet"); + builder.AddAttribute(3, "ChildContent", (RenderFragment)(contentBuilder => + { + contentBuilder.AddContent(0, "Order Details"); + })); + builder.CloseComponent(); + }); + }); + + Assert.Contains("account_balance_wallet", component.Markup); + Assert.Contains("Orders", component.Markup); + } + + [Fact] + public void Accordion_SingleExpand_OnlyOneItemExpanded() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Multiple, false); // Single expand mode + parameters.Add(p => p.Items, builder => + { + // Add first item + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Item 1"); + builder.AddAttribute(2, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Content 1"))); + builder.CloseComponent(); + + // Add second item + builder.OpenComponent(1); + builder.AddAttribute(1, "Text", "Item 2"); + builder.AddAttribute(2, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Content 2"))); + builder.CloseComponent(); + }); + }); + + Assert.False(component.Instance.Multiple); + } + + [Fact] + public void Accordion_MultipleExpand_AllowsMultipleItemsExpanded() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Multiple, true); + }); + + Assert.True(component.Instance.Multiple); + } + + [Fact] + public void Accordion_Raises_ExpandEvent() + { + using var ctx = new TestContext(); + + var expandRaised = false; + int expandedIndex = -1; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Expand, EventCallback.Factory.Create(this, (index) => + { + expandRaised = true; + expandedIndex = index; + })); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Test Item"); + builder.AddAttribute(2, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Content"))); + builder.CloseComponent(); + }); + }); + + // Find and click the accordion header link to expand + var header = component.Find(".rz-accordion-header a"); + header.Click(); + + Assert.True(expandRaised); + Assert.Equal(0, expandedIndex); + } + + [Fact] + public void Accordion_Raises_CollapseEvent() + { + using var ctx = new TestContext(); + + var collapseRaised = false; + int collapsedIndex = -1; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Collapse, EventCallback.Factory.Create(this, (index) => + { + collapseRaised = true; + collapsedIndex = index; + })); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Test Item"); + builder.AddAttribute(2, "Selected", true); // Start expanded + builder.AddAttribute(3, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Content"))); + builder.CloseComponent(); + }); + }); + + // Find and click the accordion header link to collapse + var header = component.Find(".rz-accordion-header a"); + header.Click(); + + Assert.True(collapseRaised); + Assert.Equal(0, collapsedIndex); + } + + [Fact] + public void Accordion_DisabledItem_CannotExpand() + { + using var ctx = new TestContext(); + + var expandRaised = false; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Expand, EventCallback.Factory.Create(this, (_) => expandRaised = true)); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Disabled Item"); + builder.AddAttribute(2, "Disabled", true); + builder.AddAttribute(3, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Content"))); + builder.CloseComponent(); + }); + }); + + // Try to click the disabled item + var header = component.Find(".rz-accordion-header a"); + header.Click(); + + // Event should not be raised for disabled item + Assert.False(expandRaised); + } + } +} + diff --git a/Radzen.Blazor.Tests/AlertTests.cs b/Radzen.Blazor.Tests/AlertTests.cs new file mode 100644 index 00000000..98ed91f6 --- /dev/null +++ b/Radzen.Blazor.Tests/AlertTests.cs @@ -0,0 +1,195 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class AlertTests + { + [Fact] + public void Alert_Renders_CssClasses() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-alert", component.Markup); + } + + [Fact] + public void Alert_Renders_AlertStyle() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlertStyle, AlertStyle.Danger)); + Assert.Contains("rz-danger", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlertStyle, AlertStyle.Success)); + Assert.Contains("rz-success", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlertStyle, AlertStyle.Warning)); + Assert.Contains("rz-warning", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlertStyle, AlertStyle.Info)); + Assert.Contains("rz-info", component.Markup); + } + + [Fact] + public void Alert_Renders_Shade() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters + .Add(p => p.AlertStyle, AlertStyle.Primary) + .Add(p => p.Shade, Shade.Lighter)); + + Assert.Contains("rz-shade-lighter", component.Markup); + + component.SetParametersAndRender(parameters => parameters + .Add(p => p.AlertStyle, AlertStyle.Primary) + .Add(p => p.Shade, Shade.Darker)); + + Assert.Contains("rz-shade-darker", component.Markup); + } + + [Fact] + public void Alert_Renders_Variant() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Variant, Variant.Outlined)); + Assert.Contains("rz-variant-outlined", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Variant, Variant.Flat)); + Assert.Contains("rz-variant-flat", component.Markup); + } + + [Fact] + public void Alert_Renders_Title() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var title = "Alert Title"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Title, title)); + + Assert.Contains(title, component.Markup); + Assert.Contains("rz-alert-title", component.Markup); + } + + [Fact] + public void Alert_Renders_Text() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var text = "This is an alert message"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Text, text)); + + Assert.Contains(text, component.Markup); + } + + [Fact] + public void Alert_Renders_ChildContent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.AddChildContent("Custom alert content"); + }); + + Assert.Contains("Custom alert content", component.Markup); + } + + [Fact] + public void Alert_ShowIcon_DisplaysIcon() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + // Default should show icon + Assert.Contains("rz-alert-icon", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.ShowIcon, false)); + Assert.DoesNotContain("rz-alert-icon", component.Markup); + } + + [Fact] + public void Alert_AllowClose_DisplaysCloseButton() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + // Default AllowClose is true - should contain a button with close icon + component.SetParametersAndRender(parameters => parameters.Add(p => p.AllowClose, true)); + Assert.Contains("close", component.Markup); + Assert.Contains("rz-button", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AllowClose, false)); + // When AllowClose is false, should not have close button + var buttonCount = System.Text.RegularExpressions.Regex.Matches(component.Markup, "rz-button").Count; + Assert.Equal(0, buttonCount); + } + + [Fact] + public void Alert_CloseButton_RaisesCloseEvent() + { + using var ctx = new TestContext(); + + var closeRaised = false; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowClose, true); + parameters.Add(p => p.Close, () => closeRaised = true); + }); + + var closeButton = component.Find("button.rz-button"); + closeButton.Click(); + + Assert.True(closeRaised); + } + + [Fact] + public void Alert_Visible_ControlsDisplay() + { + using var ctx = new TestContext(); + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Visible, true); + parameters.Add(p => p.Text, "Visible Alert"); + }); + + Assert.Contains("Visible Alert", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Visible, false)); + + // When not visible, component should not render + Assert.DoesNotContain("Visible Alert", component.Markup); + } + + [Fact] + public void Alert_CloseButton_SetsVisibleToFalse() + { + using var ctx = new TestContext(); + + var visibleValue = true; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Visible, visibleValue); + parameters.Add(p => p.AllowClose, true); + parameters.Add(p => p.VisibleChanged, (bool value) => visibleValue = value); + }); + + var closeButton = component.Find("button.rz-button"); + closeButton.Click(); + + Assert.False(visibleValue); + } + } +} + + diff --git a/Radzen.Blazor.Tests/CardTests.cs b/Radzen.Blazor.Tests/CardTests.cs new file mode 100644 index 00000000..4bc4fb8c --- /dev/null +++ b/Radzen.Blazor.Tests/CardTests.cs @@ -0,0 +1,46 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class CardTests + { + [Fact] + public void Card_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-card", component.Markup); + } + + [Fact] + public void Card_Renders_ChildContent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.AddChildContent("
Card Content
"); + }); + + Assert.Contains("Card Content", component.Markup); + } + + [Fact] + public void Card_Renders_Variant() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Variant, Variant.Outlined)); + Assert.Contains("rz-variant-outlined", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Variant, Variant.Filled)); + Assert.Contains("rz-variant-filled", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Variant, Variant.Flat)); + Assert.Contains("rz-variant-flat", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/CarouselTests.cs b/Radzen.Blazor.Tests/CarouselTests.cs new file mode 100644 index 00000000..4698b7b3 --- /dev/null +++ b/Radzen.Blazor.Tests/CarouselTests.cs @@ -0,0 +1,173 @@ +using Bunit; +using Microsoft.AspNetCore.Components; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class CarouselTests + { + [Fact] + public void Carousel_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-carousel", component.Markup); + } + + [Fact] + public void Carousel_Renders_AllowPaging_True() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowPaging, true); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Slide 1"))); + builder.CloseComponent(); + + builder.OpenComponent(2); + builder.AddAttribute(3, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Slide 2"))); + builder.CloseComponent(); + }); + }); + + Assert.Contains("rz-carousel-pager-button", component.Markup); + } + + [Fact] + public void Carousel_Renders_AllowPaging_False() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowPaging, false); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Slide 1"))); + builder.CloseComponent(); + }); + }); + + Assert.DoesNotContain("rz-carousel-pager-button", component.Markup); + } + + [Fact] + public void Carousel_Renders_AllowNavigation_True() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowNavigation, true); + }); + + Assert.Contains("rz-carousel-prev", component.Markup); + Assert.Contains("rz-carousel-next", component.Markup); + } + + [Fact] + public void Carousel_Renders_AllowNavigation_False() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowNavigation, false); + }); + + Assert.DoesNotContain("rz-carousel-prev", component.Markup); + Assert.DoesNotContain("rz-carousel-next", component.Markup); + Assert.Contains("rz-carousel-no-navigation", component.Markup); + } + + [Fact] + public void Carousel_Renders_PagerPosition_Top() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.PagerPosition, PagerPosition.Top); + parameters.Add(p => p.AllowPaging, true); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Slide"))); + builder.CloseComponent(); + }); + }); + + Assert.Contains("rz-carousel-pager-top", component.Markup); + } + + [Fact] + public void Carousel_Renders_PagerPosition_Bottom() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.PagerPosition, PagerPosition.Bottom); + parameters.Add(p => p.AllowPaging, true); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Slide"))); + builder.CloseComponent(); + }); + }); + + Assert.Contains("rz-carousel-pager-bottom", component.Markup); + } + + [Fact] + public void Carousel_Renders_PagerPosition_TopAndBottom() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.PagerPosition, PagerPosition.TopAndBottom); + parameters.Add(p => p.AllowPaging, true); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "ChildContent", (RenderFragment)(b => b.AddContent(0, "Slide"))); + builder.CloseComponent(); + }); + }); + + Assert.Contains("rz-carousel-pager-top", component.Markup); + Assert.Contains("rz-carousel-pager-bottom", component.Markup); + } + + [Fact] + public void Carousel_Renders_PagerOverlay_True() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.PagerOverlay, true); + }); + + Assert.Contains("rz-carousel-pager-overlay", component.Markup); + } + + [Fact] + public void Carousel_Renders_PagerOverlay_False() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.PagerOverlay, false); + }); + + Assert.DoesNotContain("rz-carousel-pager-overlay", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/ColumnTests.cs b/Radzen.Blazor.Tests/ColumnTests.cs new file mode 100644 index 00000000..5fa724af --- /dev/null +++ b/Radzen.Blazor.Tests/ColumnTests.cs @@ -0,0 +1,74 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class ColumnTests + { + [Fact] + public void Column_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-col", component.Markup); + } + + [Fact] + public void Column_Renders_ChildContent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.AddChildContent("
Column Content
"); + }); + + Assert.Contains("Column Content", component.Markup); + } + + [Fact] + public void Column_Renders_SizeParameter() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, 6)); + + Assert.Contains("rz-col-6", component.Markup); + } + + [Fact] + public void Column_Renders_SizeMD() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.SizeMD, 4)); + + Assert.Contains("rz-col-md-4", component.Markup); + } + + [Fact] + public void Column_Renders_SizeSM() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.SizeSM, 12)); + + Assert.Contains("rz-col-sm-12", component.Markup); + } + + [Fact] + public void Column_Renders_Offset() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Offset, 2)); + + Assert.Contains("rz-offset-2", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/HeadingTests.cs b/Radzen.Blazor.Tests/HeadingTests.cs new file mode 100644 index 00000000..1eee86ec --- /dev/null +++ b/Radzen.Blazor.Tests/HeadingTests.cs @@ -0,0 +1,103 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class HeadingTests + { + [Fact] + public void Heading_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-heading", component.Markup); + } + + [Fact] + public void Heading_Renders_TextParameter() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var text = "Test Heading"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Text, text)); + + Assert.Contains(text, component.Markup); + } + + [Fact] + public void Heading_Renders_H1_ByDefault() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var text = "Heading Text"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Text, text)); + + Assert.Contains("(); + + var text = "Heading 2"; + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Text, text); + parameters.Add(p => p.Size, "H2"); + }); + + Assert.Contains("(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, "H3")); + + Assert.Contains("(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, "H4")); + + Assert.Contains("(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, "H5")); + + Assert.Contains("(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, "H6")); + + Assert.Contains("(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-html-editor", component.Markup); + } + + [Fact] + public void HtmlEditor_Renders_ShowToolbar_True() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + ctx.Services.AddScoped(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ShowToolbar, true); + }); + + Assert.Contains("rz-html-editor-toolbar", component.Markup); + } + + [Fact] + public void HtmlEditor_Renders_ShowToolbar_False() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + ctx.Services.AddScoped(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ShowToolbar, false); + }); + + Assert.DoesNotContain("rz-html-editor-toolbar", component.Markup); + } + + [Fact] + public void HtmlEditor_Renders_Mode_Design() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + ctx.Services.AddScoped(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Mode, HtmlEditorMode.Design); + }); + + // Design mode shows the content editable div + Assert.Contains("contenteditable", component.Markup); + } + + [Fact] + public void HtmlEditor_Renders_Mode_Source() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + ctx.Services.AddScoped(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Mode, HtmlEditorMode.Source); + }); + + // Source mode shows the textarea for HTML editing + Assert.Contains("rz-html-editor-source", component.Markup); + } + + [Fact] + public void HtmlEditor_Renders_Disabled_Attribute() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + ctx.Services.AddScoped(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Disabled, true); + }); + + Assert.Contains("disabled", component.Markup); + } + + [Fact] + public void HtmlEditor_Renders_ContentArea() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + ctx.Services.AddScoped(); + var component = ctx.RenderComponent(); + + Assert.Contains("rz-html-editor-content", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/ListBoxTests.cs b/Radzen.Blazor.Tests/ListBoxTests.cs new file mode 100644 index 00000000..2359cdb3 --- /dev/null +++ b/Radzen.Blazor.Tests/ListBoxTests.cs @@ -0,0 +1,140 @@ +using Bunit; +using Xunit; +using System.Collections.Generic; + +namespace Radzen.Blazor.Tests +{ + public class ListBoxTests + { + class Item + { + public int Id { get; set; } + public string Name { get; set; } + } + + [Fact] + public void ListBox_Renders_WithClassName() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent>(); + + Assert.Contains(@"rz-listbox", component.Markup); + } + + [Fact] + public void ListBox_Renders_ListWrapper() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var data = new List { "Apple", "Banana", "Cherry" }; + + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Data, data); + }); + + Assert.Contains("rz-listbox-list-wrapper", component.Markup); + Assert.Contains("rz-listbox-list", component.Markup); + } + + [Fact] + public void ListBox_Renders_WithData_SimpleList() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var data = new List { "Apple", "Banana", "Cherry" }; + + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Data, data); + }); + + Assert.Contains("Apple", component.Markup); + Assert.Contains("Banana", component.Markup); + Assert.Contains("Cherry", component.Markup); + } + + [Fact] + public void ListBox_Renders_WithData_CustomTextValueProperties() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var data = new List + { + new Item { Id = 1, Name = "First Item" }, + new Item { Id = 2, Name = "Second Item" } + }; + + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Data, data); + parameters.Add(p => p.TextProperty, "Name"); + parameters.Add(p => p.ValueProperty, "Id"); + }); + + Assert.Contains("First Item", component.Markup); + Assert.Contains("Second Item", component.Markup); + } + + [Fact] + public void ListBox_Renders_AllowFiltering() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.AllowFiltering, true); + parameters.Add(p => p.Data, new List { "Item1", "Item2" }); + }); + + Assert.Contains("rz-listbox-filter", component.Markup); + Assert.Contains("rz-listbox-header", component.Markup); + } + + [Fact] + public void ListBox_Renders_Disabled_Attribute() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Disabled, true); + }); + + Assert.Contains("disabled", component.Markup); + } + + [Fact] + public void ListBox_Renders_Multiple_WithSelectAll() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent>>(parameters => + { + parameters.Add(p => p.Multiple, true); + parameters.Add(p => p.SelectAllText, "Select All Items"); + parameters.Add(p => p.Data, new List { "Item1", "Item2" }); + }); + + Assert.Contains("Select All Items", component.Markup); + Assert.Contains("rz-chkbox", component.Markup); + } + + [Fact] + public void ListBox_Renders_FilterPlaceholder() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Placeholder, "Select an item"); + parameters.Add(p => p.AllowFiltering, true); + parameters.Add(p => p.Data, new List { "Item1", "Item2" }); + }); + + Assert.Contains("Select an item", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/MediaQueryTests.cs b/Radzen.Blazor.Tests/MediaQueryTests.cs new file mode 100644 index 00000000..29ae2b1d --- /dev/null +++ b/Radzen.Blazor.Tests/MediaQueryTests.cs @@ -0,0 +1,65 @@ +using Bunit; +using Microsoft.AspNetCore.Components; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class MediaQueryTests + { + [Fact] + public void MediaQuery_Renders() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Query, "(max-width: 768px)"); + }); + + Assert.NotNull(component.Instance); + } + + [Fact] + public void MediaQuery_HasQueryParameter() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + + var query = "(max-width: 1024px)"; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Query, query); + }); + + Assert.Equal(query, component.Instance.Query); + } + + [Fact] + public void MediaQuery_InvokesChangeCallback() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + + bool changeInvoked = false; + bool matchResult = false; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Query, "(max-width: 768px)"); + parameters.Add(p => p.Change, EventCallback.Factory.Create(this, (matches) => + { + changeInvoked = true; + matchResult = matches; + })); + }); + + // Invoke the JSInvokable method directly + component.Instance.OnChange(true); + + Assert.True(changeInvoked); + Assert.True(matchResult); + } + } +} + diff --git a/Radzen.Blazor.Tests/MenuTests.cs b/Radzen.Blazor.Tests/MenuTests.cs new file mode 100644 index 00000000..0e6609c1 --- /dev/null +++ b/Radzen.Blazor.Tests/MenuTests.cs @@ -0,0 +1,58 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class MenuTests + { + [Fact] + public void Menu_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-menu", component.Markup); + } + + [Fact] + public void Menu_Renders_Responsive_True() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Responsive, true); + }); + + Assert.Contains("rz-menu-closed", component.Markup); + Assert.Contains("rz-menu-toggle", component.Markup); + } + + [Fact] + public void Menu_Renders_Responsive_False() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Responsive, false); + }); + + Assert.DoesNotContain("rz-menu-toggle", component.Markup); + Assert.DoesNotContain("rz-menu-closed", component.Markup); + } + + + [Fact] + public void Menu_Renders_CustomToggleAriaLabel() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Responsive, true); + parameters.Add(p => p.ToggleAriaLabel, "Open navigation"); + }); + + Assert.Contains("Open navigation", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/RadioButtonListTests.cs b/Radzen.Blazor.Tests/RadioButtonListTests.cs new file mode 100644 index 00000000..b8666b94 --- /dev/null +++ b/Radzen.Blazor.Tests/RadioButtonListTests.cs @@ -0,0 +1,62 @@ +using Bunit; +using System.Collections.Generic; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class RadioButtonListTests + { + [Fact] + public void RadioButtonList_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent>(); + + Assert.Contains(@"rz-radio-button-list", component.Markup); + } + + [Fact] + public void RadioButtonList_Renders_Orientation() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent>(0); + builder.AddAttribute(1, "Text", "Option 1"); + builder.AddAttribute(2, "Value", 1); + builder.CloseComponent(); + }); + }); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Horizontal)); + // Orientation is applied via RadzenStack which uses flex-direction + Assert.Contains("rz-flex-row", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Vertical)); + Assert.Contains("rz-flex-column", component.Markup); + } + + [Fact] + public void RadioButtonList_Renders_Disabled() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Disabled, true); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent>(0); + builder.AddAttribute(1, "Text", "Option 1"); + builder.AddAttribute(2, "Value", 1); + builder.CloseComponent(); + }); + }); + + // Disabled class is on the radio button items + Assert.Contains("rz-state-disabled", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/RatingTests.cs b/Radzen.Blazor.Tests/RatingTests.cs new file mode 100644 index 00000000..98c79684 --- /dev/null +++ b/Radzen.Blazor.Tests/RatingTests.cs @@ -0,0 +1,82 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class RatingTests + { + [Fact] + public void Rating_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-rating", component.Markup); + } + + [Fact] + public void Rating_Renders_Stars() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Stars, 5)); + + // Should render 5 star icons (rzi-star or rzi-star-o) + 1 clear button icon = 6 total + var starCount = System.Text.RegularExpressions.Regex.Matches(component.Markup, "rz-rating-icon").Count; + Assert.Equal(6, starCount); // 5 stars + 1 clear button + } + + [Fact] + public void Rating_Renders_CustomStarCount() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Stars, 10)); + + var starCount = System.Text.RegularExpressions.Regex.Matches(component.Markup, "rz-rating-icon").Count; + Assert.Equal(11, starCount); // 10 stars + 1 clear button + } + + [Fact] + public void Rating_Renders_Value() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Value, 3); + parameters.Add(p => p.Stars, 5); + }); + + // Should have 3 filled stars (rzi-star) and 2 outline stars (rzi-star-o) + var filledStars = System.Text.RegularExpressions.Regex.Matches(component.Markup, "rzi-star\"").Count; + Assert.Equal(3, filledStars); + } + + [Fact] + public void Rating_Renders_ReadOnly() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.ReadOnly, true)); + + Assert.Contains("rz-state-readonly", component.Markup); + } + + [Fact] + public void Rating_Renders_Disabled() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Disabled, true)); + + Assert.Contains("rz-state-disabled", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/RowTests.cs b/Radzen.Blazor.Tests/RowTests.cs new file mode 100644 index 00000000..11551a9d --- /dev/null +++ b/Radzen.Blazor.Tests/RowTests.cs @@ -0,0 +1,63 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class RowTests + { + [Fact] + public void Row_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-row", component.Markup); + } + + [Fact] + public void Row_Renders_ChildContent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.AddChildContent("
Row Content
"); + }); + + Assert.Contains("Row Content", component.Markup); + } + + [Fact] + public void Row_Renders_Gap() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Gap, "2rem")); + + Assert.Contains("--rz-gap:2rem", component.Markup); + } + + [Fact] + public void Row_Renders_RowGap() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.RowGap, "1.5rem")); + + Assert.Contains("--rz-row-gap:1.5rem", component.Markup); + } + + [Fact] + public void Row_Renders_ColumnGap() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Gap, "1rem")); + + Assert.Contains("--rz-gap:1rem", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/SecurityCodeTests.cs b/Radzen.Blazor.Tests/SecurityCodeTests.cs new file mode 100644 index 00000000..48f01244 --- /dev/null +++ b/Radzen.Blazor.Tests/SecurityCodeTests.cs @@ -0,0 +1,45 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class SecurityCodeTests + { + [Fact] + public void SecurityCode_Renders_WithClassName() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-security-code", component.Markup); + } + + [Fact] + public void SecurityCode_Renders_Count() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Count, 6)); + + // Should render 6 input boxes + 1 hidden input for form submission = 7 total + var inputCount = System.Text.RegularExpressions.Regex.Matches(component.Markup, "(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Disabled, true)); + + Assert.Contains("disabled", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/SelectBarTests.cs b/Radzen.Blazor.Tests/SelectBarTests.cs new file mode 100644 index 00000000..95fd5d94 --- /dev/null +++ b/Radzen.Blazor.Tests/SelectBarTests.cs @@ -0,0 +1,83 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class SelectBarTests + { + [Fact] + public void SelectBar_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent>(); + + Assert.Contains(@"rz-selectbar", component.Markup); + } + + [Fact] + public void SelectBar_Renders_Orientation() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Option 1"); + builder.AddAttribute(2, "Value", 1); + builder.CloseComponent(); + }); + }); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Horizontal)); + Assert.Contains("rz-selectbar-horizontal", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Vertical)); + Assert.Contains("rz-selectbar-vertical", component.Markup); + } + + [Fact] + public void SelectBar_Renders_Multiple() + { + using var ctx = new TestContext(); + // When Multiple is true, TValue should be IEnumerable + var component = ctx.RenderComponent>>(parameters => + { + parameters.Add(p => p.Multiple, true); + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Option 1"); + builder.AddAttribute(2, "Value", 1); + builder.CloseComponent(); + }); + }); + + Assert.NotNull(component.Instance); + Assert.True(component.Instance.Multiple); + } + + [Fact] + public void SelectBar_Renders_Size() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent>(parameters => + { + parameters.Add(p => p.Items, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "Text", "Option 1"); + builder.AddAttribute(2, "Value", 1); + builder.CloseComponent(); + }); + }); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, ButtonSize.Small)); + Assert.Contains("rz-button-sm", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Size, ButtonSize.Large)); + Assert.Contains("rz-button-lg", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/SidebarToggleTests.cs b/Radzen.Blazor.Tests/SidebarToggleTests.cs new file mode 100644 index 00000000..aea62369 --- /dev/null +++ b/Radzen.Blazor.Tests/SidebarToggleTests.cs @@ -0,0 +1,65 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class SidebarToggleTests + { + [Fact] + public void SidebarToggle_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-sidebar-toggle", component.Markup); + } + + [Fact] + public void SidebarToggle_Renders_DefaultIcon() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains("menu", component.Markup); + } + + [Fact] + public void SidebarToggle_Renders_CustomIcon() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var icon = "close"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Icon, icon)); + + Assert.Contains(icon, component.Markup); + } + + [Fact] + public void SidebarToggle_Renders_AriaLabel() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var ariaLabel = "Toggle Navigation"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.ToggleAriaLabel, ariaLabel)); + + Assert.Contains($"aria-label=\"{ariaLabel}\"", component.Markup); + } + + [Fact] + public void SidebarToggle_Raises_ClickEvent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var clicked = false; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Click, args => { clicked = true; })); + + component.Find("button").Click(); + + Assert.True(clicked); + } + } +} + diff --git a/Radzen.Blazor.Tests/SplitterTests.cs b/Radzen.Blazor.Tests/SplitterTests.cs new file mode 100644 index 00000000..26d4318e --- /dev/null +++ b/Radzen.Blazor.Tests/SplitterTests.cs @@ -0,0 +1,42 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class SplitterTests + { + [Fact] + public void Splitter_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-splitter", component.Markup); + } + + [Fact] + public void Splitter_Renders_Orientation_Horizontal() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Orientation, Orientation.Horizontal); + }); + + Assert.Contains("rz-splitter-horizontal", component.Markup); + } + + [Fact] + public void Splitter_Renders_Orientation_Vertical() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Orientation, Orientation.Vertical); + }); + + Assert.Contains("rz-splitter-vertical", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/StackTests.cs b/Radzen.Blazor.Tests/StackTests.cs new file mode 100644 index 00000000..2f4a13d6 --- /dev/null +++ b/Radzen.Blazor.Tests/StackTests.cs @@ -0,0 +1,98 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class StackTests + { + [Fact] + public void Stack_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-stack", component.Markup); + } + + [Fact] + public void Stack_Renders_ChildContent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.AddChildContent("
Stack Content
"); + }); + + Assert.Contains("Stack Content", component.Markup); + } + + [Fact] + public void Stack_Renders_Orientation() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Horizontal)); + Assert.Contains("rz-flex-row", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Vertical)); + Assert.Contains("rz-flex-column", component.Markup); + } + + [Fact] + public void Stack_Renders_Gap() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Gap, "1.5rem")); + + Assert.Contains("--rz-gap:1.5rem", component.Markup); + } + + [Fact] + public void Stack_Renders_AlignItems() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlignItems, AlignItems.Center)); + + Assert.Contains("rz-align-items-center", component.Markup); + } + + [Fact] + public void Stack_Renders_JustifyContent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.JustifyContent, JustifyContent.SpaceBetween)); + + Assert.Contains("rz-justify-content-space-between", component.Markup); + } + + [Fact] + public void Stack_Renders_Wrap() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Wrap, FlexWrap.Wrap)); + + Assert.Contains("flex-wrap:wrap", component.Markup); + } + + [Fact] + public void Stack_Renders_Reverse() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Reverse, true)); + + Assert.Contains("rz-flex-column-reverse", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/StepsTests.cs b/Radzen.Blazor.Tests/StepsTests.cs new file mode 100644 index 00000000..64e27a23 --- /dev/null +++ b/Radzen.Blazor.Tests/StepsTests.cs @@ -0,0 +1,70 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class StepsTests + { + [Fact] + public void Steps_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-steps", component.Markup); + } + + [Fact] + public void Steps_Renders_ShowStepsButtons_True() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ShowStepsButtons, true); + }); + + Assert.Contains("rz-steps-buttons", component.Markup); + } + + [Fact] + public void Steps_Renders_ShowStepsButtons_False() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ShowStepsButtons, false); + }); + + Assert.DoesNotContain("rz-steps-buttons", component.Markup); + } + + [Fact] + public void Steps_Renders_StepsButtons() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ShowStepsButtons, true); + }); + + Assert.Contains("rz-steps-prev", component.Markup); + Assert.Contains("rz-steps-next", component.Markup); + } + + [Fact] + public void Steps_Renders_CustomButtonText() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ShowStepsButtons, true); + parameters.Add(p => p.NextText, "Continue"); + parameters.Add(p => p.PreviousText, "Back"); + }); + + Assert.Contains("Continue", component.Markup); + Assert.Contains("Back", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/TableTests.cs b/Radzen.Blazor.Tests/TableTests.cs new file mode 100644 index 00000000..2a01c182 --- /dev/null +++ b/Radzen.Blazor.Tests/TableTests.cs @@ -0,0 +1,100 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class TableTests + { + [Fact] + public void Table_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-datatable", component.Markup); + } + + [Fact] + public void Table_Renders_TableElement() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains("rz-grid-table", component.Markup); + Assert.Contains("(parameters => + { + parameters.Add(p => p.GridLines, DataGridGridLines.None); + }); + + Assert.Contains("rz-grid-gridlines-none", component.Markup); + } + + [Fact] + public void Table_Renders_GridLines_Horizontal() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.GridLines, DataGridGridLines.Horizontal); + }); + + Assert.Contains("rz-grid-gridlines-horizontal", component.Markup); + } + + [Fact] + public void Table_Renders_GridLines_Vertical() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.GridLines, DataGridGridLines.Vertical); + }); + + Assert.Contains("rz-grid-gridlines-vertical", component.Markup); + } + + [Fact] + public void Table_Renders_GridLines_Both() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.GridLines, DataGridGridLines.Both); + }); + + Assert.Contains("rz-grid-gridlines-both", component.Markup); + } + + [Fact] + public void Table_Renders_AllowAlternatingRows_True() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowAlternatingRows, true); + }); + + Assert.Contains("rz-grid-table-striped", component.Markup); + } + + [Fact] + public void Table_Renders_AllowAlternatingRows_False() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowAlternatingRows, false); + }); + + Assert.DoesNotContain("rz-grid-table-striped", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/TabsTests.cs b/Radzen.Blazor.Tests/TabsTests.cs new file mode 100644 index 00000000..f2a2f64a --- /dev/null +++ b/Radzen.Blazor.Tests/TabsTests.cs @@ -0,0 +1,108 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class TabsTests + { + [Fact] + public void Tabs_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-tabview", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPosition_Top() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.TabPosition, TabPosition.Top); + }); + + Assert.Contains("rz-tabview-top", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPosition_Bottom() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.TabPosition, TabPosition.Bottom); + }); + + Assert.Contains("rz-tabview-bottom", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPosition_Left() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.TabPosition, TabPosition.Left); + }); + + Assert.Contains("rz-tabview-left", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPosition_Right() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.TabPosition, TabPosition.Right); + }); + + Assert.Contains("rz-tabview-right", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPosition_TopRight() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.TabPosition, TabPosition.TopRight); + }); + + Assert.Contains("rz-tabview-top-right", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPosition_BottomRight() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.TabPosition, TabPosition.BottomRight); + }); + + Assert.Contains("rz-tabview-bottom-right", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabNav() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains("rz-tabview-nav", component.Markup); + } + + [Fact] + public void Tabs_Renders_TabPanels() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains("rz-tabview-panels", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/TimelineTests.cs b/Radzen.Blazor.Tests/TimelineTests.cs new file mode 100644 index 00000000..f8bb98e4 --- /dev/null +++ b/Radzen.Blazor.Tests/TimelineTests.cs @@ -0,0 +1,71 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class TimelineTests + { + [Fact] + public void Timeline_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-timeline", component.Markup); + } + + [Fact] + public void Timeline_Renders_Orientation() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Horizontal)); + Assert.Contains("rz-timeline-row", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Orientation, Orientation.Vertical)); + Assert.Contains("rz-timeline-column", component.Markup); + } + + [Fact] + public void Timeline_Renders_LinePosition() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.LinePosition, LinePosition.Start)); + Assert.Contains("rz-timeline-start", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.LinePosition, LinePosition.End)); + Assert.Contains("rz-timeline-end", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.LinePosition, LinePosition.Center)); + Assert.Contains("rz-timeline-center", component.Markup); + } + + [Fact] + public void Timeline_Renders_AlignItems() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlignItems, AlignItems.Start)); + Assert.Contains("rz-timeline-align-items-start", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.AlignItems, AlignItems.Center)); + Assert.Contains("rz-timeline-align-items-center", component.Markup); + } + + [Fact] + public void Timeline_Renders_Reverse() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Reverse, true)); + + Assert.Contains("rz-timeline-reverse", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/ToggleButtonTests.cs b/Radzen.Blazor.Tests/ToggleButtonTests.cs new file mode 100644 index 00000000..a88872a3 --- /dev/null +++ b/Radzen.Blazor.Tests/ToggleButtonTests.cs @@ -0,0 +1,98 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class ToggleButtonTests + { + [Fact] + public void ToggleButton_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-button", component.Markup); + } + + [Fact] + public void ToggleButton_Renders_TextParameter() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var text = "Toggle Me"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Text, text)); + + Assert.Contains(text, component.Markup); + } + + [Fact] + public void ToggleButton_Renders_IconParameter() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var icon = "toggle_on"; + component.SetParametersAndRender(parameters => parameters.Add(p => p.Icon, icon)); + + Assert.Contains(icon, component.Markup); + } + + [Fact] + public void ToggleButton_Renders_Value() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Value, true)); + + Assert.Contains("rz-state-active", component.Markup); + } + + [Fact] + public void ToggleButton_Renders_Disabled() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Disabled, true)); + + Assert.Contains("rz-state-disabled", component.Markup); + } + + [Fact] + public void ToggleButton_Renders_ButtonStyle() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.ButtonStyle, ButtonStyle.Primary)); + Assert.Contains("rz-primary", component.Markup); + + component.SetParametersAndRender(parameters => parameters.Add(p => p.ButtonStyle, ButtonStyle.Success)); + Assert.Contains("rz-success", component.Markup); + } + + [Fact] + public void ToggleButton_Raises_ChangeEvent() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + var changed = false; + bool newValue = false; + + component.SetParametersAndRender(parameters => parameters.Add(p => p.Change, args => + { + changed = true; + newValue = args; + })); + + component.Find("button").Click(); + + Assert.True(changed); + Assert.True(newValue); + } + } +} + diff --git a/Radzen.Blazor.Tests/TreeTests.cs b/Radzen.Blazor.Tests/TreeTests.cs new file mode 100644 index 00000000..81afefce --- /dev/null +++ b/Radzen.Blazor.Tests/TreeTests.cs @@ -0,0 +1,211 @@ +using Bunit; +using Xunit; +using System.Collections.Generic; +using System.Linq; + +namespace Radzen.Blazor.Tests +{ + public class TreeTests + { + class Category + { + public string Name { get; set; } + public List Products { get; set; } = new List(); + } + + class Product + { + public string Name { get; set; } + } + + class Employee + { + public string FirstName { get; set; } + public string LastName { get; set; } + public List Employees { get; set; } = new List(); + } + + [Fact] + public void Tree_Renders_WithClassName() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-tree", component.Markup); + } + + [Fact] + public void Tree_Renders_TreeContainer() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains("rz-tree-container", component.Markup); + } + + [Fact] + public void Tree_Renders_TabIndex() + { + using var ctx = new TestContext(); + var component = ctx.RenderComponent(); + + Assert.Contains("tabindex=\"0\"", component.Markup); + } + + [Fact] + public void Tree_Renders_WithData_SingleLevel() + { + using var ctx = new TestContext(); + var data = new List + { + new Category { Name = "Electronics" }, + new Category { Name = "Clothing" } + }; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Data, data); + parameters.Add(p => p.ChildContent, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "TextProperty", "Name"); + builder.CloseComponent(); + }); + }); + + Assert.Contains("Electronics", component.Markup); + Assert.Contains("Clothing", component.Markup); + } + + [Fact] + public void Tree_Renders_WithData_HierarchicalData() + { + using var ctx = new TestContext(); + var data = new List + { + new Category + { + Name = "Electronics", + Products = new List + { + new Product { Name = "Laptop" }, + new Product { Name = "Phone" } + } + } + }; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Data, data); + parameters.Add(p => p.ChildContent, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "TextProperty", "Name"); + builder.AddAttribute(2, "ChildrenProperty", "Products"); + builder.CloseComponent(); + + builder.OpenComponent(3); + builder.AddAttribute(4, "TextProperty", "Name"); + builder.AddAttribute(5, "HasChildren", (object product) => false); + builder.CloseComponent(); + }); + }); + + Assert.Contains("Electronics", component.Markup); + } + + [Fact] + public void Tree_Renders_WithData_SelfReferencing() + { + using var ctx = new TestContext(); + var data = new List + { + new Employee + { + FirstName = "Nancy", + LastName = "Davolio", + Employees = new List + { + new Employee { FirstName = "Andrew", LastName = "Fuller" } + } + } + }; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Data, data); + parameters.Add(p => p.ChildContent, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "TextProperty", "LastName"); + builder.AddAttribute(2, "ChildrenProperty", "Employees"); + builder.AddAttribute(3, "HasChildren", (object e) => (e as Employee).Employees.Any()); + builder.CloseComponent(); + }); + }); + + Assert.Contains("Davolio", component.Markup); + } + + [Fact] + public void Tree_Renders_WithCheckBoxes() + { + using var ctx = new TestContext(); + var data = new List + { + new Category { Name = "Electronics" } + }; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.AllowCheckBoxes, true); + parameters.Add(p => p.Data, data); + parameters.Add(p => p.ChildContent, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "TextProperty", "Name"); + builder.CloseComponent(); + }); + }); + + Assert.Contains("rz-chkbox", component.Markup); + } + + [Fact] + public void Tree_Renders_WithExpandableItems() + { + using var ctx = new TestContext(); + var data = new List + { + new Category + { + Name = "Electronics", + Products = new List + { + new Product { Name = "Laptop" } + } + } + }; + + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Data, data); + parameters.Add(p => p.ChildContent, builder => + { + builder.OpenComponent(0); + builder.AddAttribute(1, "TextProperty", "Name"); + builder.AddAttribute(2, "ChildrenProperty", "Products"); + builder.CloseComponent(); + + builder.OpenComponent(3); + builder.AddAttribute(4, "TextProperty", "Name"); + builder.CloseComponent(); + }); + }); + + // Expandable items should have a toggle icon + Assert.Contains("rz-tree-toggler", component.Markup); + } + } +} + diff --git a/Radzen.Blazor.Tests/UploadTests.cs b/Radzen.Blazor.Tests/UploadTests.cs new file mode 100644 index 00000000..e4306a32 --- /dev/null +++ b/Radzen.Blazor.Tests/UploadTests.cs @@ -0,0 +1,95 @@ +using Bunit; +using Xunit; + +namespace Radzen.Blazor.Tests +{ + public class UploadTests + { + [Fact] + public void Upload_Renders_WithClassName() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(); + + Assert.Contains(@"rz-fileupload", component.Markup); + } + + [Fact] + public void Upload_Renders_Disabled() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Disabled, true); + }); + + Assert.Contains("rz-state-disabled", component.Markup); + } + + [Fact] + public void Upload_Renders_ChooseText() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.ChooseText, "Select Files"); + }); + + Assert.Contains("Select Files", component.Markup); + } + + [Fact] + public void Upload_Renders_DefaultChooseText() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(); + + Assert.Contains("Choose", component.Markup); + } + + [Fact] + public void Upload_Renders_Icon() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Icon, "upload"); + }); + + Assert.Contains("upload", component.Markup); + Assert.Contains("rzi", component.Markup); + } + + [Fact] + public void Upload_Renders_Multiple_Attribute() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Multiple, true); + }); + + Assert.Contains("multiple", component.Markup); + } + + [Fact] + public void Upload_Renders_Accept_Attribute() + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + var component = ctx.RenderComponent(parameters => + { + parameters.Add(p => p.Accept, "image/*"); + }); + + Assert.Contains("accept=\"image/*\"", component.Markup); + } + } +} + diff --git a/all_components.txt b/all_components.txt new file mode 100644 index 00000000..3cd04cc0 Binary files /dev/null and b/all_components.txt differ