using Data.SeaHavenIndustries.Enums; using FluentAssertions; using SeaHaven.Services.Constants; using SeaHaven.Services.Implementation; using Xunit; namespace SeaHaven.Services.Tests; public class TeamPermissionPolicyTests { private static readonly string[] DispatcherKeys = { TeamPermissionKeys.CreateVendors, TeamPermissionKeys.EditVendors, TeamPermissionKeys.DeactivateVendors, TeamPermissionKeys.CreateSites, TeamPermissionKeys.EditSites, TeamPermissionKeys.CreateWorkOrders, TeamPermissionKeys.EditOthersWorkOrders, TeamPermissionKeys.CancelWorkOrders, TeamPermissionKeys.RequestUplifts, TeamPermissionKeys.AutoApproveUplifts }; private static readonly string[] SchedulerOnlyKeys = { TeamPermissionKeys.DeleteSites, TeamPermissionKeys.CreateServices, TeamPermissionKeys.EditServices, TeamPermissionKeys.CreateCompletionDocTemplates, TeamPermissionKeys.EditCompletionDocTemplates, TeamPermissionKeys.ViewAllDispatchersOnDashboard }; private static readonly string[] AdminOnlyKeys = { TeamPermissionKeys.ManageTeamMembers, TeamPermissionKeys.ChangeTeamMemberRole, TeamPermissionKeys.DeactivateServices, TeamPermissionKeys.DeleteCompletionDocTemplates, TeamPermissionKeys.DeleteWorkOrders, TeamPermissionKeys.ReviewUplifts }; private static IReadOnlyDictionary Overrides( string key, UserPermissionState state) => new Dictionary(StringComparer.OrdinalIgnoreCase) { [key] = state }; [Fact] public void Registry_Exposes_Exactly_The_22_Prototype_Keys() { TeamPermissionKeys.All.Should().HaveCount(22); TeamPermissionKeys.KnownKeys.Should().HaveCount(22); TeamPermissionKeys.All.Should().OnlyHaveUniqueItems(); TeamPermissionKeys.All.Should().OnlyContain(key => !string.IsNullOrWhiteSpace(key)); TeamPermissionKeys.All.Should().BeEquivalentTo(new[] { "manageTeamMembers", "changeTeamMemberRole", "createVendors", "editVendors", "deactivateVendors", "createSites", "editSites", "deleteSites", "createServices", "editServices", "deactivateServices", "createCompletionDocTemplates", "editCompletionDocTemplates", "deleteCompletionDocTemplates", "createWorkOrders", "editOthersWorkOrders", "cancelWorkOrders", "deleteWorkOrders", "requestUplifts", "autoApproveUplifts", "reviewUplifts", "viewAllDispatchersOnDashboard" }); } [Fact] public void Registry_IsKnown_Is_Case_Insensitive_And_Rejects_Unknown_Keys() { TeamPermissionKeys.IsKnown("CREATEVENDORS").Should().BeTrue(); TeamPermissionKeys.IsKnown("autoApproveUplifts").Should().BeTrue(); TeamPermissionKeys.IsKnown("nope.unknown").Should().BeFalse(); TeamPermissionKeys.IsKnown("").Should().BeFalse(); TeamPermissionKeys.IsKnown(null).Should().BeFalse(); } [Fact] public void Dispatcher_Gets_Exactly_Prototype_Defaults() { var policy = new TeamPermissionPolicy(); foreach (var key in TeamPermissionKeys.All) { var expected = DispatcherKeys.Contains(key, StringComparer.Ordinal); policy.IsAllowed("Dispatcher", key).Should().Be(expected, $"Dispatcher default for '{key}' should be {expected}"); } } [Fact] public void Scheduler_Gets_Exactly_Prototype_Defaults() { var policy = new TeamPermissionPolicy(); foreach (var key in TeamPermissionKeys.All) { var expected = SchedulerOnlyKeys.Contains(key, StringComparer.Ordinal) || DispatcherKeys.Contains(key, StringComparer.Ordinal) && key is not TeamPermissionKeys.RequestUplifts && key is not TeamPermissionKeys.AutoApproveUplifts; policy.IsAllowed("Scheduler", key).Should().Be(expected, $"Scheduler default for '{key}' should be {expected}"); } } [Fact] public void Admin_Has_Effective_Access_To_Every_Key() { var policy = new TeamPermissionPolicy(); foreach (var key in TeamPermissionKeys.All) policy.IsAllowed("Admin", key).Should().BeTrue($"Admin should hold '{key}'"); } [Fact] public void Role_Recognition_Is_Case_Insensitive() { var policy = new TeamPermissionPolicy(); policy.IsAllowed("dIsPaTcHeR", TeamPermissionKeys.CreateVendors).Should().BeTrue(); policy.IsAllowed("SCHEDULER", TeamPermissionKeys.DeleteSites).Should().BeTrue(); policy.IsAllowed("admin", TeamPermissionKeys.ReviewUplifts).Should().BeTrue(); policy.IsAllowed("dIsPaTcHeR", TeamPermissionKeys.DeleteSites).Should().BeFalse(); policy.IsAllowed("SCHEDULER", TeamPermissionKeys.AutoApproveUplifts).Should().BeFalse(); } [Theory] [InlineData("Manager")] [InlineData("OfficeAdmin")] [InlineData("")] [InlineData(null)] public void Unknown_And_Legacy_Roles_Receive_No_Permissions(string? role) { var policy = new TeamPermissionPolicy(); foreach (var key in TeamPermissionKeys.All) policy.IsAllowed(role, key).Should().BeFalse( $"unknown/legacy role '{role}' must not hold '{key}'"); } [Fact] public void Unknown_Role_Gains_Nothing_Even_With_Allow_Overrides() { var policy = new TeamPermissionPolicy(); foreach (var key in TeamPermissionKeys.All) policy.IsAllowed("Manager", key, Overrides(key, UserPermissionState.Allow)) .Should().BeFalse($"an unknown role must not be elevated via '{key}'"); } [Fact] public void Allow_Override_Grants_Key_Outside_Role_Default() { var policy = new TeamPermissionPolicy(); policy.IsAllowed("Scheduler", TeamPermissionKeys.RequestUplifts) .Should().BeFalse(); policy.IsAllowed( "Scheduler", TeamPermissionKeys.RequestUplifts, Overrides(TeamPermissionKeys.RequestUplifts, UserPermissionState.Allow)) .Should().BeTrue(); } [Fact] public void Deny_Override_Removes_Key_Inside_Role_Default() { var policy = new TeamPermissionPolicy(); policy.IsAllowed("Dispatcher", TeamPermissionKeys.CreateVendors) .Should().BeTrue(); policy.IsAllowed( "Dispatcher", TeamPermissionKeys.CreateVendors, Overrides(TeamPermissionKeys.CreateVendors, UserPermissionState.Deny)) .Should().BeFalse(); } [Fact] public void Unset_Override_And_Missing_Row_Fall_Back_To_Role_Default() { var policy = new TeamPermissionPolicy(); policy.IsAllowed( "Dispatcher", TeamPermissionKeys.CreateWorkOrders, Overrides(TeamPermissionKeys.CreateWorkOrders, UserPermissionState.Unset)) .Should().BeTrue(); policy.IsAllowed( "Scheduler", TeamPermissionKeys.RequestUplifts, Overrides(TeamPermissionKeys.RequestUplifts, UserPermissionState.Unset)) .Should().BeFalse(); policy.IsAllowed( "Scheduler", TeamPermissionKeys.RequestUplifts, new Dictionary()) .Should().BeFalse(); } [Fact] public void Admin_Is_Immune_To_Overrides() { var policy = new TeamPermissionPolicy(); foreach (var key in TeamPermissionKeys.All) { policy.IsAllowed("Admin", key, Overrides(key, UserPermissionState.Deny)) .Should().BeTrue($"Admin must keep '{key}' despite a Deny override"); policy.IsAllowed("ADMIN", key, Overrides(key, UserPermissionState.Unset)) .Should().BeTrue(); } } [Fact] public void Unknown_Permission_Key_Is_Denied_For_Every_Role() { var policy = new TeamPermissionPolicy(); policy.IsAllowed("Admin", "nope.unknown").Should().BeFalse(); policy.IsAllowed("Dispatcher", "nope.unknown").Should().BeFalse(); policy.IsAllowed("Admin", "nope.unknown", Overrides("nope.unknown", UserPermissionState.Allow)) .Should().BeFalse(); } }