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