using System.Net; using Microsoft.Extensions.DependencyInjection; using NeonSprawl.Server.Game.Mastery; using NeonSprawl.Server.Tests; using Xunit; namespace NeonSprawl.Server.Tests.Game.Mastery; public class MasteryCatalogRegistryTests { private static MasteryCatalogRegistry CreateRegistryFromCatalog(MasteryCatalog catalog) => new(catalog); [Fact] public void TryGetTrack_ShouldReturnTrue_WhenSkillIdExists() { // Arrange var track = new MasteryTrackRow( "salvage", [new MasteryTierRow(1, 2, [new MasteryBranchRow("scrap_efficiency", null, [])])]); var catalog = new MasteryCatalog( "/tmp/mastery", new Dictionary(StringComparer.Ordinal) { ["salvage"] = track }, new Dictionary(StringComparer.Ordinal), catalogJsonFileCount: 1); var registry = CreateRegistryFromCatalog(catalog); // Act var found = registry.TryGetTrack("salvage", out var result); // Assert Assert.True(found); Assert.NotNull(result); Assert.Equal("salvage", result.SkillId); } [Fact] public void TryGetTrack_ShouldReturnFalse_WhenSkillIdUnknown() { // Arrange var catalog = new MasteryCatalog( "/tmp/mastery", new Dictionary(StringComparer.Ordinal), new Dictionary(StringComparer.Ordinal), catalogJsonFileCount: 0); var registry = CreateRegistryFromCatalog(catalog); // Act var found = registry.TryGetTrack("not_a_track", out var result); // Assert Assert.False(found); Assert.Null(result); } [Fact] public void TryGetPerk_ShouldReturnTrue_WhenPerkIdExists() { // Arrange var perk = new PerkDefRow("salvage_scrap_efficiency_1", "Scrap Sifter", "gather_yield_modifier"); var catalog = new MasteryCatalog( "/tmp/mastery", new Dictionary(StringComparer.Ordinal), new Dictionary(StringComparer.Ordinal) { [perk.Id] = perk }, catalogJsonFileCount: 1); var registry = CreateRegistryFromCatalog(catalog); // Act var found = registry.TryGetPerk("salvage_scrap_efficiency_1", out var result); // Assert Assert.True(found); Assert.NotNull(result); Assert.Equal("gather_yield_modifier", result.EffectKind); } [Fact] public void GetTracksInSkillIdOrder_ShouldReturnTracksSortedBySkillId() { // Arrange var refine = new MasteryTrackRow("refine", []); var salvage = new MasteryTrackRow("salvage", []); var intrusion = new MasteryTrackRow("intrusion", []); var catalog = new MasteryCatalog( "/tmp/mastery", new Dictionary(StringComparer.Ordinal) { ["refine"] = refine, ["salvage"] = salvage, ["intrusion"] = intrusion, }, new Dictionary(StringComparer.Ordinal), catalogJsonFileCount: 1); var registry = CreateRegistryFromCatalog(catalog); // Act var tracks = registry.GetTracksInSkillIdOrder(); // Assert Assert.Equal(["intrusion", "refine", "salvage"], [.. tracks.Select(t => t.SkillId)]); } [Fact] public void GetPerksInIdOrder_ShouldReturnPerksSortedById() { // Arrange var perks = new Dictionary(StringComparer.Ordinal) { ["z_perk"] = new("z_perk", "Z", null), ["a_perk"] = new("a_perk", "A", null), ["m_perk"] = new("m_perk", "M", null), }; var catalog = new MasteryCatalog( "/tmp/mastery", new Dictionary(StringComparer.Ordinal), perks, catalogJsonFileCount: 1); var registry = CreateRegistryFromCatalog(catalog); // Act var ordered = registry.GetPerksInIdOrder(); // Assert Assert.Equal(["a_perk", "m_perk", "z_perk"], [.. ordered.Select(p => p.Id)]); } [Fact] public async Task Host_ShouldResolveRegistryFromDi_WhenStartupSucceeds() { // Arrange await using var factory = new InMemoryWebApplicationFactory(); using var client = factory.CreateClient(); // Act var response = await client.GetAsync("/health"); var registry = factory.Services.GetRequiredService(); var catalog = factory.Services.GetRequiredService(); var foundTrack = registry.TryGetTrack("salvage", out var track); var foundPerk = registry.TryGetPerk("salvage_scrap_efficiency_1", out var perk); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(1, catalog.TrackCount); Assert.True(catalog.TracksBySkillId.ContainsKey("salvage")); Assert.True(foundTrack); Assert.NotNull(track); Assert.Equal(2, track.Tiers.Count); Assert.True(foundPerk); Assert.NotNull(perk); Assert.Equal("Scrap Sifter", perk.DisplayName); } }