public void Execute( ItemType itemType, bool shopItemExist, long blockIndex, int itemCount, int prevCount, int expectedProductsCount ) { var avatarState = _initialState.GetAvatarState(_avatarAddress); ITradableItem tradableItem; switch (itemType) { case ItemType.Consumable: tradableItem = ItemFactory.CreateItemUsable( _tableSheets.ConsumableItemSheet.First, Guid.NewGuid(), 0); break; case ItemType.Costume: tradableItem = ItemFactory.CreateCostume( _tableSheets.CostumeItemSheet.First, Guid.NewGuid()); break; case ItemType.Equipment: tradableItem = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.First, Guid.NewGuid(), 0); break; case ItemType.Material: var tradableMaterialRow = _tableSheets.MaterialItemSheet.OrderedList .First(row => row.ItemSubType == ItemSubType.Hourglass); tradableItem = ItemFactory.CreateTradableMaterial(tradableMaterialRow); break; default: throw new ArgumentOutOfRangeException(nameof(itemType), itemType, null); } Assert.Equal(0, tradableItem.RequiredBlockIndex); avatarState.inventory.AddItem2((ItemBase)tradableItem, itemCount); var previousStates = _initialState; previousStates = previousStates.SetState(_avatarAddress, avatarState.Serialize()); var currencyState = previousStates.GetGoldCurrency(); var price = new FungibleAssetValue(currencyState, ProductPrice, 0); var expectedProductId = new Guid("6f460c1a755d48e4ad6765d5f519dbc8"); var productId = new Guid("229e5f8c-fabe-4c04-bab9-45325cfa69a4"); var shardedShopAddress = ShardedShopState.DeriveAddress( tradableItem.ItemSubType, expectedProductId); if (shopItemExist) { tradableItem.RequiredBlockIndex = blockIndex; Assert.Equal(blockIndex, tradableItem.RequiredBlockIndex); var shopItem = new ShopItem( _agentAddress, _avatarAddress, productId, new FungibleAssetValue(currencyState, 1, 0), blockIndex, tradableItem, prevCount ); var shardedShopState = new ShardedShopState(shardedShopAddress); shardedShopState.Register(shopItem); Assert.Single(shardedShopState.Products); previousStates = previousStates.SetState( shardedShopAddress, shardedShopState.Serialize()); } else { Assert.Null(previousStates.GetState(shardedShopAddress)); } var sellAction = new Sell6 { sellerAvatarAddress = _avatarAddress, tradableId = tradableItem.TradableId, count = itemCount, price = price, itemSubType = tradableItem.ItemSubType, }; var nextState = sellAction.Execute(new ActionContext { BlockIndex = 1, PreviousStates = previousStates, Rehearsal = false, Signer = _agentAddress, Random = new TestRandom(), }); const long expiredBlockIndex = Sell6.ExpiredBlockIndex + 1; // Check AvatarState and Inventory var nextAvatarState = nextState.GetAvatarState(_avatarAddress); Assert.Single(nextAvatarState.inventory.Items); Assert.True(nextAvatarState.inventory.TryGetTradableItems( tradableItem.TradableId, expiredBlockIndex, 1, out var inventoryItems)); Assert.Single(inventoryItems); ITradableItem nextTradableItem = (ITradableItem)inventoryItems.First().item; Assert.Equal(expiredBlockIndex, nextTradableItem.RequiredBlockIndex); // Check ShardedShopState and ShopItem var nextSerializedShardedShopState = nextState.GetState(shardedShopAddress); Assert.NotNull(nextSerializedShardedShopState); var nextShardedShopState = new ShardedShopState((Dictionary)nextSerializedShardedShopState); Assert.Equal(expectedProductsCount, nextShardedShopState.Products.Count); var nextShopItem = nextShardedShopState.Products.Values.First(s => s.ExpiredBlockIndex == expiredBlockIndex); ITradableItem nextTradableItemInShopItem; switch (itemType) { case ItemType.Consumable: case ItemType.Equipment: nextTradableItemInShopItem = nextShopItem.ItemUsable; break; case ItemType.Costume: nextTradableItemInShopItem = nextShopItem.Costume; break; case ItemType.Material: nextTradableItemInShopItem = nextShopItem.TradableFungibleItem; break; default: throw new ArgumentOutOfRangeException(nameof(itemType), itemType, null); } Assert.Equal(price, nextShopItem.Price); Assert.Equal(expectedProductId, nextShopItem.ProductId); Assert.Equal(expiredBlockIndex, nextShopItem.ExpiredBlockIndex); Assert.Equal(_agentAddress, nextShopItem.SellerAgentAddress); Assert.Equal(_avatarAddress, nextShopItem.SellerAvatarAddress); Assert.Equal(expiredBlockIndex, nextTradableItemInShopItem.RequiredBlockIndex); var mailList = nextAvatarState.mailBox.Where(m => m is SellCancelMail).ToList(); Assert.Single(mailList); var mail = mailList.First() as SellCancelMail; Assert.NotNull(mail); Assert.Equal(expiredBlockIndex, mail.requiredBlockIndex); ITradableItem attachmentItem; int attachmentCount = 0; switch (itemType) { case ItemType.Consumable: case ItemType.Equipment: Assert.NotNull(mail.attachment.itemUsable); attachmentItem = mail.attachment.itemUsable; Assert.Equal(tradableItem, mail.attachment.itemUsable); break; case ItemType.Costume: Assert.NotNull(mail.attachment.costume); attachmentItem = mail.attachment.costume; Assert.Equal(tradableItem, mail.attachment.costume); break; case ItemType.Material: Assert.NotNull(mail.attachment.tradableFungibleItem); attachmentItem = mail.attachment.tradableFungibleItem; attachmentCount = mail.attachment.tradableFungibleItemCount; break; default: throw new ArgumentOutOfRangeException(nameof(itemType), itemType, null); } Assert.Equal(attachmentCount, nextShopItem.TradableFungibleItemCount); Assert.Equal(nextTradableItem, attachmentItem); Assert.Equal(nextTradableItemInShopItem, attachmentItem); }
public void Execute_20210604( long blockIndex, ItemSubType itemSubType, string agentAddressHex, string avatarAddressHex, long shopExpiredBlockIndex, long expectedBlockIndex, int shopItemCount, int itemCount, int shopPrice, int expectedPrice) { var avatarState = _initialState.GetAvatarState(_avatarAddress); var sellerAgentAddress = new Address(agentAddressHex); var sellerAvatarAddress = new Address(avatarAddressHex); ITradableItem tradableItem; switch (itemSubType) { case ItemSubType.Weapon: tradableItem = ItemFactory.CreateItemUsable( _tableSheets.EquipmentItemSheet.OrderedList.First(row => row.ItemSubType == ItemSubType.Weapon), Guid.NewGuid(), 1); break; case ItemSubType.Hourglass: var tradableMaterialRow = _tableSheets.MaterialItemSheet.OrderedList .First(row => row.ItemSubType == ItemSubType.Hourglass); tradableItem = ItemFactory.CreateTradableMaterial(tradableMaterialRow); tradableItem.RequiredBlockIndex = 1; break; default: throw new ArgumentOutOfRangeException(nameof(itemSubType), itemSubType, null); } Assert.Equal(1, tradableItem.RequiredBlockIndex); avatarState.inventory.AddItem2((ItemBase)tradableItem, itemCount); var previousStates = _initialState; previousStates = previousStates.SetState(_avatarAddress, avatarState.Serialize()); var currencyState = previousStates.GetGoldCurrency(); var price = new FungibleAssetValue(currencyState, expectedPrice, 0); var productId = new Guid("6f460c1a755d48e4ad6765d5f519dbc8"); var shardedShopAddress = ShardedShopState.DeriveAddress( tradableItem.ItemSubType, productId); Assert.Equal(1, tradableItem.RequiredBlockIndex); var shopItem = new ShopItem( sellerAgentAddress, sellerAvatarAddress, Guid.NewGuid(), new FungibleAssetValue(currencyState, shopPrice, 0), shopExpiredBlockIndex, tradableItem, shopItemCount ); var shardedShopState = new ShardedShopState(shardedShopAddress); shardedShopState.Register(shopItem); Assert.Single(shardedShopState.Products); previousStates = previousStates.SetState( shardedShopAddress, shardedShopState.Serialize()); var sellAction = new Sell6 { sellerAvatarAddress = _avatarAddress, tradableId = tradableItem.TradableId, count = itemCount, price = price, itemSubType = tradableItem.ItemSubType, }; var nextState = sellAction.Execute(new ActionContext { BlockIndex = blockIndex, PreviousStates = previousStates, Rehearsal = false, Signer = _agentAddress, Random = new TestRandom(), }); // Check AvatarState and Inventory var nextAvatarState = nextState.GetAvatarState(_avatarAddress); Assert.Single(nextAvatarState.inventory.Items); Assert.True(nextAvatarState.inventory.TryGetTradableItems( tradableItem.TradableId, expectedBlockIndex, itemCount, out var inventoryItems)); Assert.Single(inventoryItems); ITradableItem nextTradableItem = (ITradableItem)inventoryItems.First().item; Assert.Equal(expectedBlockIndex, nextTradableItem.RequiredBlockIndex); // Check ShardedShopState and ShopItem var nextSerializedShardedShopState = nextState.GetState(shardedShopAddress); Assert.NotNull(nextSerializedShardedShopState); var nextShardedShopState = new ShardedShopState((Dictionary)nextSerializedShardedShopState); Assert.Equal(2, nextShardedShopState.Products.Count); Assert.Single(nextShardedShopState.Products.Values.Where(s => s.Equals(shopItem))); Assert.Single(nextShardedShopState.Products.Values.Where(s => !s.Equals(shopItem))); ShopItem nextShopItem = nextShardedShopState.Products.Values.First(s => !s.Equals(shopItem)); ITradableItem innerShopItem = nextShopItem.TradableFungibleItem; int fungibleCount = itemCount; if (itemSubType == ItemSubType.Weapon) { innerShopItem = nextShopItem.ItemUsable; fungibleCount = 0; } Assert.Equal(price, nextShopItem.Price); Assert.Equal(expectedBlockIndex, nextShopItem.ExpiredBlockIndex); Assert.Equal(_agentAddress, nextShopItem.SellerAgentAddress); Assert.Equal(_avatarAddress, nextShopItem.SellerAvatarAddress); Assert.Equal(expectedBlockIndex, innerShopItem.RequiredBlockIndex); Assert.Equal(fungibleCount, nextShopItem.TradableFungibleItemCount); var mailList = nextAvatarState.mailBox.Where(m => m is SellCancelMail).ToList(); Assert.Single(mailList); var mail = mailList.First() as SellCancelMail; Assert.NotNull(mail); Assert.Equal(expectedBlockIndex, mail.requiredBlockIndex); ITradableItem attachmentItem = itemSubType == ItemSubType.Weapon ? (ITradableItem)mail.attachment.itemUsable : mail.attachment.tradableFungibleItem; Assert.Equal(itemSubType == ItemSubType.Weapon, mail.attachment.tradableFungibleItem is null); Assert.Equal(fungibleCount, mail.attachment.tradableFungibleItemCount); Assert.Equal(nextTradableItem, attachmentItem); }