namespace ZB.MOM.WW.Theme.Tests; public sealed class TreeTableTests : BunitContext { private sealed record TestRow(string Key, int Depth, bool HasChildren, string Name) : ITreeRow; private IRenderedComponent> RenderTreeTable(IReadOnlyList rows, IReadOnlySet? collapsed = null, Action? toggle = null) => Render>(p => p .Add(x => x.Rows, rows) .Add(x => x.Collapsed, collapsed ?? new HashSet()) .Add(x => x.Label, row => row.Name) .Add(x => x.Head, builder => builder.AddMarkupContent(0, "ScopeValue")) .Add(x => x.Row, row => builder => { builder.OpenElement(0, "td"); builder.AddContent(1, "Value for " + row.Name); builder.CloseElement(); }) .Add(x => x.OnToggle, key => toggle?.Invoke(key))); [Fact] public void Caller_fragments_and_arbitrary_depth_are_rendered_without_inline_stylesheets() { var cut = RenderTreeTable([new("root", 0, true, "Site"), new("deep", 7, false, "Machine <7>")]); Assert.Equal(2, cut.FindAll("thead th").Count); Assert.Equal(2, cut.FindAll("tbody tr").Count); Assert.Equal("Value for Machine <7>", cut.FindAll("tbody td")[3].TextContent); Assert.Contains("Machine <7>", cut.Find(".tt-d7 .tt-name").TextContent); Assert.Contains("--tt-depth: 7", cut.Find(".tt-d7 .tt-name").GetAttribute("style")); Assert.Empty(cut.FindAll("style")); } [Fact] public void Leaf_keeps_alignment_without_promising_a_subtree() { var cut = RenderTreeTable([new("leaf", 1, false, "Cell")]); var twist = cut.Find("button"); Assert.Contains("tt-leaf", twist.ClassList); Assert.True(twist.HasAttribute("disabled")); Assert.False(twist.HasAttribute("aria-expanded")); Assert.False(twist.HasAttribute("aria-label")); Assert.Equal("true", cut.Find("i").GetAttribute("aria-hidden")); } [Fact] public void Toggle_reports_stable_key_and_caller_controls_expansion() { string? toggled = null; var cut = RenderTreeTable([new("site-key", 0, true, "Site")], new HashSet { "site-key" }, key => toggled = key); Assert.Equal("false", cut.Find("button").GetAttribute("aria-expanded")); Assert.Equal("Expand Site", cut.Find("button").GetAttribute("aria-label")); cut.Find("button").Click(); Assert.Equal("site-key", toggled); Assert.Equal("false", cut.Find("button").GetAttribute("aria-expanded")); cut.Render(p => p.Add(x => x.Collapsed, new HashSet())); Assert.Equal("true", cut.Find("button").GetAttribute("aria-expanded")); Assert.Equal("Collapse Site", cut.Find("button").GetAttribute("aria-label")); Assert.Contains("bi-chevron-down", cut.Find("i").ClassList); } [Fact] public void Empty_rows_keep_the_header_and_empty_body() { var cut = RenderTreeTable([]); Assert.Equal(2, cut.FindAll("thead th").Count); Assert.Empty(cut.FindAll("tbody tr")); } }