using Microsoft.Extensions.DependencyInjection; using NeonSprawl.Server.Game.Items; using Xunit; namespace NeonSprawl.Server.Tests.Game.Items; public sealed class InMemoryPlayerInventoryStoreTests { [Fact] public void TryGetSnapshot_ForSeededDevPlayer_ShouldReturnEmptyInventory() { // Arrange using var factory = new InMemoryWebApplicationFactory(); var store = factory.Services.GetRequiredService(); // Act var found = store.TryGetSnapshot("dev-local-1", out var snapshot); // Assert Assert.True(found); Assert.NotNull(snapshot); Assert.Equal(PlayerInventorySnapshot.BagSlotCount, snapshot!.BagSlots.Length); Assert.Single(snapshot.EquipmentSlots); Assert.All(snapshot.BagSlots, static s => Assert.True(s.IsEmpty)); Assert.All(snapshot.EquipmentSlots, static s => Assert.True(s.IsEmpty)); } [Fact] public void TryReplaceSnapshot_ShouldRoundTripOccupiedSlots() { // Arrange using var factory = new InMemoryWebApplicationFactory(); var store = factory.Services.GetRequiredService(); store.TryGetSnapshot("dev-local-1", out var before); var updated = before!.WithSlots( InventoryContainerKind.Bag, CloneWithOccupied(before.BagSlots, slotIndex: 3, "scrap_metal_bulk", quantity: 42)); // Act var replaced = store.TryReplaceSnapshot("dev-local-1", updated); var readBack = store.TryGetSnapshot("dev-local-1", out var after); // Assert Assert.True(replaced); Assert.True(readBack); Assert.Equal("scrap_metal_bulk", after!.BagSlots[3].ItemId); Assert.Equal(42, after.BagSlots[3].Quantity); } [Fact] public void TryGetSnapshot_ForUnknownPlayer_ShouldReturnFalse() { // Arrange using var factory = new InMemoryWebApplicationFactory(); var store = factory.Services.GetRequiredService(); // Act var found = store.TryGetSnapshot("unknown-player-xyz", out _); // Assert Assert.False(found); } private static InventorySlotState[] CloneWithOccupied( InventorySlotState[] source, int slotIndex, string itemId, int quantity) { var copy = new InventorySlotState[source.Length]; for (var i = 0; i < source.Length; i++) { var s = source[i]; copy[i] = i == slotIndex ? new InventorySlotState(slotIndex, itemId, quantity) : new InventorySlotState(s.SlotIndex, s.ItemId, s.Quantity); } return copy; } }