test(uplifts): cover escalation audit on a dispatch without an owning work order

This commit is contained in:
Alexandre Brandizzi 2026-09-24 23:37:58 -03:00
parent c5d82a996a
commit b2b9fc3588

View file

@ -162,10 +162,61 @@ public sealed class UpliftDecisionAuditRelationalTests
Assert.Empty(audits);
}
[Theory]
[InlineData(Ownership.Linked)]
[InlineData(Ownership.Unresolvable)]
public async Task Escalation_CommitsAndAuditsResolvedWorkOrder(Ownership ownership)
{
await using var connection = new SqliteConnection("Data Source=:memory:;Foreign Keys=True");
await connection.OpenAsync();
var options = new DbContextOptionsBuilder<ApplicationDbContext>().UseSqlite(connection).Options;
int upliftId;
int? expectedWorkOrderId;
await using (var seed = new SqliteUpliftDecisionTestDbContext(options))
{
await seed.Database.EnsureCreatedAsync();
(upliftId, expectedWorkOrderId) = await SeedAsync(
seed,
ownership,
expiresAt: null,
initialNotificationSentAt: DateTime.UtcNow.AddDays(-3));
}
var emailSender = new NoEmailSender();
await using (var context = new SqliteUpliftDecisionTestDbContext(options))
{
var lifecycle = new UpliftLifecycleService(
new UpliftDataService(context),
new DispatchDataService(context),
null!,
emailSender,
Options.Create(new FrontendOptions()),
Options.Create(new ApprovalsOptions { EscalationRecipients = new[] { "escalate@test.local" } }),
TimeProvider.System,
NullLogger<UpliftLifecycleService>.Instance);
Assert.Equal(1, await lifecycle.EscalateDueAsync(CancellationToken.None));
}
await using var verify = new SqliteUpliftDecisionTestDbContext(options);
var saved = await verify.DispatchUpliftRequests.AsNoTracking().SingleAsync(u => u.Id == upliftId);
Assert.NotNull(saved.EscalatedAt);
Assert.Equal(1, emailSender.Calls);
var audits = await verify.WorkOrderAuditLogs.AsNoTracking().ToListAsync();
Assert.DoesNotContain(audits, a => a.WorkOrderId == 0);
if (expectedWorkOrderId is int workOrderId)
Assert.Equal(workOrderId, Assert.Single(audits).WorkOrderId);
else
Assert.Empty(audits);
}
private static async Task<(int UpliftId, int? ExpectedWorkOrderId)> SeedAsync(
ApplicationDbContext context,
Ownership ownership,
DateTime? expiresAt)
DateTime? expiresAt,
DateTime? initialNotificationSentAt = null)
{
context.Users.Add(new ApplicationUser
{
@ -218,7 +269,8 @@ public sealed class UpliftDecisionAuditRelationalTests
RequiredTier = 2,
CreatedDate = DateTime.UtcNow.AddDays(-4),
ExpiresAt = expiresAt,
NotificationStatus = "Pending"
InitialNotificationSentAt = initialNotificationSentAt,
NotificationStatus = initialNotificationSentAt == null ? "Pending" : "Sent"
};
context.DispatchUpliftRequests.Add(request);
await context.SaveChangesAsync();
@ -238,9 +290,16 @@ public sealed class UpliftDecisionAuditRelationalTests
=> throw new NotSupportedException();
}
// Records sends without delivering anything.
private sealed class NoEmailSender : IEmailSender
{
public Task<bool> SendEmailAsync(string emailTo, string subject, string body) => Task.FromResult(true);
public int Calls;
public Task<bool> SendEmailAsync(string emailTo, string subject, string body)
{
Calls++;
return Task.FromResult(true);
}
}
private sealed class SqliteUpliftDecisionTestDbContext : ApplicationDbContext