diff --git a/SVSim.Database/Repositories/Globals/GlobalsRepository.cs b/SVSim.Database/Repositories/Globals/GlobalsRepository.cs index fa0d1d0..c3bb986 100644 --- a/SVSim.Database/Repositories/Globals/GlobalsRepository.cs +++ b/SVSim.Database/Repositories/Globals/GlobalsRepository.cs @@ -65,6 +65,13 @@ public class GlobalsRepository : IGlobalsRepository public Task> GetBanners() => _dbContext.Banners.AsNoTracking().OrderBy(b => b.Id).ToListAsync(); + public async Task> GetActiveHomeDialogsAsync(DateTime nowUtc) => + await _dbContext.HomeDialogEntries.AsNoTracking() + .Where(e => e.BeginTime <= nowUtc && e.EndTime > nowUtc) + .OrderByDescending(e => e.Priority) + .ThenBy(e => e.Id) + .ToListAsync(); + public Task GetCurrentColosseum() => _dbContext.Colosseums.AsNoTracking().FirstOrDefaultAsync(e => e.Id == 1); diff --git a/SVSim.Database/Repositories/Globals/IGlobalsRepository.cs b/SVSim.Database/Repositories/Globals/IGlobalsRepository.cs index 3edd6fc..b9ec92e 100644 --- a/SVSim.Database/Repositories/Globals/IGlobalsRepository.cs +++ b/SVSim.Database/Repositories/Globals/IGlobalsRepository.cs @@ -21,6 +21,7 @@ public interface IGlobalsRepository Task> GetBattlePassLevels(); Task> GetDailyLoginBonus(); Task> GetBanners(); + Task> GetActiveHomeDialogsAsync(DateTime nowUtc); Task GetCurrentColosseum(); Task GetCurrentSealedSeason(); Task GetCurrentMasterPointPeriod(); diff --git a/SVSim.UnitTests/Repositories/GlobalsRepositoryHomeDialogTests.cs b/SVSim.UnitTests/Repositories/GlobalsRepositoryHomeDialogTests.cs new file mode 100644 index 0000000..afe7376 --- /dev/null +++ b/SVSim.UnitTests/Repositories/GlobalsRepositoryHomeDialogTests.cs @@ -0,0 +1,57 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using SVSim.Database; +using SVSim.Database.Models; +using SVSim.Database.Repositories.Globals; +using SVSim.UnitTests.Infrastructure; + +namespace SVSim.UnitTests.Repositories; + +public class GlobalsRepositoryHomeDialogTests +{ + [Test] + public async Task GetActiveHomeDialogsAsync_returns_only_rows_inside_window_ordered_by_priority_desc_then_id_asc() + { + using var factory = new SVSimTestFactory(); + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var repo = scope.ServiceProvider.GetRequiredService(); + + var now = new DateTime(2026, 6, 8, 12, 0, 0, DateTimeKind.Utc); + + db.HomeDialogEntries.AddRange( + new HomeDialogEntry { Id = 1, TitleTextId = "past", Image = "i", BeginTime = now.AddDays(-30), EndTime = now.AddDays(-1), Priority = 0 }, + new HomeDialogEntry { Id = 2, TitleTextId = "active-lo", Image = "i", BeginTime = now.AddDays(-1), EndTime = now.AddDays(1), Priority = 5 }, + new HomeDialogEntry { Id = 3, TitleTextId = "active-hi", Image = "i", BeginTime = now.AddDays(-1), EndTime = now.AddDays(1), Priority = 10 }, + new HomeDialogEntry { Id = 4, TitleTextId = "future", Image = "i", BeginTime = now.AddDays(1), EndTime = now.AddDays(30), Priority = 99 }, + new HomeDialogEntry { Id = 5, TitleTextId = "active-mid", Image = "i", BeginTime = now.AddDays(-1), EndTime = now.AddDays(1), Priority = 5 } + ); + await db.SaveChangesAsync(); + + var result = await repo.GetActiveHomeDialogsAsync(now); + + Assert.That(result.Select(r => r.Id), Is.EqualTo(new[] { 3, 2, 5 }), + "Expected priority-DESC then Id-ASC ordering; only entries whose window covers `now`."); + } + + [Test] + public async Task GetActiveHomeDialogsAsync_excludes_row_whose_end_time_equals_now() + { + // Window is [begin, end) — exclusive on the upper bound. + using var factory = new SVSimTestFactory(); + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var repo = scope.ServiceProvider.GetRequiredService(); + + var now = new DateTime(2026, 6, 8, 12, 0, 0, DateTimeKind.Utc); + db.HomeDialogEntries.Add(new HomeDialogEntry + { + Id = 1, TitleTextId = "just-expired", Image = "i", + BeginTime = now.AddHours(-1), EndTime = now, Priority = 0, + }); + await db.SaveChangesAsync(); + + var result = await repo.GetActiveHomeDialogsAsync(now); + Assert.That(result, Is.Empty); + } +}