feat(m9/T22): template tree search box (wire TemplateFolderTree.Filter)

This commit is contained in:
Joseph Doherty
2026-06-18 10:35:35 -04:00
parent efcdd18794
commit f618ac0322
2 changed files with 70 additions and 1 deletions
@@ -127,6 +127,55 @@ public class TemplatesPageTests : BunitContext
Assert.Contains("bi-arrow-return-right", cut.Markup);
}
[Fact]
public void SearchBox_IsPresentAndBound_ToTemplateFolderTreeFilter()
{
// Seed two templates in the same folder so we can confirm the filter narrows
// the visible set and that clearing the input restores the full tree.
var folder = new TemplateFolder("Controllers") { Id = 1 };
var alpha = new Template("AlphaDevice") { Id = 10, FolderId = 1 };
var beta = new Template("BetaDevice") { Id = 20, FolderId = 1 };
_repo.GetAllTemplatesAsync(Arg.Any<CancellationToken>())
.Returns(Task.FromResult<IReadOnlyList<Template>>(new List<Template> { alpha, beta }));
_repo.GetAllFoldersAsync(Arg.Any<CancellationToken>())
.Returns(Task.FromResult<IReadOnlyList<TemplateFolder>>(new List<TemplateFolder> { folder }));
var cut = Render<TemplatesPage>();
// 1. A search input must exist in the rendered output.
var search = cut.Find("input[type='text'][placeholder*='earch']");
Assert.NotNull(search);
// 2. Typing a substring hides non-matching templates. The TemplateFolderTree
// filter auto-expands ancestors of matches via its _initiallyExpanded hook,
// so "AlphaDevice" appears without a manual toggle click. "BetaDevice" is
// absent from the filtered tree entirely.
search.Input("Alpha");
Assert.Contains("AlphaDevice", cut.Markup);
Assert.DoesNotContain("BetaDevice", cut.Markup);
// 3. Clearing the input restores the full tree. The folder may now be collapsed
// (prior expansion state is stored per-key; after filter-clear the tree uses
// saved state). Expand manually to verify both templates are reachable.
search.Input("");
// Both templates must be in the tree; expand the folder if needed.
var folderToggleAfter = cut.FindAll("li[role='treeitem']")
.FirstOrDefault(li => li.TextContent.Contains("Controllers"))
?.QuerySelector(".tv-toggle");
// Only click if the folder is not yet expanded (aria-expanded='false').
var folderLi = cut.FindAll("li[role='treeitem']")
.FirstOrDefault(li => li.TextContent.Contains("Controllers"));
if (folderLi?.GetAttribute("aria-expanded") != "true")
folderToggleAfter?.Click();
Assert.Contains("AlphaDevice", cut.Markup);
Assert.Contains("BetaDevice", cut.Markup);
}
}
internal sealed class TestAuthStateProvider : AuthenticationStateProvider