using CareFix.Api.Fixes; using CareFix.Api.Infrastructure; using Xunit; namespace CareFix.Tests; public class ApprovalRulesTests { private static ApprovalRow Approve(int userId, string role) => new() { ApproverId = userId, ApproverRole = role, Decision = "Approved" }; [Fact] public void Low_risk_needs_one_lead() { Assert.False(ApprovalRules.IsSatisfied("Low", [], false)); Assert.False(ApprovalRules.IsSatisfied("Low", [Approve(1, Roles.Engineer)], false)); Assert.False(ApprovalRules.IsSatisfied("Low", [Approve(1, Roles.ProductOwner)], false)); Assert.True(ApprovalRules.IsSatisfied("Low", [Approve(1, Roles.Lead)], false)); Assert.True(ApprovalRules.IsSatisfied("Low", [Approve(1, Roles.Head)], false)); } [Fact] public void Medium_risk_needs_two_different_people() { Assert.False(ApprovalRules.IsSatisfied("Medium", [Approve(1, Roles.Lead)], false)); Assert.False(ApprovalRules.IsSatisfied("Medium", [Approve(1, Roles.ProductOwner)], false)); Assert.True(ApprovalRules.IsSatisfied("Medium", [Approve(1, Roles.Lead), Approve(2, Roles.ProductOwner)], false)); Assert.True(ApprovalRules.IsSatisfied("Medium", [Approve(1, Roles.Head), Approve(2, Roles.Lead)], false)); } [Fact] public void One_head_cannot_count_as_both_approvals() { Assert.False(ApprovalRules.IsSatisfied("Medium", [Approve(7, Roles.Head)], false)); } [Fact] public void High_risk_needs_the_head_and_the_consent_file() { Assert.False(ApprovalRules.IsSatisfied("High", [Approve(1, Roles.Head)], hasConsent: false)); Assert.False(ApprovalRules.IsSatisfied("High", [Approve(1, Roles.Lead), Approve(2, Roles.ProductOwner)], hasConsent: true)); Assert.True(ApprovalRules.IsSatisfied("High", [Approve(1, Roles.Head)], hasConsent: true)); } [Fact] public void Rejections_never_count_as_approvals() { var rejected = new ApprovalRow { ApproverId = 1, ApproverRole = Roles.Head, Decision = "Rejected" }; Assert.False(ApprovalRules.IsSatisfied("Low", [rejected], false)); Assert.False(ApprovalRules.IsSatisfied("High", [rejected], true)); } [Theory] [InlineData("Low", Roles.Engineer, false)] [InlineData("Low", Roles.ProductOwner, false)] [InlineData("Low", Roles.Lead, true)] [InlineData("Medium", Roles.ProductOwner, true)] [InlineData("High", Roles.Lead, false)] [InlineData("High", Roles.ProductOwner, false)] [InlineData("High", Roles.Head, true)] [InlineData("High", Roles.Admin, false)] public void Only_the_right_roles_can_approve(string risk, string role, bool expected) => Assert.Equal(expected, ApprovalRules.CanApprove(role, risk)); } public class RiskRulesTests { [Theory] [InlineData("NET_AMT")] [InlineData("PHARMACY_AMT")] [InlineData("DISCOUNT_AMT")] [InlineData("QTY")] [InlineData("RATE")] [InlineData("PAID_AMOUNT")] [InlineData("refund_amt")] public void Money_and_quantity_columns_are_always_high_risk(string column) => Assert.True(RiskRules.IsAmountColumn(column)); [Theory] [InlineData("CANCEL_FLAG")] [InlineData("STATUS")] [InlineData("DISCHARGE_DATE")] [InlineData("UHID")] [InlineData("DOCTOR")] public void Other_columns_are_not(string column) => Assert.False(RiskRules.IsAmountColumn(column)); [Theory] [InlineData("Low", "Medium", "Medium")] [InlineData("High", "Low", "High")] [InlineData("Medium", "High", "High")] [InlineData("Low", "Low", "Low")] public void Risk_takes_the_higher_of_two(string a, string b, string expected) => Assert.Equal(expected, RiskRules.Max(a, b)); }