test(ui): failing bUnit tests for OpcUaEndpointEditor new sections

Adds 10 new tests covering:
- Authentication section label + Enable/Remove toggle (creates/nulls UserIdentity)
- TokenType conditional rendering: UsernamePassword shows Username/Password,
  X509Certificate shows Certificate path/password, Anonymous shows no extras
- Deadband Enable/Remove toggle
- Advanced Subscription section labels (Discard oldest, Subscription display
  name, Subscription priority, Timestamps to return)
- UserIdentity per-field error rendering under Username

9 new tests fail because the editor component hasn't been extended yet
(TDD red phase). Layer E2 implements the sections.
This commit is contained in:
Joseph Doherty
2026-05-12 02:28:47 -04:00
parent 8faaa8fe2b
commit f89f234558

View File

@@ -82,4 +82,149 @@ public class OpcUaEndpointEditorTests : BunitContext
Assert.Contains("alert-warning", cut.Markup); Assert.Contains("alert-warning", cut.Markup);
Assert.Contains("migrated from a legacy format", cut.Markup); Assert.Contains("migrated from a legacy format", cut.Markup);
} }
// ── Layer E: new editor sections ──
[Fact]
public void Renders_Authentication_Section_Label()
{
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, new OpcUaEndpointConfig()));
Assert.Contains("Authentication", cut.Markup);
}
[Fact]
public void EnableAuthentication_CreatesUserIdentitySubObject()
{
var config = new OpcUaEndpointConfig();
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
Assert.Null(config.UserIdentity);
cut.FindAll("button").First(b => b.TextContent.Contains("Enable Authentication")).Click();
Assert.NotNull(config.UserIdentity);
Assert.Equal(OpcUaUserTokenType.Anonymous, config.UserIdentity!.TokenType);
}
[Fact]
public void RemoveAuthentication_NullsUserIdentity()
{
var config = new OpcUaEndpointConfig
{
UserIdentity = new OpcUaUserIdentityConfig
{
TokenType = OpcUaUserTokenType.UsernamePassword,
Username = "alice",
Password = "secret"
}
};
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
cut.FindAll("button").First(b => b.TextContent.Contains("Remove Authentication")).Click();
Assert.Null(config.UserIdentity);
}
[Fact]
public void UsernamePassword_RendersUsernameAndPasswordInputs()
{
var config = new OpcUaEndpointConfig
{
UserIdentity = new OpcUaUserIdentityConfig
{
TokenType = OpcUaUserTokenType.UsernamePassword
}
};
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
Assert.Contains("Username", cut.Markup);
Assert.Contains("Password", cut.Markup);
Assert.DoesNotContain("Certificate path", cut.Markup);
}
[Fact]
public void X509Certificate_RendersCertificateFields()
{
var config = new OpcUaEndpointConfig
{
UserIdentity = new OpcUaUserIdentityConfig
{
TokenType = OpcUaUserTokenType.X509Certificate
}
};
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
Assert.Contains("Certificate path", cut.Markup);
Assert.Contains("Certificate password", cut.Markup);
Assert.DoesNotContain("Username", cut.Markup);
}
[Fact]
public void AnonymousTokenType_ShowsNoExtraFields()
{
var config = new OpcUaEndpointConfig
{
UserIdentity = new OpcUaUserIdentityConfig { TokenType = OpcUaUserTokenType.Anonymous }
};
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
Assert.DoesNotContain("Username", cut.Markup);
Assert.DoesNotContain("Certificate path", cut.Markup);
}
[Fact]
public void EnableDeadband_CreatesDeadbandSubObject()
{
var config = new OpcUaEndpointConfig();
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
Assert.Null(config.Deadband);
cut.FindAll("button").First(b => b.TextContent.Contains("Enable Deadband")).Click();
Assert.NotNull(config.Deadband);
}
[Fact]
public void RemoveDeadband_NullsDeadband()
{
var config = new OpcUaEndpointConfig
{
Deadband = new OpcUaDeadbandConfig { Type = OpcUaDeadbandType.Percent, Value = 1.5 }
};
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
cut.FindAll("button").First(b => b.TextContent.Contains("Remove Deadband")).Click();
Assert.Null(config.Deadband);
}
[Fact]
public void AdvancedSubscription_Section_Renders()
{
var config = new OpcUaEndpointConfig();
var cut = Render<OpcUaEndpointEditor>(p => p.Add(c => c.Config, config));
Assert.Contains("Discard oldest", cut.Markup);
Assert.Contains("Subscription display name", cut.Markup);
Assert.Contains("Subscription priority", cut.Markup);
Assert.Contains("Timestamps to return", cut.Markup);
}
[Fact]
public void UserIdentityError_RendersPerFieldUnderUsername()
{
var config = new OpcUaEndpointConfig
{
UserIdentity = new OpcUaUserIdentityConfig
{
TokenType = OpcUaUserTokenType.UsernamePassword,
Username = ""
}
};
var errors = OpcUaEndpointConfigValidator.Validate(config, "Primary.");
var cut = Render<OpcUaEndpointEditor>(p => p
.Add(c => c.Config, config)
.Add(c => c.Errors, errors));
Assert.Contains("Username is required", cut.Markup);
}
} }