Files
novelly/tests/Novelly.Api.Tests/TrashPurgeTests.cs
T
James Wampler aca26588f9
CI / build-and-push (push) Failing after 31s
CI / deploy (push) Has been skipped
Add soft delete + trash, keyboard-first web overhaul, move chapter tags to bottom
Adds SoftDelete/Trash across characters, chapters, locations, beats with a
purge schedule and Trash page. Reworks the web client for keyboard-driven
navigation (focus helpers, help overlay, keyboard.md doc). Moves the
ChapterPage tag editor to the bottom of the page to match CharacterDetailPage.
2026-08-20 16:39:09 -07:00

70 lines
2.6 KiB
C#

using Microsoft.EntityFrameworkCore;
using Novelly.Api.Chapters;
using Novelly.Api.Novels;
using Novelly.Api.Trash;
namespace Novelly.Api.Tests;
[TestFixture]
public class TrashPurgeScheduleTests
{
[Test]
public void Before_the_run_time_the_next_run_is_today() =>
Assert.That(
TrashPurgeSchedule.NextRunAfter(new DateTimeOffset(2026, 8, 20, 1, 0, 0, TimeSpan.Zero), new TimeOnly(2, 0)),
Is.EqualTo(new DateTimeOffset(2026, 8, 20, 2, 0, 0, TimeSpan.Zero)));
[Test]
public void After_the_run_time_the_next_run_is_tomorrow() =>
Assert.That(
TrashPurgeSchedule.NextRunAfter(new DateTimeOffset(2026, 8, 20, 3, 0, 0, TimeSpan.Zero), new TimeOnly(2, 0)),
Is.EqualTo(new DateTimeOffset(2026, 8, 21, 2, 0, 0, TimeSpan.Zero)));
[Test]
public void Exactly_at_the_run_time_the_next_run_is_tomorrow() =>
Assert.That(
TrashPurgeSchedule.NextRunAfter(new DateTimeOffset(2026, 8, 20, 2, 0, 0, TimeSpan.Zero), new TimeOnly(2, 0)),
Is.EqualTo(new DateTimeOffset(2026, 8, 21, 2, 0, 0, TimeSpan.Zero)));
}
[TestFixture]
public class TrashPurgeSweepTests : ServiceTestFixture
{
private Guid _novelId;
protected override void OnSetUp() =>
_novelId = Novels.CreateAsync(new CreateNovelRequest("The Salt Road")).Result.Id;
[Test]
public async Task A_sweep_removes_only_items_older_than_the_retention_window()
{
var old = await Chapters.CreateAsync(_novelId, new CreateChapterRequest("Old News"));
var recent = await Chapters.CreateAsync(_novelId, new CreateChapterRequest("Fresh Off The Press"));
await Chapters.DeleteAsync(old!.Id);
await Chapters.DeleteAsync(recent!.Id);
using (var context = Db.CreateContext())
{
var oldRow = await context.Chapters.IgnoreQueryFilters().SingleAsync(c => c.Id == old.Id);
oldRow.DeletedAt = DateTimeOffset.UtcNow.AddDays(-31);
await context.SaveChangesAsync();
}
var cutoff = DateTimeOffset.UtcNow.AddDays(-30);
var (characters, chapters, locations) = await TrashPurgeRunner.SweepAsync(Db.Context, cutoff, CancellationToken.None);
Assert.Multiple(() =>
{
Assert.That((characters, chapters, locations), Is.EqualTo((0, 1, 0)));
});
using var verification = Db.CreateContext();
Assert.Multiple(async () =>
{
Assert.That(await verification.Chapters.IgnoreQueryFilters().AnyAsync(c => c.Id == old.Id), Is.False);
Assert.That(await verification.Chapters.IgnoreQueryFilters().AnyAsync(c => c.Id == recent.Id), Is.True);
});
}
}