using Explorer.Application; using Explorer.Domain; namespace Explorer.Application.Tests; public class BackgroundMaintenancePlannerTests { [Fact] public void Skips_network_cloud_and_removable() { var utc = DateTimeOffset.Parse("2026-08-26T00:00:00Z"); var chosen = BackgroundMaintenancePlanner.NextLocalScan( [ Source("net", SourceKind.Smb, SourceStatus.Stale, utc.AddDays(-30)), Source("cloud", SourceKind.Cloud, SourceStatus.Stale, utc.AddDays(-30)), Source("usb", SourceKind.Removable, SourceStatus.Stale, utc.AddDays(-30)), Source("local", SourceKind.NtfsLocal, SourceStatus.Stale, utc.AddDays(-30)) ], utc); Assert.NotNull(chosen); Assert.Equal("local", chosen.StableKey); } [Fact] public void Prefers_stale_over_old_but_online() { var utc = DateTimeOffset.Parse("2026-08-26T00:00:00Z"); var chosen = BackgroundMaintenancePlanner.NextLocalScan( [ Source("old", SourceKind.NtfsLocal, SourceStatus.Online, utc.AddDays(-40)), Source("stale", SourceKind.NtfsLocal, SourceStatus.Stale, utc.AddDays(-2)) ], utc); Assert.Equal("stale", chosen!.StableKey); } [Fact] public void Fresh_online_local_is_not_full_rescanned() { var utc = DateTimeOffset.Parse("2026-08-26T00:00:00Z"); var chosen = BackgroundMaintenancePlanner.NextLocalScan( [ Source("fresh", SourceKind.NtfsLocal, SourceStatus.Online, utc.AddHours(-2)) ], utc); Assert.Null(chosen); } [Fact] public void Fresh_online_local_is_verified_when_idle() { var utc = DateTimeOffset.Parse("2026-08-26T00:00:00Z"); var chosen = BackgroundMaintenancePlanner.NextLocalVerify( [ Source("fresh", SourceKind.NtfsLocal, SourceStatus.Online, utc.AddHours(-2)) ]); Assert.NotNull(chosen); Assert.Equal("fresh", chosen.StableKey); } [Fact] public void Does_not_pick_a_source_already_queued() { var utc = DateTimeOffset.Parse("2026-08-26T00:00:00Z"); var source = Source("local", SourceKind.NtfsLocal, SourceStatus.Stale, utc.AddDays(-30)); source.Id = 7; var chosen = BackgroundMaintenancePlanner.NextLocalScan([source], utc, alreadyQueued: new HashSet { 7 }); Assert.Null(chosen); } private static Source Source(string key, SourceKind kind, SourceStatus status, DateTimeOffset indexed) => new() { StableKey = key, DisplayName = key, Kind = kind, Status = status, LastRootPath = @"D:\", LastIndexedUtc = indexed }; }