using AcDream.App.Studio; using AcDream.Core.Items; namespace AcDream.App.Tests.Studio; /// /// Unit tests for and . /// These tests have NO GL/dat dependency — they only exercise the in-memory /// ClientObjectTable population that FixtureProvider uses. /// public class FixtureProviderTests { /// /// SampleData.BuildObjectTable() must place at least 6 items in the /// player's main pack (ContainerId == PlayerGuid) and the player object /// itself must exist with the right capacities. /// [Fact] public void SampleTable_hasPackContents() { var t = SampleData.BuildObjectTable(); // Player object must exist. var player = t.Get(SampleData.PlayerGuid); Assert.NotNull(player); Assert.Equal(102, player!.ItemsCapacity); Assert.Equal(7, player.ContainersCapacity); // At least 6 loose items must be in the main pack. var contents = t.GetContents(SampleData.PlayerGuid); Assert.True(contents.Count >= 6, $"Expected >= 6 items in player pack; got {contents.Count}"); // Verify the first item has a non-zero IconId and a recognised Type. var firstId = contents[0]; var first = t.Get(firstId); Assert.NotNull(first); Assert.NotEqual(0u, first!.IconId); Assert.NotEqual(ItemType.None, first.Type); } /// /// Spot-check that the sample table also seeds a sword-like item /// (MeleeWeapon) and a piece of armor so icon resolution has /// recognisable item types to work with. /// [Fact] public void SampleTable_hasWeaponAndArmor() { var t = SampleData.BuildObjectTable(); var contents = t.GetContents(SampleData.PlayerGuid); bool hasMelee = false, hasArmor = false; foreach (var guid in contents) { var obj = t.Get(guid); if (obj is null) continue; if ((obj.Type & ItemType.MeleeWeapon) != 0) hasMelee = true; if ((obj.Type & ItemType.Armor) != 0) hasArmor = true; } Assert.True(hasMelee, "Expected at least one MeleeWeapon in sample pack"); Assert.True(hasArmor, "Expected at least one Armor item in sample pack"); } /// /// Sample table must include at least 1 equipped item whose /// CurrentlyEquippedLocation is non-None. /// [Fact] public void SampleTable_hasEquippedItems() { var t = SampleData.BuildObjectTable(); bool anyEquipped = false; foreach (var obj in t.Objects) { if (obj.CurrentlyEquippedLocation != EquipMask.None) { anyEquipped = true; break; } } Assert.True(anyEquipped, "Expected at least one equipped item in sample table"); } /// /// Sample table must include at least 2 side-bag containers in the /// player's pack (ContainerId == PlayerGuid, Type has Container bit). /// [Fact] public void SampleTable_hasSideBags() { var t = SampleData.BuildObjectTable(); int bagCount = 0; foreach (var guid in t.GetContents(SampleData.PlayerGuid)) { var obj = t.Get(guid); if (obj is not null && (obj.Type & ItemType.Container) != 0) bagCount++; } Assert.True(bagCount >= 2, $"Expected >= 2 side-bag containers in player pack; got {bagCount}"); } /// /// Side bags must match the InventoryController filter: ItemType.Container OR ItemsCapacity > 0. /// This ensures they appear in the side-bag column even if the exact Type flag changes. /// [Fact] public void SampleTable_sideBags_matchInventoryControllerFilter() { var t = SampleData.BuildObjectTable(); int bagCount = 0; foreach (var guid in t.GetContents(SampleData.PlayerGuid)) { var obj = t.Get(guid); if (obj is null) continue; // InventoryController.Populate line ~203: Type.HasFlag(Container) OR ItemsCapacity > 0 bool isBag = obj.Type.HasFlag(ItemType.Container) || obj.ItemsCapacity > 0; if (isBag) bagCount++; } Assert.True(bagCount >= 2, $"Expected >= 2 items matching the side-bag filter; got {bagCount}"); } /// /// Equipped items must BOTH (a) retain CurrentlyEquippedLocation != None after /// seeding AND (b) appear in GetContents(PlayerGuid) so PaperdollController.Populate /// can find them. These are the two conditions PaperdollController checks on every /// equipped item (PaperdollController.Populate: ContainerId == playerGuid AND /// CurrentlyEquippedLocation != None). /// [Fact] public void SampleTable_equippedItems_retainLocationAndAreInContents() { var t = SampleData.BuildObjectTable(); var contents = new System.Collections.Generic.HashSet(t.GetContents(SampleData.PlayerGuid)); int equippedCount = 0; foreach (var obj in t.Objects) { if (obj.CurrentlyEquippedLocation == EquipMask.None) continue; equippedCount++; // Must appear in GetContents so the controller can pick them up. Assert.True(contents.Contains(obj.ObjectId), $"Equipped item 0x{obj.ObjectId:X8} ('{obj.Name}', loc={obj.CurrentlyEquippedLocation}) " + $"is NOT in GetContents(PlayerGuid). PaperdollController will miss it."); // The equip location must survive the MoveItem call. Assert.NotEqual(EquipMask.None, obj.CurrentlyEquippedLocation); } Assert.True(equippedCount >= 3, $"Expected >= 3 equipped items in sample table; got {equippedCount}"); } }