예제 #1
0
        public void ExecuteThrowNotEnoughClearedStageLevelException()
        {
            var avatarState = new AvatarState(_buyerAvatarState)
            {
                worldInformation = new WorldInformation(
                    0,
                    _tableSheets.WorldSheet,
                    0
                    ),
            };

            _initialState = _initialState.SetState(_buyerAvatarAddress, avatarState.Serialize());

            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = new List <BuyMultiple.PurchaseInfo>(),
            };

            Assert.Throws <NotEnoughClearedStageLevelException>(() => action.Execute(new ActionContext()
            {
                BlockIndex     = 0,
                PreviousStates = _initialState,
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            })
                                                                );
        }
예제 #2
0
        public void ExecuteThrowShopItemExpiredError()
        {
            var sellerAvatarAddress = new PrivateKey().ToAddress();
            var sellerAgentAddress  = new PrivateKey().ToAddress();

            var(avatarState, agentState) = CreateAvatarState(sellerAgentAddress, sellerAvatarAddress);

            IAccountStateDelta previousStates = _initialState;
            var shopState = previousStates.GetShopState();

            var productId = Guid.NewGuid();
            var equipment = ItemFactory.CreateItemUsable(
                _tableSheets.EquipmentItemSheet.First,
                Guid.NewGuid(),
                10);

            shopState.Register(new ShopItem(
                                   sellerAgentAddress,
                                   sellerAvatarAddress,
                                   productId,
                                   new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
                                   10,
                                   equipment));

            previousStates = previousStates
                             .SetState(Addresses.Shop, shopState.Serialize());
            shopState = previousStates.GetShopState();

            Assert.True(shopState.Products.ContainsKey(productId));
            var products = shopState.Products.Values
                           .Select(p => new BuyMultiple.PurchaseInfo(
                                       p.ProductId,
                                       p.SellerAgentAddress,
                                       p.SellerAvatarAddress))
                           .ToList();

            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = products,
            };

            action.Execute(new ActionContext()
            {
                BlockIndex     = 11,
                PreviousStates = previousStates,
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            });

            var results     = action.buyerResult.purchaseResults;
            var isAllFailed = results.Any(r => r.errorCode == BuyMultiple.ERROR_CODE_SHOPITEM_EXPIRED);

            Assert.True(isAllFailed);
        }
예제 #3
0
        public void ExecuteThrowFailedLoadStateException()
        {
            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = new List <BuyMultiple.PurchaseInfo>(),
            };

            Assert.Throws <FailedLoadStateException>(() => action.Execute(new ActionContext()
            {
                BlockIndex     = 0,
                PreviousStates = new State(),
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            })
                                                     );
        }
예제 #4
0
        public void ExecuteThrowInvalidAddressException()
        {
            var shopState = _initialState.GetShopState();
            var costume   = ItemFactory.CreateCostume(
                _tableSheets.CostumeItemSheet.First,
                Guid.NewGuid());

            shopState.Register(new ShopItem(
                                   _buyerAgentAddress,
                                   _buyerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
                                   100,
                                   costume));

            _initialState = _initialState
                            .SetState(Addresses.Shop, shopState.Serialize());

            shopState = _initialState.GetShopState();
            var products = shopState.Products.Values
                           .Select(p => new BuyMultiple.PurchaseInfo(
                                       p.ProductId,
                                       p.SellerAgentAddress,
                                       p.SellerAvatarAddress))
                           .ToList();

            Assert.NotEmpty(products);

            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = products,
            };

            Assert.Throws <InvalidAddressException>(() => action.Execute(new ActionContext()
            {
                BlockIndex     = 0,
                PreviousStates = new State(),
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            })
                                                    );
        }
예제 #5
0
        public void ExecuteThrowItemDoesNotExistErrorByEmptyCollection()
        {
            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = new List <BuyMultiple.PurchaseInfo>(),
            };

            action.Execute(new ActionContext()
            {
                BlockIndex     = 0,
                PreviousStates = _initialState,
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            });

            var nextBuyerAvatarState = _initialState.GetAvatarState(_buyerAvatarAddress);

            foreach (var result in action.buyerResult.purchaseResults)
            {
                Assert.Equal(BuyMultiple.ERROR_CODE_ITEM_DOES_NOT_EXIST, result.errorCode);
            }
        }
