Skip to content

Commit

Permalink
Merge pull request planetarium#398 from planetarium/improve/tradable-…
Browse files Browse the repository at this point in the history
…material

Fix Material sell
  • Loading branch information
ipdae authored May 7, 2021
2 parents 8aa415f + e9e580d commit 91af105
Show file tree
Hide file tree
Showing 7 changed files with 456 additions and 175 deletions.
56 changes: 41 additions & 15 deletions .Lib9c.Tests/Action/SellCancellationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,16 @@ public SellCancellationTest(ITestOutputHelper outputHelper)
}

[Theory]
[InlineData(ItemType.Equipment, "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4", true)]
[InlineData(ItemType.Costume, "936DA01F-9ABD-4d9d-80C7-02AF85C822A8", true)]
[InlineData(ItemType.Equipment, "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4", false)]
[InlineData(ItemType.Costume, "936DA01F-9ABD-4d9d-80C7-02AF85C822A8", false)]
public void Execute(ItemType itemType, string guid, bool contain)
[InlineData(ItemType.Equipment, "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4", true, 1)]
[InlineData(ItemType.Costume, "936DA01F-9ABD-4d9d-80C7-02AF85C822A8", true, 1)]
[InlineData(ItemType.Material, "15396359-04db-68d5-f24a-d89c18665900", true, 1)]
[InlineData(ItemType.Material, "15396359-04db-68d5-f24a-d89c18665900", true, 2)]
[InlineData(ItemType.Equipment, "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4", false, 1)]
[InlineData(ItemType.Costume, "936DA01F-9ABD-4d9d-80C7-02AF85C822A8", false, 1)]
public void Execute(ItemType itemType, string guid, bool contain, int itemCount)
{
var avatarState = _initialState.GetAvatarState(_avatarAddress);
INonFungibleItem nonFungibleItem;
ITradableItem tradableItem;
Guid itemId = new Guid(guid);
Guid productId = itemId;
ItemSubType itemSubType;
Expand All @@ -92,16 +94,23 @@ public void Execute(ItemType itemType, string guid, bool contain)
_tableSheets.EquipmentItemSheet.First,
itemId,
requiredBlockIndex);
nonFungibleItem = itemUsable;
tradableItem = itemUsable;
itemSubType = itemUsable.ItemSubType;
}
else
else if (itemType == ItemType.Costume)
{
var costume = ItemFactory.CreateCostume(_tableSheets.CostumeItemSheet.First, itemId);
costume.Update(requiredBlockIndex);
nonFungibleItem = costume;
tradableItem = costume;
itemSubType = costume.ItemSubType;
}
else
{
var material = ItemFactory.CreateTradableMaterial(
_tableSheets.MaterialItemSheet.OrderedList.First(r => r.ItemSubType == ItemSubType.Hourglass));
itemSubType = material.ItemSubType;
tradableItem = material;
}

var result = new DailyReward.DailyRewardResult()
{
Expand All @@ -123,12 +132,13 @@ public void Execute(ItemType itemType, string guid, bool contain)
productId,
new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
requiredBlockIndex,
nonFungibleItem);
tradableItem,
itemCount);

if (contain)
{
shopState.Register(shopItem);
avatarState.inventory.AddItem((ItemBase)nonFungibleItem);
avatarState.inventory.AddItem((ItemBase)tradableItem, itemCount);
Assert.Empty(legacyShopState.Products);
Assert.Single(shopState.Products);
}
Expand All @@ -139,8 +149,11 @@ public void Execute(ItemType itemType, string guid, bool contain)
Assert.Empty(shopState.Products);
}

Assert.Equal(requiredBlockIndex, nonFungibleItem.RequiredBlockIndex);
Assert.Equal(contain, avatarState.inventory.TryGetNonFungibleItem(itemId, out _));
Assert.Equal(requiredBlockIndex, tradableItem.RequiredBlockIndex);
Assert.Equal(
contain,
avatarState.inventory.TryGetTradableItems(itemId, requiredBlockIndex, itemCount, out _)
);

