using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using SVSim.Database; using SVSim.Database.Enums; using SVSim.Database.Models; using SVSim.EmulatedEntrypoint.Services; using SVSim.UnitTests.Infrastructure; namespace SVSim.UnitTests.Services; public class DbCardPoolProviderTests { [Test] public async Task GetPool_for_standard_pack_returns_cards_of_matching_set() { using var factory = new SVSimTestFactory(); long anyCardId; int setId; using (var scope = factory.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); var setWithCards = await db.CardSets.Include(s => s.Cards) .FirstAsync(s => s.Cards.Count > 0); setId = setWithCards.Id; anyCardId = setWithCards.Cards.First().Id; } using var scope2 = factory.Services.CreateScope(); var provider = scope2.ServiceProvider.GetRequiredService(); var pool = provider.GetPool(new PackConfigEntry { Id = setId, BasePackId = setId, PackCategory = PackCategory.None }); Assert.That(pool.Any(c => c.Id == anyCardId), Is.True); } [Test] public void GetPool_for_legendary_special_returns_cards_from_rotation_sets() { using var factory = new SVSimTestFactory(); using var scope = factory.Services.CreateScope(); var provider = scope.ServiceProvider.GetRequiredService(); var pool = provider.GetPool(new PackConfigEntry { Id = 92001, BasePackId = 90001, PackCategory = PackCategory.SpecialCardPack }); Assert.That(pool.Count, Is.GreaterThan(0)); } [Test] public void GetPool_for_skin_pack_returns_empty() { using var factory = new SVSimTestFactory(); using var scope = factory.Services.CreateScope(); var provider = scope.ServiceProvider.GetRequiredService(); var pool = provider.GetPool(new PackConfigEntry { Id = 70001, BasePackId = 70001, PackCategory = PackCategory.LeaderSkinPack }); Assert.That(pool, Is.Empty); } [Test] public async Task GetPool_excludes_foil_cards() { using var factory = new SVSimTestFactory(); long nonFoilId, foilId; using (var scope = factory.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); // Pick the highest-Id card so that id+1 is guaranteed unoccupied. nonFoilId = await db.Cards.OrderByDescending(c => c.Id).Select(c => c.Id).FirstAsync(); foilId = nonFoilId + 1; var foilCard = new ShadowverseCardEntry { Id = foilId, Name = $"Card {foilId}", Rarity = Rarity.Bronze, IsFoil = true, }; // Add directly to the Cards DbSet and set the FK via shadow property, // avoiding nav-collection tracker conflicts. db.Cards.Add(foilCard); db.Entry(foilCard).Property("ShadowverseCardSetEntryId").CurrentValue = 10001; await db.SaveChangesAsync(); } using var scope2 = factory.Services.CreateScope(); var provider = scope2.ServiceProvider.GetRequiredService(); var pool = provider.GetPool(new PackConfigEntry { Id = 10001, BasePackId = 10001, PackCategory = PackCategory.None, }); Assert.That(pool.Any(c => c.Id == nonFoilId), Is.True, "non-foil must be in the pool"); Assert.That(pool.Any(c => c.Id == foilId), Is.False, "foil must be excluded from the pool"); } [Test] public async Task TryGetFoilTwin_returns_the_id_plus_one_foil_when_present() { using var factory = new SVSimTestFactory(); long nonFoilId, foilId; using (var scope = factory.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); // Pick the highest-Id card so that id+1 is guaranteed unoccupied. nonFoilId = await db.Cards.OrderByDescending(c => c.Id).Select(c => c.Id).FirstAsync(); foilId = nonFoilId + 1; var foilCard = new ShadowverseCardEntry { Id = foilId, Name = $"Card {foilId}", Rarity = Rarity.Bronze, IsFoil = true, }; db.Cards.Add(foilCard); db.Entry(foilCard).Property("ShadowverseCardSetEntryId").CurrentValue = 10001; await db.SaveChangesAsync(); } using var scope2 = factory.Services.CreateScope(); var provider = scope2.ServiceProvider.GetRequiredService(); var twin = provider.TryGetFoilTwin(nonFoilId); Assert.That(twin, Is.Not.Null); Assert.That(twin!.Id, Is.EqualTo(foilId)); Assert.That(twin.IsFoil, Is.True); } [Test] public async Task TryGetFoilTwin_returns_null_when_no_foil_at_id_plus_one() { using var factory = new SVSimTestFactory(); long anyCardId; using (var scope = factory.Services.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); anyCardId = await db.Cards.OrderBy(c => c.Id).Select(c => c.Id).FirstAsync(); } using var scope2 = factory.Services.CreateScope(); var provider = scope2.ServiceProvider.GetRequiredService(); Assert.That(provider.TryGetFoilTwin(anyCardId), Is.Null, "no foil seeded at anyCardId+1, so TryGetFoilTwin must return null"); } }