using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Moq; using ROLAC.API.Authorization; using ROLAC.API.Services; using Xunit; namespace ROLAC.API.Tests.Authorization; public class PermissionAuthorizationHandlerTests { private static ClaimsPrincipal UserWithRoles(params string[] roles) { var claims = roles.Select(role => new Claim("role", role)); return new ClaimsPrincipal(new ClaimsIdentity(claims, authenticationType: "test")); } private static async Task EvaluateAsync( ClaimsPrincipal user, PermissionRequirement requirement, IPermissionService permissions) { var handler = new PermissionAuthorizationHandler(permissions); var context = new AuthorizationHandlerContext([requirement], user, resource: null); await handler.HandleAsync(context); return context.HasSucceeded; } [Fact] public async Task SuperAdmin_AlwaysSucceeds_WithoutConsultingMatrix() { var permissions = new Mock(MockBehavior.Strict); // must NOT be called var requirement = new PermissionRequirement(Modules.Members, PermissionActions.Delete); var succeeded = await EvaluateAsync(UserWithRoles("super_admin"), requirement, permissions.Object); Assert.True(succeeded); permissions.Verify(p => p.HasPermissionAsync(It.IsAny>(), It.IsAny(), It.IsAny()), Times.Never); } [Fact] public async Task RoleWithPermission_Succeeds() { var permissions = new Mock(); permissions.Setup(p => p.HasPermissionAsync(It.IsAny>(), Modules.Members, PermissionActions.Write)) .ReturnsAsync(true); var requirement = new PermissionRequirement(Modules.Members, PermissionActions.Write); var succeeded = await EvaluateAsync(UserWithRoles("secretary"), requirement, permissions.Object); Assert.True(succeeded); } [Fact] public async Task RoleWithoutPermission_Fails() { var permissions = new Mock(); permissions.Setup(p => p.HasPermissionAsync(It.IsAny>(), It.IsAny(), It.IsAny())) .ReturnsAsync(false); var requirement = new PermissionRequirement(Modules.Givings, PermissionActions.Write); var succeeded = await EvaluateAsync(UserWithRoles("member"), requirement, permissions.Object); Assert.False(succeeded); } }