using System.Security.Claims; using Data.SeaHavenIndustries; using FluentAssertions; using Microsoft.Extensions.Options; using Moq; using SeaHaven.DataServices.Interfaces; using SeaHaven.Services.Configuration; using SeaHaven.Services.DTOs; using SeaHaven.Services.Implementation; using SeaHaven.Services.Interfaces; using Xunit; namespace Api.SeaHavenIndustries.Tests; public sealed class UpliftServiceRefusedTests { [Fact] public async Task RevokeAsync_DelegatesApprovedAdminRevocationToWorkOrderFlow() { var request = new DispatchUpliftRequest { Id = 7, DispatchId = 42, Status = "Approved", RequiredTier = 1, RequestedNTE = 900m }; var upliftData = new Mock(); upliftData.Setup(data => data.GetByIdAsync(7, It.IsAny())) .ReturnsAsync(request); upliftData.Setup(data => data.GetWorkOrderIdForUpliftAsync(7, It.IsAny())) .ReturnsAsync(77); var workOrderFlow = new Mock(); workOrderFlow.Setup(flow => flow.RevokeAsync( 77, 7, It.Is(r => r.Reason == "Policy change"), It.IsAny(), It.IsAny())) .ReturnsAsync(new WorkOrderUpliftDto { Id = 7, Status = "revoked" }); var service = new UpliftService( upliftData.Object, Mock.Of(), Mock.Of(), TimeProvider.System, Microsoft.Extensions.Options.Options.Create(new ApprovalsOptions()), workOrderFlow.Object); var user = new ClaimsPrincipal(new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, "admin-1"), new Claim(ClaimTypes.Role, "Admin") }, "test")); var result = await service.RevokeAsync(user, 7, " Policy change ", CancellationToken.None); result.Id.Should().Be(7); result.Status.Should().Be("Revoked"); workOrderFlow.Verify(flow => flow.RevokeAsync( 77, 7, It.Is(r => r.Reason == "Policy change"), It.IsAny(), It.IsAny()), Times.Once); } [Fact] public async Task ApproveAsync_RefusedDispatch_RejectsWithoutChangingNteOrRequest() { var request = new DispatchUpliftRequest { Id = 7, DispatchId = 42, Status = "Pending", RequiredTier = 1, RequestedNTE = 900m }; var dispatch = new Dispatch { Id = 42, Status = "Refused", NTEAmount = 500m, DispatchNumber = "DSP-42" }; var upliftData = new Mock(); upliftData.Setup(data => data.GetByIdAsync(7, It.IsAny())) .ReturnsAsync(request); var dispatchData = new Mock(); dispatchData.Setup(data => data.GetByIdAsync(42)).ReturnsAsync(dispatch); var service = new UpliftService( upliftData.Object, dispatchData.Object, Mock.Of(), TimeProvider.System, Microsoft.Extensions.Options.Options.Create( new ApprovalsOptions { Tier1Roles = new[] { "UpliftApprover" } })); var user = new ClaimsPrincipal(new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, "dispatcher-1"), new Claim(ClaimTypes.Role, "UpliftApprover") }, "test")); var act = () => service.ApproveAsync(user, 7, "approve", CancellationToken.None); await act.Should().ThrowAsync().WithMessage("*Refused*"); dispatch.NTEAmount.Should().Be(500m); request.Status.Should().Be("Pending"); dispatchData.Verify( data => data.StageAuditLogAsync(It.IsAny(), It.IsAny()), Times.Never); upliftData.Verify(data => data.SaveChangesAsync(It.IsAny()), Times.Never); } }