using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Configuration.Entities; using ZB.MOM.WW.OtOpcUa.Configuration.Enums; using ZB.MOM.WW.OtOpcUa.Security.Ldap; namespace ZB.MOM.WW.OtOpcUa.Security.Tests; public sealed class RoleMapperTests { /// /// Verifies that empty mapping returns no roles. /// [Fact] public void Empty_mapping_returns_empty() { RoleMapper.Map(new[] { "Admins" }, new Dictionary()) .ShouldBeEmpty(); } /// /// Verifies that RoleMapper maps a group to its corresponding role. /// [Fact] public void Maps_group_to_role() { RoleMapper.Map( new[] { "AdminGroup" }, new Dictionary { ["AdminGroup"] = "Administrator" }) .ShouldBe(new[] { "Administrator" }); } /// /// Verifies that group matching is case-insensitive. /// [Fact] public void Case_insensitive_group_match() { RoleMapper.Map( new[] { "admingroup" }, new Dictionary(StringComparer.OrdinalIgnoreCase) { ["AdminGroup"] = "Administrator", }) .ShouldBe(new[] { "Administrator" }); } /// /// Verifies that multiple groups are deduplicated to unique roles. /// [Fact] public void Multiple_groups_dedup_roles() { var roles = RoleMapper.Map( new[] { "AdminGroup", "AlsoAdmin" }, new Dictionary { ["AdminGroup"] = "Administrator", ["AlsoAdmin"] = "Administrator", }); roles.ShouldBe(new[] { "Administrator" }); } [Fact] public void Merge_unions_baseline_and_systemwide_db_roles() { var rows = new[] { new LdapGroupRoleMapping { LdapGroup = "g1", Role = AdminRole.Administrator, IsSystemWide = true }, new LdapGroupRoleMapping { LdapGroup = "g2", Role = AdminRole.Designer, IsSystemWide = false, ClusterId = "SITE-A" }, }; var result = RoleMapper.Merge(["Viewer"], rows); result.ShouldContain("Viewer"); result.ShouldContain("Administrator"); result.ShouldNotContain("Designer"); // cluster-scoped row ignored (global-only) } [Fact] public void Merge_with_no_db_rows_returns_baseline() => RoleMapper.Merge(["Administrator"], []).ShouldBe(["Administrator"]); }