Files
scadaproj/ZB.MOM.WW.Theme/tests/ZB.MOM.WW.Theme.Tests/LoginCardTests.cs
T
Joseph Doherty 0e41e7c2e4 fix(theme): resolve nav/login kit issues + bump 0.2.1 -> 0.3.0
Addresses ZB.MOM.WW.Theme/themeissues.md:
- #1 NavRailSection <summary> renders aria-expanded (SSR from Expanded),
  kept in sync by nav-state.js on restore + toggle.
- #2 nav-state.js auto-expands the section holding a.rail-link.active
  (transient via data-zbnav-transient — does not overwrite saved state).
- #3 nav-state.js re-applies on Blazor 'enhancedload' (idempotent via
  per-element init guard).
- #5 LoginCard wraps product in span.login-product + optional Heading
  override param.
- #4 documented as an accepted client-only-persistence tradeoff (no code change).

+4 bUnit tests (48 total, all green).
2026-06-05 04:42:24 -04:00

69 lines
2.5 KiB
C#

namespace ZB.MOM.WW.Theme.Tests;
public class LoginCardTests : TestContext
{
[Fact]
public void Posts_to_action_with_username_password_fields()
{
var cut = RenderComponent<LoginCard>(p => p
.Add(x => x.Product, "OtOpcUa")
.Add(x => x.Action, "/auth/login"));
var form = cut.Find("form");
Assert.Equal("post", form.GetAttribute("method"));
Assert.Equal("/auth/login", form.GetAttribute("action"));
Assert.NotNull(cut.Find("input#username"));
Assert.NotNull(cut.Find("input#password"));
Assert.Contains("OtOpcUa", cut.Find(".login-title").TextContent);
}
[Fact]
public void ReturnUrl_renders_hidden_input()
{
var cut = RenderComponent<LoginCard>(p => p
.Add(x => x.Product, "OtOpcUa")
.Add(x => x.ReturnUrl, "/clusters"));
var hidden = cut.Find("input[name=returnUrl]");
Assert.Equal("/clusters", hidden.GetAttribute("value"));
}
[Fact]
public void Error_renders_notice()
{
var cut = RenderComponent<LoginCard>(p => p
.Add(x => x.Product, "OtOpcUa")
.Add(x => x.Error, "Bad credentials"));
Assert.Contains("Bad credentials", cut.Find(".notice").TextContent);
}
[Fact]
public void No_returnUrl_no_hidden_input()
{
var cut = RenderComponent<LoginCard>(p => p.Add(x => x.Product, "OtOpcUa"));
Assert.Empty(cut.FindAll("input[name=returnUrl]"));
}
// Theme issue #5: the product token is isolated in a .login-product span so it
// can be styled/asserted apart from the "— sign in" suffix.
[Fact]
public void Product_is_wrapped_in_login_product_span()
{
var cut = RenderComponent<LoginCard>(p => p.Add(x => x.Product, "OtOpcUa"));
var product = cut.Find(".login-title .login-product");
Assert.Equal("OtOpcUa", product.TextContent);
Assert.Contains("sign in", cut.Find(".login-title").TextContent);
}
// Theme issue #5: Heading replaces the whole heading copy when set.
[Fact]
public void Heading_overrides_default_heading_when_set()
{
var cut = RenderComponent<LoginCard>(p => p
.Add(x => x.Product, "OtOpcUa")
.Add(x => x.Heading, "Welcome back"));
var title = cut.Find(".login-title");
Assert.Equal("Welcome back", title.TextContent);
Assert.Empty(cut.FindAll(".login-title .login-product"));
Assert.DoesNotContain("sign in", title.TextContent);
}
}