using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser; namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests; /// /// Unit-only coverage of 's pre-connect /// validation. These tests do not require a live OPC UA endpoint and are safe to /// run without the opc-plc Docker fixture. /// [Trait("Category", "Unit")] public sealed class OpcUaClientDriverBrowserTests { private readonly OpcUaClientDriverBrowser _sut = new(); /// The DriverType key must match the AdminUI's persisted value. [Fact] public void DriverType_is_OpcUaClient() => _sut.DriverType.ShouldBe("OpcUaClient"); /// An empty endpoint must fail fast with a clear EndpointUrl-mentioning message. [Fact] public async Task OpenAsync_with_empty_endpoint_throws() { var json = """{"EndpointUrl":"","EndpointUrls":[]}"""; var ex = await Should.ThrowAsync( () => _sut.OpenAsync(json, TestContext.Current.CancellationToken)); ex.Message.ShouldContain("EndpointUrl"); } /// A JSON literal that deserializes to null must fail fast. [Fact] public async Task OpenAsync_with_null_json_throws() { var ex = await Should.ThrowAsync( () => _sut.OpenAsync("null", TestContext.Current.CancellationToken)); ex.Message.ShouldContain("null"); } /// Certificate auth is not supported by the browser; the failure message /// must say so explicitly rather than surfacing a downstream COM/SDK error. /// OpcUaAuthType.Certificate serializes as the numeric value 2 under the /// browser's default System.Text.Json options (no string-enum converter). [Fact] public async Task OpenAsync_with_certificate_auth_throws_clear_message() { var json = """{"EndpointUrl":"opc.tcp://127.0.0.1:1","AuthType":2}"""; var ex = await Should.ThrowAsync( () => _sut.OpenAsync(json, TestContext.Current.CancellationToken)); ex.Message.ShouldContain("Certificate"); } }