using Opc.Ua; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers; namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Tests.Helpers; public class HistoryReadStatusTests { public static IEnumerable Refusals() => new[] { StatusCodes.BadHistoryOperationUnsupported, StatusCodes.BadUserAccessDenied, StatusCodes.BadNodeIdUnknown, StatusCodes.BadTimeout }.Select(s => new object[] { s }); public static IEnumerable NonRefusals() => new[] { StatusCodes.Good, StatusCodes.GoodNoData, StatusCodes.GoodMoreData, StatusCodes.UncertainNoCommunicationLastUsableValue, StatusCodes.BadNoData }.Select(s => new object[] { s }); /// A refused read must surface, carrying the status code, rather than read as an empty result. /// The Bad per-node status code. [Theory] [MemberData(nameof(Refusals))] public void Bad_status_throws_ServiceResultException_with_the_code(StatusCode code) { var ex = Should.Throw( () => HistoryReadStatus.ThrowIfRefused(code, new NodeId("n", 2))); ex.StatusCode.ShouldBe(code.Code); ex.Message.ShouldContain("ns=2;s=n"); } /// Good, GoodNoData, Uncertain and BadNoData are all non-refusals (the window may simply be empty). /// The non-refusal status code. [Theory] [MemberData(nameof(NonRefusals))] public void Non_refusal_status_does_not_throw(StatusCode code) { Should.NotThrow(() => HistoryReadStatus.ThrowIfRefused(code, new NodeId("n", 2))); } }