IAccountStateDelta prevState = _initialState
.SetState(_avatarAddress, avatarState.Serialize())
Expand All @@ -166,8 +179,21 @@ public void Execute(ItemType itemType, string guid, bool contain)
Assert.Empty(nextShopState.Products);

var nextAvatarState = nextState.GetAvatarState(_avatarAddress);
Assert.True(nextAvatarState.inventory.TryGetNonFungibleItem(itemId, out INonFungibleItem nextNonFungibleItem));
Assert.Equal(1, nextNonFungibleItem.RequiredBlockIndex);
Assert.False(nextAvatarState.inventory.TryGetTradableItems(
itemId,
requiredBlockIndex,
itemCount,
out List<Inventory.Item> _
));
Assert.True(nextAvatarState.inventory.TryGetTradableItems(
itemId,
1,
itemCount,
out List<Inventory.Item> inventoryItems
));
Assert.Single(inventoryItems);
ITradableItem nextTradableItem = (ITradableItem)inventoryItems.First().item;
Assert.Equal(1, nextTradableItem.RequiredBlockIndex);
Assert.Equal(30, nextAvatarState.mailBox.Count);
ShopState nextLegacyShopState = nextState.GetShopState();
Assert.Empty(nextLegacyShopState.Products);
Expand Down
156 changes: 78 additions & 78 deletions .Lib9c.Tests/Action/SellTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,28 +69,6 @@ public SellTest(ITestOutputHelper outputHelper)
};
agentState.avatarAddresses[0] = _avatarAddress;

var equipment = ItemFactory.CreateItemUsable(
_tableSheets.EquipmentItemSheet.First,
Guid.NewGuid(),
0);
_avatarState.inventory.AddItem(equipment);

var consumable = ItemFactory.CreateItemUsable(
_tableSheets.ConsumableItemSheet.First,
Guid.NewGuid(),
0);
_avatarState.inventory.AddItem(consumable);

var costume = ItemFactory.CreateCostume(
_tableSheets.CostumeItemSheet.First,
Guid.NewGuid());
_avatarState.inventory.AddItem(costume);

var tradableMaterialRow = _tableSheets.MaterialItemSheet.OrderedList
.FirstOrDefault(row => row.ItemSubType == ItemSubType.Hourglass);
var tradableMaterial = ItemFactory.CreateTradableMaterial(tradableMaterialRow);
_avatarState.inventory.AddItem(tradableMaterial);

_initialState = _initialState
.SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize())
.SetState(Addresses.Shop, shopState.Serialize())
Expand All @@ -99,26 +77,64 @@ public SellTest(ITestOutputHelper outputHelper)
}

