github.com/Finschia/finschia-sdk@v0.49.1/x/token/client/testutil/suite.go (about)

     1  package testutil
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/gogo/protobuf/proto"
     7  	"github.com/stretchr/testify/suite"
     8  	abci "github.com/tendermint/tendermint/abci/types"
     9  
    10  	"github.com/Finschia/finschia-sdk/client/flags"
    11  	"github.com/Finschia/finschia-sdk/crypto/hd"
    12  	"github.com/Finschia/finschia-sdk/crypto/keyring"
    13  	clitestutil "github.com/Finschia/finschia-sdk/testutil/cli"
    14  	"github.com/Finschia/finschia-sdk/testutil/network"
    15  	sdk "github.com/Finschia/finschia-sdk/types"
    16  	bankcli "github.com/Finschia/finschia-sdk/x/bank/client/cli"
    17  	"github.com/Finschia/finschia-sdk/x/token"
    18  	"github.com/Finschia/finschia-sdk/x/token/client/cli"
    19  )
    20  
    21  type IntegrationTestSuite struct {
    22  	suite.Suite
    23  
    24  	cfg     network.Config
    25  	network *network.Network
    26  
    27  	setupHeight int64
    28  
    29  	vendor   sdk.AccAddress
    30  	customer sdk.AccAddress
    31  
    32  	classes []token.Contract
    33  
    34  	balance sdk.Int
    35  }
    36  
    37  var commonArgs = []string{
    38  	fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
    39  	fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
    40  	fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))).String()),
    41  }
    42  
    43  func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
    44  	return &IntegrationTestSuite{cfg: cfg}
    45  }
    46  
    47  func (s *IntegrationTestSuite) SetupSuite() {
    48  	s.T().Log("setting up integration test suite")
    49  
    50  	s.network = network.New(s.T(), s.cfg)
    51  	_, err := s.network.WaitForHeight(1)
    52  	s.Require().NoError(err)
    53  
    54  	s.vendor = s.createAccount("vendor")
    55  	s.customer = s.createAccount("customer")
    56  
    57  	s.classes = []token.Contract{
    58  		{
    59  			Name:     "test",
    60  			Symbol:   "ZERO",
    61  			Decimals: 8,
    62  			Mintable: true,
    63  		},
    64  		{
    65  			Name:     "test",
    66  			Symbol:   "ONE",
    67  			Decimals: 8,
    68  			Mintable: true,
    69  		},
    70  	}
    71  
    72  	s.balance = sdk.NewInt(1000)
    73  
    74  	// vendor creates 2 tokens
    75  	s.classes[1].Id = s.createClass(s.vendor, s.vendor, s.classes[1].Name, s.classes[1].Symbol, s.balance, s.classes[1].Mintable)
    76  	s.classes[0].Id = s.createClass(s.vendor, s.customer, s.classes[0].Name, s.classes[0].Symbol, s.balance, s.classes[0].Mintable)
    77  
    78  	// customer approves vendor to manipulate its tokens of the both classes, so vendor can do OperatorXXX (Send or Burn) later.
    79  	for _, class := range s.classes {
    80  		s.authorizeOperator(class.Id, s.customer, s.vendor)
    81  	}
    82  
    83  	s.setupHeight, err = s.network.LatestHeight()
    84  	s.Require().NoError(err)
    85  	s.Require().NoError(s.network.WaitForNextBlock())
    86  }
    87  
    88  func (s *IntegrationTestSuite) createClass(owner, to sdk.AccAddress, name, symbol string, supply sdk.Int, mintable bool) string {
    89  	val := s.network.Validators[0]
    90  	args := append([]string{
    91  		owner.String(),
    92  		to.String(),
    93  		name,
    94  		symbol,
    95  		fmt.Sprintf("--%s=%v", cli.FlagMintable, mintable),
    96  		fmt.Sprintf("--%s=%s", cli.FlagSupply, supply),
    97  		fmt.Sprintf("--%s=%s", flags.FlagFrom, owner),
    98  	}, commonArgs...)
    99  
   100  	out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.NewTxCmdIssue(), args)
   101  	s.Require().NoError(err)
   102  
   103  	var res sdk.TxResponse
   104  	s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &res), out.String())
   105  	s.Require().EqualValues(0, res.Code, out.String())
   106  
   107  	var event token.EventIssued
   108  	s.pickEvent(res.Events, &event, func(e proto.Message) {
   109  		event = *e.(*token.EventIssued)
   110  	})
   111  	return event.ContractId
   112  }
   113  
   114  // creates an account and send some coins to it for the future transactions.
   115  func (s *IntegrationTestSuite) createAccount(uid string) sdk.AccAddress {
   116  	val := s.network.Validators[0]
   117  	keyInfo, _, err := val.ClientCtx.Keyring.NewMnemonic(uid, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
   118  	s.Require().NoError(err)
   119  	addr := keyInfo.GetAddress()
   120  
   121  	fee := sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(1000)))
   122  	args := append([]string{
   123  		val.Address.String(),
   124  		addr.String(),
   125  		fee.String(),
   126  		fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address),
   127  	}, commonArgs...)
   128  	out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, bankcli.NewSendTxCmd(), args)
   129  	s.Require().NoError(err)
   130  
   131  	var res sdk.TxResponse
   132  	s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &res), out.String())
   133  	s.Require().EqualValues(0, res.Code, out.String())
   134  
   135  	return addr
   136  }
   137  
   138  func (s *IntegrationTestSuite) authorizeOperator(contractID string, holder, operator sdk.AccAddress) {
   139  	val := s.network.Validators[0]
   140  	args := append([]string{
   141  		contractID,
   142  		holder.String(),
   143  		operator.String(),
   144  		fmt.Sprintf("--%s=%s", flags.FlagFrom, holder),
   145  	}, commonArgs...)
   146  
   147  	out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.NewTxCmdAuthorizeOperator(), args)
   148  	s.Require().NoError(err)
   149  
   150  	var res sdk.TxResponse
   151  	s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &res), out.String())
   152  	s.Require().EqualValues(0, res.Code, out.String())
   153  }
   154  
   155  func (s *IntegrationTestSuite) pickEvent(events []abci.Event, event proto.Message, fn func(event proto.Message)) {
   156  	for _, e := range events {
   157  		if e.Type == proto.MessageName(event) {
   158  			msg, err := sdk.ParseTypedEvent(e)
   159  			s.Require().NoError(err)
   160  
   161  			fn(msg)
   162  			return
   163  		}
   164  	}
   165  
   166  	s.Require().Failf("event not found", "%s", events)
   167  }
   168  
   169  func (s *IntegrationTestSuite) TearDownSuite() {
   170  	s.T().Log("tearing down integration test suite")
   171  	s.network.Cleanup()
   172  }