diff --git a/SVSim.Database/Repositories/Viewer/ViewerRepository.cs b/SVSim.Database/Repositories/Viewer/ViewerRepository.cs index 287d67a..8a39360 100644 --- a/SVSim.Database/Repositories/Viewer/ViewerRepository.cs +++ b/SVSim.Database/Repositories/Viewer/ViewerRepository.cs @@ -170,6 +170,8 @@ public class ViewerRepository : IViewerRepository if (defaultEmblem is not null) viewer.Emblems.Add(defaultEmblem); if (defaultBg is not null) viewer.MyPageBackgrounds.Add(defaultBg); + // Grant one of each class's default leader skin. Filter out the synthetic placeholders + // (Id=0) and dedupe — skins are many-to-many via SleeveEntryViewer-style join. var grantedSkins = viewer.Classes .Select(vcd => vcd.LeaderSkin) .Where(s => s.Id != 0) diff --git a/SVSim.UnitTests/Repositories/ViewerRepositoryTests.cs b/SVSim.UnitTests/Repositories/ViewerRepositoryTests.cs index 10c1ea5..322339b 100644 --- a/SVSim.UnitTests/Repositories/ViewerRepositoryTests.cs +++ b/SVSim.UnitTests/Repositories/ViewerRepositoryTests.cs @@ -155,12 +155,20 @@ public class ViewerRepositoryTests await repo.LinkSteamToViewer(viewerId, steamId); } + using (var scope = factory.Services.CreateScope()) + { + var repo = scope.ServiceProvider.GetRequiredService(); + await repo.LinkSteamToViewer(viewerId, steamId); // second call must be a no-op + } + using var verifyScope = factory.Services.CreateScope(); var db = verifyScope.ServiceProvider.GetRequiredService(); var loaded = await db.Viewers .Include(v => v.SocialAccountConnections) .FirstAsync(v => v.Id == viewerId); + // Count == 1 proves both the initial append AND that the second LinkSteamToViewer call + // hit the `alreadyLinked` short-circuit (idempotent re-link). Assert.That(loaded.SocialAccountConnections, Has.Count.EqualTo(1)); Assert.That(loaded.SocialAccountConnections[0].AccountType, Is.EqualTo(SocialAccountType.Steam));