[Theory]
[InlineData(ItemType.Consumable, true, 2)]
[InlineData(ItemType.Costume, true, 2)]
[InlineData(ItemType.Equipment, true, 2)]
[InlineData(ItemType.Material, true, 2)]
[InlineData(ItemType.Consumable, false, 0)]
[InlineData(ItemType.Costume, false, 0)]
[InlineData(ItemType.Equipment, false, 0)]
[InlineData(ItemType.Material, false, 0)]
public void Execute(ItemType itemType, bool shopItemExist, int blockIndex)
[InlineData(ItemType.Consumable, true, 2, 1, 1, 1)]
[InlineData(ItemType.Costume, true, 2, 1, 1, 1)]
[InlineData(ItemType.Equipment, true, 2, 1, 1, 1)]
[InlineData(ItemType.Consumable, false, 0, 1, 1, 1)]
[InlineData(ItemType.Costume, false, 0, 1, 1, 1)]
[InlineData(ItemType.Equipment, false, 0, 1, 1, 1)]
[InlineData(ItemType.Material, true, 1, 2, 1, 1)]
[InlineData(ItemType.Material, true, 1, 1, 2, 1)]
[InlineData(ItemType.Material, true, 2, 1, 2, 2)]
[InlineData(ItemType.Material, true, 3, 2, 2, 2)]
[InlineData(ItemType.Material, false, 1, 1, 1, 1)]
public void Execute(
ItemType itemType,
bool shopItemExist,
long blockIndex,
int itemCount,
int prevCount,
int expectedProductsCount
)
{
var avatarState = _initialState.GetAvatarState(_avatarAddress);
var inventoryItems = avatarState.inventory.Items
.Where(i => i.item.ItemType == itemType)
.ToList();
Assert.NotEmpty(inventoryItems);

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.AddItem((ItemBase)tradableItem, itemCount);

var previousStates = _initialState;
previousStates = previousStates.SetState(_avatarAddress, avatarState.Serialize());
var currencyState = previousStates.GetGoldCurrency();
var price = new FungibleAssetValue(currencyState, ProductPrice, 0);
var tradableItem = (ITradableItem)inventoryItems.First().item;
var productId = new Guid("6f460c1a755d48e4ad6765d5f519dbc8");
var shardedShopAddress = ShardedShopState.DeriveAddress(
tradableItem.ItemSubType,
Expand All @@ -130,10 +146,12 @@ public void Execute(ItemType itemType, bool shopItemExist, int blockIndex)
var shopItem = new ShopItem(
_agentAddress,
_avatarAddress,
productId,
expectedProductsCount == 2 ? Guid.NewGuid() : productId,
price,
blockIndex,
tradableItem);
tradableItem,
prevCount
);

var shardedShopState = new ShardedShopState(shardedShopAddress);
shardedShopState.Register(shopItem);
Expand All @@ -151,7 +169,7 @@ public void Execute(ItemType itemType, bool shopItemExist, int blockIndex)
{
sellerAvatarAddress = _avatarAddress,
tradableId = tradableItem.TradableId,
count = 1,
count = itemCount,
price = price,
itemSubType = tradableItem.ItemSubType,
};
Expand All @@ -168,21 +186,24 @@ public void Execute(ItemType itemType, bool shopItemExist, int blockIndex)

// Check AvatarState and Inventory
var nextAvatarState = nextState.GetAvatarState(_avatarAddress);
Assert.True(nextAvatarState.inventory.TryGetTradableItem(
Assert.Single(nextAvatarState.inventory.Items);
Assert.True(nextAvatarState.inventory.TryGetTradableItems(
tradableItem.TradableId,
out var nextInventoryItem));
var nextTradableItem = nextInventoryItem.item as ITradableItem;
Assert.NotNull(nextTradableItem);
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.Single(nextShardedShopState.Products);
Assert.Equal(expectedProductsCount, nextShardedShopState.Products.Count);

var nextShopItem = nextShardedShopState.Products.Values.First();
var nextShopItem = nextShardedShopState.Products.Values.First(s => s.ExpiredBlockIndex == expiredBlockIndex);
ITradableItem nextTradableItemInShopItem;
switch (itemType)
{
Expand Down Expand Up @@ -211,25 +232,34 @@ public void Execute(ItemType itemType, bool shopItemExist, int blockIndex)
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);
Assert.Equal(tradableItem, mail.attachment.tradableFungibleItem);
Assert.True(mail.attachment.tradableFungibleItemCount == 1);
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);
}

[Fact]
Expand Down Expand Up @@ -347,37 +377,7 @@ public void Execute_Throw_InvalidItemTypeException()

Assert.Throws<InvalidItemTypeException>(() => action.Execute(new ActionContext
{
BlockIndex = 0,
PreviousStates = _initialState,
Signer = _agentAddress,
Random = new TestRandom(),
}));
}

[Fact]
public void Execute_Throw_RequiredBlockIndexException()
{
var equipmentId = Guid.NewGuid();
var equipment = ItemFactory.CreateItemUsable(
_tableSheets.EquipmentItemSheet.First,
equipmentId,
10);
_avatarState.inventory.AddItem(equipment);

_initialState = _initialState.SetState(_avatarAddress, _avatarState.Serialize());

var action = new Sell
{
sellerAvatarAddress = _avatarAddress,
tradableId = equipmentId,
count = 1,
price = 0 * _currency,
itemSubType = equipment.ItemSubType,
};

Assert.Throws<RequiredBlockIndexException>(() => action.Execute(new ActionContext
{
BlockIndex = 0,
BlockIndex = 11,
PreviousStates = _initialState,
Signer = _agentAddress,
Random = new TestRandom(),
Expand Down
Loading

0 comments on commit 91af105

Please sign in to comment.