96 lines
4.0 KiB
C#
96 lines
4.0 KiB
C#
using Bunit;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using NSubstitute;
|
|
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms;
|
|
using ZB.MOM.WW.ScadaBridge.CentralUI.Services;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Components;
|
|
|
|
/// <summary>
|
|
/// Covers the M7-B8 (T17) "Verify endpoint" affordance added to
|
|
/// <see cref="OpcUaEndpointEditor"/>: a button that calls the injected
|
|
/// <see cref="IEndpointVerificationService"/> with the current endpoint config and
|
|
/// renders the typed <see cref="VerifyEndpointResult"/> — green on success, a red
|
|
/// failure line otherwise, and a read-only certificate panel when the failure is
|
|
/// <see cref="VerifyFailureKind.UntrustedCertificate"/> with a captured cert.
|
|
/// </summary>
|
|
public class OpcUaEndpointVerifyTests : BunitContext
|
|
{
|
|
private readonly IEndpointVerificationService _verify =
|
|
Substitute.For<IEndpointVerificationService>();
|
|
|
|
public OpcUaEndpointVerifyTests()
|
|
{
|
|
Services.AddSingleton(_verify);
|
|
}
|
|
|
|
private IRenderedComponent<OpcUaEndpointEditor> RenderEditor() =>
|
|
Render<OpcUaEndpointEditor>(p => p
|
|
.Add(c => c.Config, new OpcUaEndpointConfig { EndpointUrl = "opc.tcp://host:4840" })
|
|
.Add(c => c.SiteIdentifier, "plant-a")
|
|
.Add(c => c.ConnectionName, "PLC-OPC")
|
|
.Add(c => c.Protocol, "OpcUa"));
|
|
|
|
[Fact]
|
|
public void Verify_Success_ShowsSuccessMessage()
|
|
{
|
|
_verify.VerifyAsync(
|
|
Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(),
|
|
Arg.Any<OpcUaEndpointConfig>(), Arg.Any<CancellationToken>())
|
|
.Returns(new VerifyEndpointResult(true, null, null, null));
|
|
|
|
var cut = RenderEditor();
|
|
cut.Find("[data-test=verify-endpoint-btn]").Click();
|
|
|
|
Assert.NotEmpty(cut.FindAll("[data-test=verify-success]"));
|
|
Assert.Empty(cut.FindAll("[data-test=verify-failure]"));
|
|
Assert.Empty(cut.FindAll("[data-test=verify-cert-panel]"));
|
|
}
|
|
|
|
[Fact]
|
|
public void Verify_UntrustedCertificate_ShowsCertPanelWithThumbprint()
|
|
{
|
|
var cert = new ServerCertInfo(
|
|
Thumbprint: "ABCDEF0123456789",
|
|
Subject: "CN=opc-server",
|
|
Issuer: "CN=opc-server",
|
|
NotBeforeUtc: new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
|
NotAfterUtc: new DateTime(2027, 1, 1, 0, 0, 0, DateTimeKind.Utc),
|
|
DerBase64: "ZGVy");
|
|
_verify.VerifyAsync(
|
|
Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(),
|
|
Arg.Any<OpcUaEndpointConfig>(), Arg.Any<CancellationToken>())
|
|
.Returns(new VerifyEndpointResult(
|
|
false, VerifyFailureKind.UntrustedCertificate, "Untrusted certificate.", cert));
|
|
|
|
var cut = RenderEditor();
|
|
cut.Find("[data-test=verify-endpoint-btn]").Click();
|
|
|
|
var panel = cut.Find("[data-test=verify-cert-panel]");
|
|
Assert.Contains("ABCDEF0123456789", panel.TextContent);
|
|
Assert.Contains("CN=opc-server", panel.TextContent);
|
|
// The failure line is still shown alongside the cert panel.
|
|
Assert.NotEmpty(cut.FindAll("[data-test=verify-failure]"));
|
|
}
|
|
|
|
[Fact]
|
|
public void Verify_GenericFailure_ShowsFailureMessage()
|
|
{
|
|
_verify.VerifyAsync(
|
|
Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(),
|
|
Arg.Any<OpcUaEndpointConfig>(), Arg.Any<CancellationToken>())
|
|
.Returns(new VerifyEndpointResult(
|
|
false, VerifyFailureKind.Unreachable, "Connection refused.", null));
|
|
|
|
var cut = RenderEditor();
|
|
cut.Find("[data-test=verify-endpoint-btn]").Click();
|
|
|
|
var failure = cut.Find("[data-test=verify-failure]");
|
|
Assert.Contains("Connection refused.", failure.TextContent);
|
|
Assert.Empty(cut.FindAll("[data-test=verify-success]"));
|
|
Assert.Empty(cut.FindAll("[data-test=verify-cert-panel]"));
|
|
}
|
|
}
|