using AcDream.Core.Items; using Xunit; namespace AcDream.Core.Tests.Items; public sealed class ItemRepositoryTests { private static ItemInstance MakeItem(uint id, string name = "Widget") => new ItemInstance { ObjectId = id, WeenieClassId = 1, Name = name, Type = ItemType.Misc, StackSize = 1, Burden = 10, Value = 5, }; [Fact] public void AddOrUpdate_FiresAddedEvent() { var repo = new ItemRepository(); ItemInstance? added = null; repo.ItemAdded += i => added = i; var item = MakeItem(100); repo.AddOrUpdate(item); Assert.Same(item, added); Assert.Equal(1, repo.ItemCount); Assert.Same(item, repo.GetItem(100)); } [Fact] public void AddOrUpdate_ExistingItem_FiresPropertiesUpdated() { var repo = new ItemRepository(); var item = MakeItem(100); repo.AddOrUpdate(item); int propUpdateCount = 0; repo.ItemPropertiesUpdated += _ => propUpdateCount++; repo.AddOrUpdate(item); // second call is an update Assert.Equal(1, propUpdateCount); } [Fact] public void MoveItem_UpdatesContainerAndFiresEvent() { var repo = new ItemRepository(); var item = MakeItem(100); repo.AddOrUpdate(item); uint seenOld = 999, seenNew = 999; repo.ItemMoved += (it, oldC, newC) => { seenOld = oldC; seenNew = newC; }; repo.MoveItem(100, 42, newSlot: 3); Assert.Equal(0u, seenOld); // was not in any container initially Assert.Equal(42u, seenNew); Assert.Equal(42u, item.ContainerId); Assert.Equal(3, item.ContainerSlot); } [Fact] public void MoveItem_Nonexistent_ReturnsFalse() { var repo = new ItemRepository(); Assert.False(repo.MoveItem(999, 42)); } [Fact] public void Remove_FiresEventAndRemoves() { var repo = new ItemRepository(); var item = MakeItem(100); repo.AddOrUpdate(item); ItemInstance? removed = null; repo.ItemRemoved += i => removed = i; Assert.True(repo.Remove(100)); Assert.Same(item, removed); Assert.Null(repo.GetItem(100)); } [Fact] public void UpdateProperties_MergesIncomingBundle() { var repo = new ItemRepository(); var item = MakeItem(100); item.Properties.Ints[1] = 10; repo.AddOrUpdate(item); var patch = new PropertyBundle(); patch.Ints[2] = 20; // new patch.Ints[1] = 15; // overrides patch.Strings[100] = "desc"; repo.UpdateProperties(100, patch); Assert.Equal(15, item.Properties.Ints[1]); Assert.Equal(20, item.Properties.Ints[2]); Assert.Equal("desc", item.Properties.Strings[100]); } [Fact] public void Clear_RemovesAllItems() { var repo = new ItemRepository(); repo.AddOrUpdate(MakeItem(1)); repo.AddOrUpdate(MakeItem(2)); repo.AddOrUpdate(MakeItem(3)); repo.Clear(); Assert.Equal(0, repo.ItemCount); } [Fact] public void EnrichItem_updatesIconOnExistingStub_andRaisesUpdated() { var repo = new ItemRepository(); repo.AddOrUpdate(new ItemInstance { ObjectId = 0x5001u, WeenieClassId = 42u }); // stub from PlayerDescription ItemInstance? updated = null; repo.ItemPropertiesUpdated += i => updated = i; bool hit = repo.EnrichItem(0x5001u, iconId: 0x06001234u, name: "Mana Stone", type: ItemType.Misc); Assert.True(hit); Assert.Equal(0x06001234u, repo.GetItem(0x5001u)!.IconId); Assert.Equal("Mana Stone", repo.GetItem(0x5001u)!.Name); Assert.NotNull(updated); } [Fact] public void EnrichItem_returnsFalse_whenItemUnknown() { var repo = new ItemRepository(); Assert.False(repo.EnrichItem(0x9999u, 0x06001234u, "x", ItemType.Misc)); } [Fact] public void EnrichItem_carriesEffects() { var repo = new ItemRepository(); repo.AddOrUpdate(new ItemInstance { ObjectId = 0x500000AAu }); bool ok = repo.EnrichItem(0x500000AAu, iconId: 0x06001234u, name: "Wand", type: ItemType.Caster, iconOverlayId: 0, iconUnderlayId: 0, effects: 0x1u); Assert.True(ok); Assert.Equal(0x1u, repo.GetItem(0x500000AAu)!.Effects); } [Fact] public void UpdateIntProperty_uiEffects_setsEffectsAndFires() { var repo = new ItemRepository(); repo.AddOrUpdate(new ItemInstance { ObjectId = 0x500000ABu }); ItemInstance? fired = null; repo.ItemPropertiesUpdated += i => fired = i; bool ok = repo.UpdateIntProperty(0x500000ABu, ItemRepository.UiEffectsPropertyId, value: 0x9); Assert.True(ok); Assert.Equal(0x9u, repo.GetItem(0x500000ABu)!.Effects); Assert.Equal(0x9, repo.GetItem(0x500000ABu)!.Properties.Ints[ItemRepository.UiEffectsPropertyId]); Assert.NotNull(fired); } [Fact] public void UpdateIntProperty_unknownItem_returnsFalse() { var repo = new ItemRepository(); Assert.False(repo.UpdateIntProperty(0xDEADBEEFu, 18u, 1)); } }