using System.Collections.Generic; using System.Linq; using Opc.Ua; using Shouldly; using Xunit; using ZB.MOM.WW.LmxOpcUa.Host.OpcUa; namespace ZB.MOM.WW.LmxOpcUa.Tests.Security { public class SecurityProfileResolverTests { [Fact] public void Resolve_DefaultNone_ReturnsSingleNonePolicy() { var result = SecurityProfileResolver.Resolve(new List { "None" }); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.None); result[0].SecurityPolicyUri.ShouldBe(SecurityPolicies.None); } [Fact] public void Resolve_SignProfile_ReturnsBasic256Sha256Sign() { var result = SecurityProfileResolver.Resolve(new List { "Basic256Sha256-Sign" }); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.Sign); result[0].SecurityPolicyUri.ShouldBe(SecurityPolicies.Basic256Sha256); } [Fact] public void Resolve_SignAndEncryptProfile_ReturnsBasic256Sha256SignAndEncrypt() { var result = SecurityProfileResolver.Resolve(new List { "Basic256Sha256-SignAndEncrypt" }); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.SignAndEncrypt); result[0].SecurityPolicyUri.ShouldBe(SecurityPolicies.Basic256Sha256); } [Fact] public void Resolve_MultipleProfiles_ReturnsExpectedPolicies() { var result = SecurityProfileResolver.Resolve(new List { "None", "Basic256Sha256-Sign", "Basic256Sha256-SignAndEncrypt" }); result.Count.ShouldBe(3); result.ShouldContain(p => p.SecurityMode == MessageSecurityMode.None); result.ShouldContain(p => p.SecurityMode == MessageSecurityMode.Sign); result.ShouldContain(p => p.SecurityMode == MessageSecurityMode.SignAndEncrypt); } [Fact] public void Resolve_DuplicateProfiles_Deduplicated() { var result = SecurityProfileResolver.Resolve(new List { "None", "None", "Basic256Sha256-Sign", "Basic256Sha256-Sign" }); result.Count.ShouldBe(2); } [Fact] public void Resolve_UnknownProfile_SkippedWithWarning() { var result = SecurityProfileResolver.Resolve(new List { "None", "SomeUnknownProfile" }); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.None); } [Fact] public void Resolve_EmptyList_FallsBackToNone() { var result = SecurityProfileResolver.Resolve(new List()); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.None); result[0].SecurityPolicyUri.ShouldBe(SecurityPolicies.None); } [Fact] public void Resolve_NullList_FallsBackToNone() { var result = SecurityProfileResolver.Resolve(null!); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.None); } [Fact] public void Resolve_AllUnknownProfiles_FallsBackToNone() { var result = SecurityProfileResolver.Resolve(new List { "Bogus", "AlsoBogus" }); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.None); } [Fact] public void Resolve_CaseInsensitive() { var result = SecurityProfileResolver.Resolve(new List { "none", "BASIC256SHA256-SIGN" }); result.Count.ShouldBe(2); result.ShouldContain(p => p.SecurityMode == MessageSecurityMode.None); result.ShouldContain(p => p.SecurityMode == MessageSecurityMode.Sign); } [Fact] public void Resolve_WhitespaceEntries_Skipped() { var result = SecurityProfileResolver.Resolve(new List { "", " ", "None" }); result.Count.ShouldBe(1); result[0].SecurityMode.ShouldBe(MessageSecurityMode.None); } [Fact] public void ValidProfileNames_ContainsExpectedEntries() { var names = SecurityProfileResolver.ValidProfileNames; names.ShouldContain("None"); names.ShouldContain("Basic256Sha256-Sign"); names.ShouldContain("Basic256Sha256-SignAndEncrypt"); names.Count.ShouldBe(3); } } }