shoc-backend/Api.SeaHavenIndustries.Tests/UpliftServiceRefusedTests.cs
2026-09-16 20:11:26 -03:00

117 lines
4.3 KiB
C#

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<IUpliftDataService>();
upliftData.Setup(data => data.GetByIdAsync(7, It.IsAny<CancellationToken>()))
.ReturnsAsync(request);
upliftData.Setup(data => data.GetWorkOrderIdForUpliftAsync(7, It.IsAny<CancellationToken>()))
.ReturnsAsync(77);
var workOrderFlow = new Mock<IWorkOrderUpliftService>();
workOrderFlow.Setup(flow => flow.RevokeAsync(
77,
7,
It.Is<RevokeWorkOrderUpliftRequestDto>(r => r.Reason == "Policy change"),
It.IsAny<ClaimsPrincipal>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync(new WorkOrderUpliftDto { Id = 7, Status = "revoked" });
var service = new UpliftService(
upliftData.Object,
Mock.Of<IDispatchDataService>(),
Mock.Of<IVendorDocumentStoragePort>(),
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<RevokeWorkOrderUpliftRequestDto>(r => r.Reason == "Policy change"),
It.IsAny<ClaimsPrincipal>(),
It.IsAny<CancellationToken>()), 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<IUpliftDataService>();
upliftData.Setup(data => data.GetByIdAsync(7, It.IsAny<CancellationToken>()))
.ReturnsAsync(request);
var dispatchData = new Mock<IDispatchDataService>();
dispatchData.Setup(data => data.GetByIdAsync(42)).ReturnsAsync(dispatch);
var service = new UpliftService(
upliftData.Object,
dispatchData.Object,
Mock.Of<IVendorDocumentStoragePort>(),
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<InvalidOperationException>().WithMessage("*Refused*");
dispatch.NTEAmount.Should().Be(500m);
request.Status.Should().Be("Pending");
dispatchData.Verify(
data => data.StageAuditLogAsync(It.IsAny<WorkOrderAuditLog>(), It.IsAny<CancellationToken>()),
Times.Never);
upliftData.Verify(data => data.SaveChangesAsync(It.IsAny<CancellationToken>()), Times.Never);
}
}