using Opc.Ua; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Server.OpcUa; namespace ZB.MOM.WW.OtOpcUa.Server.Tests; /// /// Regression for Server-004 — the production /// must surface the LDAP-resolved display /// name through , since /// DriverNodeManager.ResolveCallUser reads the base interface property when stamping /// audit identities on scripted-alarm Acknowledge / Confirm / Shelve calls. /// [Trait("Category", "Unit")] public sealed class RoleBasedIdentityTests { [Fact] public void DisplayName_returns_LDAP_resolved_display_name_when_present() { IUserIdentity identity = new OtOpcUaServer.RoleBasedIdentity( userName: "alice", displayName: "Alice Smith", roles: new[] { "WriteOperate" }, ldapGroups: new[] { "ot_operators" }); identity.DisplayName.ShouldBe("Alice Smith", "DriverNodeManager.ResolveCallUser reads IUserIdentity.DisplayName for audit entries; " + "RoleBasedIdentity must surface the LDAP-resolved name, not just the username."); } [Fact] public void DisplayName_falls_back_to_userName_when_LDAP_display_name_is_null() { IUserIdentity identity = new OtOpcUaServer.RoleBasedIdentity( userName: "alice", displayName: null, roles: [], ldapGroups: []); identity.DisplayName.ShouldBe("alice", "absent an LDAP display name, audit entries should still carry the username."); } [Fact] public void ResolveCallUser_yields_LDAP_resolved_display_name() { IUserIdentity identity = new OtOpcUaServer.RoleBasedIdentity( userName: "alice", displayName: "Alice Smith", roles: [], ldapGroups: []); DriverNodeManager.ResolveCallUser(identity).ShouldBe("Alice Smith"); } }