fix(app): harden account and workflow state

This commit is contained in:
cesnimda
2026-08-24 20:21:09 +02:00
parent e7cacad7d6
commit dca5daa1a2
32 changed files with 811 additions and 86 deletions
@@ -290,6 +290,45 @@ public sealed class BackgroundWorkerTenantTests
Assert.All(jobs, job => Assert.Equal(FixedNow.DateTime, job.LastReminderEmailSentAt));
}
[Fact]
public async Task Reminder_worker_respects_each_owners_persisted_email_opt_out()
{
var email = new Mock<IAppEmailSender>();
await using var fixture = await Fixture.CreateAsync(
new Dictionary<string, string?>
{
["Workers:FollowUpRemindersEnabled"] = "true",
["Email:FollowUpReminders:Enabled"] = "true",
["App:PublicBaseUrl"] = "http://localhost:3000",
},
services => services.AddSingleton(email.Object));
await fixture.SeedJobsAsync(includeUsers: true);
await using (var scope = fixture.Provider.CreateAsyncScope())
{
var user = await scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>().FindByIdAsync("user-2");
Assert.NotNull(user);
user!.EmailFollowUpRemindersEnabled = false;
Assert.True((await scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>().UpdateAsync(user)).Succeeded);
}
var worker = new FollowUpReminderHostedService(
fixture.Runner,
fixture.Configuration,
NullLogger<FollowUpReminderHostedService>.Instance,
Mock.Of<IStartupReadiness>(),
ExternalOrigin.FromConfiguration(fixture.Configuration),
new MutableTimeProvider(FixedNow));
Assert.Equal(new BackgroundWorkerRunResult(true, 2, 2, 0), await worker.RunOnceAsync(default));
email.Verify(x => x.SendAsync("one@example.test", It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
email.Verify(x => x.SendAsync("two@example.test", It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never);
await using var verificationScope = fixture.Provider.CreateAsyncScope();
var jobs = await verificationScope.ServiceProvider.GetRequiredService<JobTrackerContext>().JobApplications
.IgnoreQueryFilters().AsNoTracking().OrderBy(job => job.OwnerUserId).ToListAsync();
Assert.Equal(FixedNow.DateTime, jobs[0].LastReminderEmailSentAt);
Assert.Null(jobs[1].LastReminderEmailSentAt);
}
[Fact]
public async Task Rules_worker_uses_injected_clock_across_threshold_and_restart()
{