From 22c220c4321c6cbb8b522a58944af07424565d49 Mon Sep 17 00:00:00 2001 From: koko Date: Wed, 13 Sep 2023 07:12:25 -0400 Subject: [PATCH] Implement dismiss expired cases repeating task (#891) * Implement dismiss expired cases repeating task I have the time temporarily set to every 1 minute for testing purposes * Rename cases list variable to be a bit more self documenting * Switch repeat interval to four hours * Make no operation log a debug * Add case expiration unit tests I called the file ModerationTests in case we want to add more general moderation unit tests in the future * I blame zaprit * Fix tests * Tests nitpicks and use UtcNow instead of Now * Use Assert.Null and Assert.NotNull for better readability --- .../Unit/ModerationTests.cs | 57 +++++++++++++++++++ .../RepeatingTasks/DismissExpiredCasesTask.cs | 39 +++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 ProjectLighthouse.Tests/Unit/ModerationTests.cs create mode 100644 ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs diff --git a/ProjectLighthouse.Tests/Unit/ModerationTests.cs b/ProjectLighthouse.Tests/Unit/ModerationTests.cs new file mode 100644 index 00000000..49b42e15 --- /dev/null +++ b/ProjectLighthouse.Tests/Unit/ModerationTests.cs @@ -0,0 +1,57 @@ +using System; +using LBPUnion.ProjectLighthouse.Administration.Maintenance.RepeatingTasks; +using LBPUnion.ProjectLighthouse.Database; +using LBPUnion.ProjectLighthouse.Tests.Helpers; +using LBPUnion.ProjectLighthouse.Types.Entities.Moderation; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace LBPUnion.ProjectLighthouse.Tests.Unit; + +[Trait("Category", "Unit")] +public class ModerationTests +{ + [Fact] + public async void DismissExpiredCases_ShouldDismissExpiredCase() + { + await using DatabaseContext database = await MockHelper.GetTestDatabase(); + + ModerationCaseEntity @case = new() + { + CaseId = 1, + ExpiresAt = DateTime.UnixEpoch, + CreatorUsername = "unitTestUser", + }; + + database.Cases.Add(@case); + + await database.SaveChangesAsync(); + + DismissExpiredCasesTask task = new(); + await task.Run(database); + + Assert.Null(await database.Cases.FirstOrDefaultAsync(c => c.CaseId == 1 && c.DismissedAt == null)); + } + + [Fact] + public async void DismissExpiredCases_ShouldNotDismissActiveCase() + { + await using DatabaseContext database = await MockHelper.GetTestDatabase(); + + ModerationCaseEntity @case = new() + { + CaseId = 2, + ExpiresAt = DateTime.UtcNow.AddHours(1), + CreatorUsername = "unitTestUser", + }; + + database.Cases.Add(@case); + + await database.SaveChangesAsync(); + + DismissExpiredCasesTask task = new(); + await task.Run(database); + + Assert.NotNull(await database.Cases.FirstOrDefaultAsync(c => c.CaseId == 2 && c.DismissedAt == null)); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs b/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs new file mode 100644 index 00000000..e38e5405 --- /dev/null +++ b/ProjectLighthouse/Administration/Maintenance/RepeatingTasks/DismissExpiredCasesTask.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Database; +using LBPUnion.ProjectLighthouse.Logging; +using LBPUnion.ProjectLighthouse.Types.Entities.Moderation; +using LBPUnion.ProjectLighthouse.Types.Logging; +using LBPUnion.ProjectLighthouse.Types.Maintenance; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.RepeatingTasks; + +public class DismissExpiredCasesTask : IRepeatingTask +{ + public string Name => "Dismiss Expired Cases"; + public TimeSpan RepeatInterval => TimeSpan.FromHours(4); + public DateTime LastRan { get; set; } + + public async Task Run(DatabaseContext database) + { + List expiredCases = + await database.Cases.Where(c => c.ExpiresAt != null && c.ExpiresAt < DateTime.UtcNow).ToListAsync(); + + if (expiredCases.Count == 0) + { + Logger.Debug("There are no expired cases to dismiss", LogArea.Maintenance); + return; + } + + foreach (ModerationCaseEntity @case in expiredCases) + { + @case.DismissedAt = DateTime.Now; + Logger.Info($"Dismissed expired case {@case.CaseId}", LogArea.Maintenance); + } + + await database.SaveChangesAsync(); + } +} \ No newline at end of file