Skip to content

Commit

Permalink
test(ecocredit): buy direct batch integration test (#1103)
Browse files Browse the repository at this point in the history
* test: buy direct batch integration test

* fix: use unique key mnemonic

* fix: order indecies, test cases

* chore: address review

* chore: use Equal instead of True

Co-authored-by: tyler <tylergoodman@Tylers-MacBook-Pro.local>
Co-authored-by: technicallyty <48813565+tytech3@users.noreply.github.com>
Co-authored-by: Ryan Christoffersen <12519942+ryanchristo@users.noreply.github.com>
  • Loading branch information
4 people authored May 23, 2022
1 parent 66ca147 commit 9451b49
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 3 deletions.
4 changes: 1 addition & 3 deletions x/ecocredit/client/marketplace/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ func TxBuyDirectBatch() *cobra.Command {
"retirement_jurisdiction": "US-NY"
},
]`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand All @@ -285,9 +286,6 @@ func TxBuyDirectBatch() *cobra.Command {
Buyer: clientCtx.GetFromAddress().String(),
Orders: orders,
}
if err = msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
Expand Down
133 changes: 133 additions & 0 deletions x/ecocredit/client/testsuite/tx.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package testsuite

import (
"encoding/json"
"fmt"
"strconv"
"strings"
Expand Down Expand Up @@ -1430,6 +1431,138 @@ func (s *IntegrationTestSuite) TestTxBuyDirect() {
}
}

func (s *IntegrationTestSuite) TestTxBuyDirectBatch() {
val0 := s.network.Validators[0]
valAddrStr := val0.Address.String()
clientCtx := val0.ClientCtx
cmd := marketplaceclient.TxBuyDirectBatch()

validAskDenom := sdk.DefaultBondDenom
askCoin := sdk.NewInt64Coin(validAskDenom, 10)

buyerAcc := s.addr
s.fundAccount(clientCtx, val0.Address, buyerAcc, sdk.Coins{sdk.NewInt64Coin(validAskDenom, 500)})

expiration, err := types.ParseDate("expiration", "3020-04-15")
s.Require().NoError(err)
_, _, batchDenom := s.createClassProjectBatch(clientCtx, valAddrStr)
orderIds, err := s.createSellOrder(clientCtx, &marketplace.MsgSell{
Owner: valAddrStr,
Orders: []*marketplace.MsgSell_Order{
{batchDenom, "10", &askCoin, true, &expiration},
{batchDenom, "10", &askCoin, false, &expiration},
},
})

buyOrders := []*marketplace.MsgBuyDirect_Order{
{SellOrderId: orderIds[0], Quantity: "10", BidPrice: &askCoin, DisableAutoRetire: true},
{SellOrderId: orderIds[1], Quantity: "10", BidPrice: &askCoin, RetirementJurisdiction: "US-OR"},
}
ordersBz, err := json.Marshal(buyOrders)
s.Require().NoError(err)
jsonFile := testutil.WriteToNewTempFile(s.T(), string(ordersBz))

makeArgs := func(fileName, from string) []string {
args := []string{fileName, makeFlagFrom(from)}
return append(args, s.commonTxFlags()...)
}

testCases := []struct {
name string
args []string
errMsg string
}{
{
name: "too many args",
args: []string{"foo", "bar"},
errMsg: "accepts 1 arg(s), received 2",
},
{
name: "invalid: file does not exist",
args: []string{"monkey.jpeg"},
errMsg: "no such file or directory",
},
{
name: "valid order",
args: makeArgs(jsonFile.Name(), buyerAcc.String()),
},
}
for _, tc := range testCases {
s.Run(tc.name, func() {
if len(tc.errMsg) != 0 {
_, err := cli.ExecTestCLICmd(clientCtx, cmd, tc.args)
s.Require().ErrorContains(err, tc.errMsg)
} else {
sellerAccBefore := s.getAccountInfo(clientCtx, val0.Address, askCoin.Denom, batchDenom)
buyerAccBefore := s.getAccountInfo(clientCtx, buyerAcc, askCoin.Denom, batchDenom)

out, err := cli.ExecTestCLICmd(clientCtx, cmd, tc.args)
s.Require().NoError(err)

sellerAccAfter := s.getAccountInfo(clientCtx, val0.Address, askCoin.Denom, batchDenom)
buyerAccAfter := s.getAccountInfo(clientCtx, buyerAcc, askCoin.Denom, batchDenom)

var res sdk.TxResponse
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &res))
s.Require().Equal(uint32(0), res.Code)
s.assertMarketBalanceBatchUpdated(sellerAccBefore, sellerAccAfter, buyerAccBefore, buyerAccAfter, buyOrders)
}
})
}
}

// assertMarketBalanceBatchUpdated asserts that all accounts involved in a marketplace transaction are updated properly.
// it assumes that both seller/buyer accounts used the same denom for amount sold/bought.
func (s *IntegrationTestSuite) assertMarketBalanceBatchUpdated(sb, sa, bb, ba accountInfo, orders []*marketplace.MsgBuyDirect_Order) {
tradSold, retSold := math.NewDecFromInt64(0), math.NewDecFromInt64(0)
cost := sdk.NewInt64Coin(sdk.DefaultBondDenom, 0)
for _, order := range orders {
qty, err := math.NewDecFromString(order.Quantity)
s.Require().NoError(err)
if order.DisableAutoRetire {
tradSold, err = tradSold.Add(qty)
s.Require().NoError(err)
} else {
retSold, err = retSold.Add(qty)
s.Require().NoError(err)
}
costDec, err := math.NewDecFromString(order.BidPrice.Amount.String())
s.Require().NoError(err)
totalCostDec, err := qty.Mul(costDec)
s.Require().NoError(err)
c := sdk.NewCoin(order.BidPrice.Denom, totalCostDec.SdkIntTrim())
cost = cost.Add(c)
}

totalSold, err := tradSold.Add(retSold)
s.Require().NoError(err)

// check sellers coins
expectedSellerGain := sb.coinBal.Add(cost)
s.Require().Equal(expectedSellerGain, sa.coinBal)

// check buyers coins
// we use LT in the buyer case, as some coins go towards fees, so their balance will be LOWER than before - total cost.
expectedBuyerCost := bb.coinBal.Sub(cost)
s.Require().True(ba.coinBal.IsLT(expectedBuyerCost))

// check sellers credits
expectedEscrowed, err := sb.escrowed.Sub(totalSold)
s.Require().NoError(err)
s.Require().Equal(expectedEscrowed.String(), sa.escrowed.String())
s.Require().Equal(sb.tradable.String(), sa.tradable.String())
s.Require().Equal(sb.retired.String(), sa.retired.String())

expectedRetired, err := bb.retired.Add(retSold)
s.Require().NoError(err)
expectedTradable, err := bb.tradable.Add(tradSold)
s.Require().NoError(err)

s.Require().Equal(bb.escrowed.String(), bb.escrowed.String())
s.Require().Equal(ba.tradable.String(), expectedTradable.String())
s.Require().Equal(ba.retired.String(), expectedRetired.String())
}

func (s *IntegrationTestSuite) TestUpdateProjectMetadata() {
admin := s.network.Validators[0]
valAddrStr := admin.Address.String()
Expand Down

0 comments on commit 9451b49

Please sign in to comment.