using System.Security.Claims; using ZB.MOM.WW.ScadaBridge.Security; using Bunit; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.Extensions.DependencyInjection; using NSubstitute; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates; using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories; using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Services; using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared; using ZB.MOM.WW.ScadaBridge.TemplateEngine; using ZB.MOM.WW.ScadaBridge.TemplateEngine.Services; using TemplatesPage = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Design.Templates; namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests; /// /// bUnit rendering tests for the Templates page that verify the folder/template /// tree builds the expected DOM for the main shape categories: empty state, /// folder-containing-template nesting, and composition leaves under their owner. /// public class TemplatesPageTests : BunitContext { private readonly ITemplateEngineRepository _repo = Substitute.For(); private readonly IAuditService _audit = Substitute.For(); public TemplatesPageTests() { // The page's TemplateService / TemplateFolderService are constructed via DI // from the repository and audit service, mirroring real Host wiring. Services.AddSingleton(_repo); Services.AddSingleton(_audit); Services.AddScoped(); Services.AddScoped(); // The Templates page injects IDialogService for the new-folder prompt // and delete confirmations. The host is rendered in MainLayout, not // here, but the DI registration still has to satisfy the [Inject]. Services.AddScoped(); AddTestAuth(); // The TreeView inside the page persists expansion state via JS interop // against sessionStorage (`templates-tree` key). bUnit requires explicit // stubs for all JS interop calls, otherwise rendering throws. JSInterop.Setup("treeviewStorage.load", _ => true).SetResult(null); JSInterop.SetupVoid("treeviewStorage.save", _ => true); } private void AddTestAuth() { // The page resolves the current user via the "Username" claim in // GetCurrentUserAsync(); supply a stub so OnInitializedAsync doesn't crash. var claims = new[] { new Claim(JwtTokenService.UsernameClaimType, "tester"), new Claim(JwtTokenService.RoleClaimType, "Designer") }; var identity = new ClaimsIdentity(claims, "TestAuth"); var user = new ClaimsPrincipal(identity); Services.AddSingleton(new TestAuthStateProvider(user)); Services.AddAuthorizationCore(); } [Fact] public void Renders_EmptyState_WhenNoTemplatesOrFolders() { _repo.GetAllTemplatesAsync(Arg.Any()) .Returns(Task.FromResult>(new List