예제 #6
0
        public void SerializeWithDotnetAPI()
        {
            var sellerAvatarAddress = new PrivateKey().ToAddress();
            var sellerAgentAddress  = new PrivateKey().ToAddress();

            CreateAvatarState(sellerAgentAddress, sellerAvatarAddress);

            IAccountStateDelta previousStates = _initialState;
            var shopState = previousStates.GetShopState();

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

            shopState.Register(new ShopItem(
                                   sellerAgentAddress,
                                   sellerAvatarAddress,
                                   productId,
                                   new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
                                   100,
                                   equipment));
            shopState.Register(new ShopItem(
                                   sellerAgentAddress,
                                   sellerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
                                   100,
                                   equipment));
            var products = shopState.Products.Values
                           .Select(p => new BuyMultiple.PurchaseInfo(
                                       p.ProductId,
                                       p.SellerAgentAddress,
                                       p.SellerAvatarAddress))
                           .ToList();

            previousStates = previousStates
                             .SetState(Addresses.Shop, shopState.Serialize());

            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = products,
            };

            action.Execute(new ActionContext()
            {
                BlockIndex     = 1,
                PreviousStates = previousStates,
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            });

            var formatter = new BinaryFormatter();

            using var ms = new MemoryStream();
            formatter.Serialize(ms, action);
            ms.Seek(0, SeekOrigin.Begin);

            var deserialized = (BuyMultiple)formatter.Deserialize(ms);

            Assert.Equal(action.PlainValue, deserialized.PlainValue);
        }
예제 #7
0
        public void ExecuteInsufficientBalanceError()
        {
            var shopState = _initialState.GetShopState();

            var sellerAvatarAddress = new PrivateKey().ToAddress();
            var sellerAgentAddress  = new PrivateKey().ToAddress();

            var(avatarState, agentState) = CreateAvatarState(sellerAgentAddress, sellerAvatarAddress);

            var equipment = ItemFactory.CreateItemUsable(
                _tableSheets.EquipmentItemSheet.First,
                Guid.NewGuid(),
                1);

            shopState.Register(new ShopItem(
                                   sellerAgentAddress,
                                   sellerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, 1, 0),
                                   100,
                                   equipment));

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

            shopState.Register(new ShopItem(
                                   sellerAgentAddress,
                                   sellerAvatarAddress,
                                   Guid.NewGuid(),
                                   new FungibleAssetValue(_goldCurrencyState.Currency, 100, 0),
                                   100,
                                   costume));

            _initialState = _initialState
                            .SetState(Addresses.Shop, shopState.Serialize());
            shopState = _initialState.GetShopState();
            Assert.NotEmpty(shopState.Products);

            var products = shopState.Products.Values
                           .Select(p => new BuyMultiple.PurchaseInfo(
                                       p.ProductId,
                                       p.SellerAgentAddress,
                                       p.SellerAvatarAddress))
                           .ToList();

            Assert.NotEmpty(products);

            var balance = _initialState.GetBalance(_buyerAgentAddress, _goldCurrencyState.Currency);

            _initialState = _initialState.BurnAsset(_buyerAgentAddress, balance);

            var action = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = products,
            };

            action.Execute(new ActionContext()
            {
                BlockIndex     = 0,
                PreviousStates = _initialState,
                Random         = new TestRandom(),
                Signer         = _buyerAgentAddress,
            });

            var results     = action.buyerResult.purchaseResults;
            var isAllFailed = results.Any(r => r.errorCode == BuyMultiple.ERROR_CODE_INSUFFICIENT_BALANCE);

            Assert.True(isAllFailed);
        }
