using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Runtime; namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests.Runtime; /// /// Pins the four-bucket MxAccess severity → (AlarmSeverity, OPC UA numeric) ladder. /// Customers see no surprise re-classification when the v2 path takes over from /// v1's sub-attribute synthesis: the bucket boundaries match v1's /// GalaxyAlarmTracker per docs/v1/AlarmTracking.md. /// public sealed class MxAccessSeverityMapperTests { [Theory] [InlineData(0, AlarmSeverity.Low, MxAccessSeverityMapper.OpcUaSeverityLow)] [InlineData(1, AlarmSeverity.Low, MxAccessSeverityMapper.OpcUaSeverityLow)] [InlineData(249, AlarmSeverity.Low, MxAccessSeverityMapper.OpcUaSeverityLow)] [InlineData(250, AlarmSeverity.Medium, MxAccessSeverityMapper.OpcUaSeverityMedium)] [InlineData(499, AlarmSeverity.Medium, MxAccessSeverityMapper.OpcUaSeverityMedium)] [InlineData(500, AlarmSeverity.High, MxAccessSeverityMapper.OpcUaSeverityHigh)] [InlineData(749, AlarmSeverity.High, MxAccessSeverityMapper.OpcUaSeverityHigh)] [InlineData(750, AlarmSeverity.Critical, MxAccessSeverityMapper.OpcUaSeverityCritical)] [InlineData(999, AlarmSeverity.Critical, MxAccessSeverityMapper.OpcUaSeverityCritical)] [InlineData(int.MaxValue, AlarmSeverity.Critical, MxAccessSeverityMapper.OpcUaSeverityCritical)] public void Map_assigns_expected_bucket(int rawMxAccessSeverity, AlarmSeverity expectedBucket, int expectedOpcUaSeverity) { var (bucket, opcUa) = MxAccessSeverityMapper.Map(rawMxAccessSeverity); bucket.ShouldBe(expectedBucket); opcUa.ShouldBe(expectedOpcUaSeverity); } [Fact] public void Map_clamps_negative_severities_into_low_bucket() { var (bucket, opcUa) = MxAccessSeverityMapper.Map(-100); bucket.ShouldBe(AlarmSeverity.Low); opcUa.ShouldBe(MxAccessSeverityMapper.OpcUaSeverityLow); } }