예제 #8
0
        public void Execute(params ShopItemData[] productDatas)
        {
            var buyerAvatarState = _initialState.GetAvatarState(_buyerAvatarAddress);

            var goldCurrency = _initialState.GetGoldCurrency();
            var shopState    = _initialState.GetShopState();
            var buyCount     = 0;
            var itemsToBuy   = new List <BuyMultiple.PurchaseInfo>();

            foreach (var product in productDatas)
            {
                var(sellerAvatarState, sellerAgentState) =
                    CreateAvatarState(product.SellerAgentAddress, product.SellerAvatarAddress);

                INonFungibleItem nonFungibleItem;
                if (product.ItemType == ItemType.Equipment)
                {
                    var itemUsable = ItemFactory.CreateItemUsable(
                        _tableSheets.EquipmentItemSheet.First,
                        product.ItemId,
                        product.RequiredBlockIndex);
                    nonFungibleItem = itemUsable;
                }
                else
                {
                    var costume = ItemFactory.CreateCostume(_tableSheets.CostumeItemSheet.First, product.ItemId);
                    costume.Update(product.RequiredBlockIndex);
                    nonFungibleItem = costume;
                }

                // Case for backward compatibility of `Buy`
                if (product.ContainsInInventory)
                {
                    sellerAvatarState.inventory.AddItem2((ItemBase)nonFungibleItem);
                }

                var shopItemId = Guid.NewGuid();

                var shopItem = new ShopItem(
                    sellerAgentState.address,
                    sellerAvatarState.address,
                    shopItemId,
                    new FungibleAssetValue(_goldCurrencyState.Currency, product.Price, 0),
                    product.RequiredBlockIndex,
                    nonFungibleItem);
                shopState.Register(shopItem);

                if (product.Buy)
                {
                    ++buyCount;
                    var purchaseInfo = new BuyMultiple.PurchaseInfo(
                        shopItem.ProductId,
                        shopItem.SellerAgentAddress,
                        shopItem.SellerAvatarAddress);
                    itemsToBuy.Add(purchaseInfo);
                }
            }

            Assert.NotNull(shopState.Products);
            Assert.Equal(3, shopState.Products.Count);

            _initialState = _initialState
                            .SetState(_buyerAvatarAddress, buyerAvatarState.Serialize())
                            .SetState(Addresses.Shop, shopState.Serialize());

            var priceData = new PriceData(goldCurrency);

            foreach (var avatarState in _sellerAgentStateMap.Keys)
            {
                var agentState = _sellerAgentStateMap[avatarState];
                priceData.TaxedPriceSum[agentState.address] = new FungibleAssetValue(goldCurrency, 0, 0);

                _initialState = _initialState
                                .SetState(avatarState.address, avatarState.Serialize());
            }

            IAccountStateDelta previousStates = _initialState;

            var buyerGold    = previousStates.GetBalance(_buyerAgentAddress, goldCurrency);
            var priceSumData = productDatas
                               .Where(i => i.Buy)
                               .Aggregate(priceData, (priceSum, next) =>
            {
                var price         = new FungibleAssetValue(goldCurrency, next.Price, 0);
                var tax           = price.DivRem(100, out _) * Buy.TaxRate;
                var taxedPrice    = price - tax;
                priceData.TaxSum += tax;

                var prevSum = priceData.TaxedPriceSum[next.SellerAgentAddress];
                priceData.TaxedPriceSum[next.SellerAgentAddress] = prevSum + taxedPrice;
                priceData.PriceSum += price;
                return(priceData);
            });

            var buyMultipleAction = new BuyMultiple
            {
                buyerAvatarAddress = _buyerAvatarAddress,
                purchaseInfos      = itemsToBuy,
            };
            var nextState = buyMultipleAction.Execute(new ActionContext()
            {
                BlockIndex     = 1,
                PreviousStates = previousStates,
                Random         = new TestRandom(),
                Rehearsal      = false,
                Signer         = _buyerAgentAddress,
            });

            var nextShopState = nextState.GetShopState();

            Assert.Equal(productDatas.Length - buyCount, nextShopState.Products.Count);

            var nextBuyerAvatarState = nextState.GetAvatarState(_buyerAvatarAddress);

            foreach (var product in productDatas.Where(i => i.Buy))
            {
                Assert.True(
                    nextBuyerAvatarState.inventory.TryGetNonFungibleItem(
                        product.ItemId,
                        out INonFungibleItem outNonFungibleItem)
                    );
                Assert.Equal(product.RequiredBlockIndex, outNonFungibleItem.RequiredBlockIndex);
            }

            Assert.Equal(buyCount, nextBuyerAvatarState.mailBox.Count);

            goldCurrency = nextState.GetGoldCurrency();
            var nextGoldCurrencyGold = nextState.GetBalance(Addresses.GoldCurrency, goldCurrency);

            Assert.Equal(priceSumData.TaxSum, nextGoldCurrencyGold);

            foreach (var product in productDatas)
            {
                var nextSellerGold = nextState.GetBalance(product.SellerAgentAddress, goldCurrency);
                Assert.Equal(priceSumData.TaxedPriceSum[product.SellerAgentAddress], nextSellerGold);
            }

            var nextBuyerGold = nextState.GetBalance(_buyerAgentAddress, goldCurrency);

            Assert.Equal(buyerGold - priceSumData.PriceSum, nextBuyerGold);

            previousStates = nextState;
        }