github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/newcmd/action/xrc20transferfrom_test.go (about)

     1  package action
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/ethereum/go-ethereum/accounts/keystore"
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/iotexproject/iotex-address/address"
    11  	"github.com/iotexproject/iotex-proto/golang/iotexapi"
    12  	"github.com/iotexproject/iotex-proto/golang/iotexapi/mock_iotexapi"
    13  	"github.com/iotexproject/iotex-proto/golang/iotextypes"
    14  	"github.com/spf13/cobra"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/iotexproject/iotex-core/ioctl/config"
    18  	"github.com/iotexproject/iotex-core/ioctl/util"
    19  	"github.com/iotexproject/iotex-core/test/identityset"
    20  	"github.com/iotexproject/iotex-core/test/mock/mock_ioctlclient"
    21  )
    22  
    23  func TestNewXrc20TransferFromCmd(t *testing.T) {
    24  	var (
    25  		require = require.New(t)
    26  		ctrl    = gomock.NewController(t)
    27  
    28  		wrongAddr         = strings.Repeat("a", 41)
    29  		wrongAlias        = "xxx"
    30  		wrongAmount       = "xxx"
    31  		wrongContractData = "xxx"
    32  
    33  		dftOwner        = identityset.Address(0).String()
    34  		dftRecipient    = identityset.Address(1).String()
    35  		dftContract     = identityset.Address(2).String()
    36  		dftAmount       = "100"
    37  		dftContractData = "2F"
    38  		dftBalance      = "20000000000000100000"
    39  	)
    40  
    41  	passwd := "passwd"
    42  	ks := keystore.NewKeyStore(t.TempDir(), 2, 1)
    43  	account, err := ks.NewAccount(passwd)
    44  	require.NoError(err)
    45  	accountAddr, err := address.FromBytes(account.Address.Bytes())
    46  	require.NoError(err)
    47  	require.NotNil(accountAddr)
    48  
    49  	newcmd := func(
    50  		contractAddr string,
    51  		contractData string,
    52  		owner string,
    53  		balance string,
    54  	) *cobra.Command {
    55  		cli := mock_ioctlclient.NewMockClient(ctrl)
    56  		api := mock_iotexapi.NewMockAPIServiceClient(ctrl)
    57  
    58  		cli.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).AnyTimes()
    59  		cli.EXPECT().APIServiceClient().Return(api, nil).AnyTimes()
    60  
    61  		cli.EXPECT().AddressWithDefaultIfNotExist(gomock.Any()).Return(owner, nil).AnyTimes()
    62  		cli.EXPECT().NewKeyStore().Return(ks).AnyTimes()
    63  		cli.EXPECT().IsCryptoSm2().Return(false).AnyTimes()
    64  		cli.EXPECT().ReadSecret().Return(passwd, nil).AnyTimes()
    65  		cli.EXPECT().Address(gomock.Any()).Return(owner, nil).AnyTimes()
    66  		cli.EXPECT().Alias(gomock.Any()).Return("", nil).AnyTimes()
    67  		cli.EXPECT().AskToConfirm(gomock.Any()).Return(true, nil).AnyTimes()
    68  
    69  		api.EXPECT().ReadContract(gomock.Any(), gomock.Any(), gomock.Any()).
    70  			Return(&iotexapi.ReadContractResponse{Data: contractData}, nil).AnyTimes()
    71  		api.EXPECT().GetAccount(gomock.Any(), gomock.Any(), gomock.Any()).
    72  			Return(&iotexapi.GetAccountResponse{
    73  				AccountMeta: &iotextypes.AccountMeta{
    74  					PendingNonce: 100,
    75  					Balance:      balance,
    76  				},
    77  			}, nil).AnyTimes()
    78  		api.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).
    79  			Return(&iotexapi.GetChainMetaResponse{}, nil).AnyTimes()
    80  		api.EXPECT().SendAction(gomock.Any(), gomock.Any()).
    81  			Return(&iotexapi.SendActionResponse{}, nil).AnyTimes()
    82  
    83  		cli.EXPECT().Config().Return(config.Config{
    84  			Explorer: "iotexscan",
    85  			Endpoint: "testnet1",
    86  		}).AnyTimes()
    87  
    88  		cmd := NewXrc20TransferFromCmd(cli)
    89  		xrc20ContractAddr := ""
    90  		cmd.PersistentFlags().StringVarP(&xrc20ContractAddr,
    91  			"contract-address",
    92  			"c",
    93  			contractAddr,
    94  			"set contract address",
    95  		)
    96  		return cmd
    97  	}
    98  
    99  	tests := []struct {
   100  		name        string
   101  		args        []string
   102  		newcmd      *cobra.Command
   103  		expectedErr string
   104  	}{
   105  		{
   106  			"WrongArgCount",
   107  			nil,
   108  			newcmd("", "", "", ""),
   109  			"accepts 3 arg(s), received 0",
   110  		}, {
   111  			"WrongOwnerAlias",
   112  			[]string{wrongAlias, "", ""},
   113  			newcmd(dftContract, dftContractData, wrongAlias, dftBalance),
   114  			fmt.Sprintf("failed to get owner address: address length = %d, expecting 41: invalid address", len(wrongAlias)),
   115  		}, {
   116  			"WrongOwnerAddress",
   117  			[]string{wrongAddr, "", ""},
   118  			newcmd(dftContract, dftContractData, wrongAddr, dftBalance),
   119  			"failed to get owner address: invalid index of 1: invalid address",
   120  		}, {
   121  			"WrongContractAddress",
   122  			[]string{dftOwner, dftRecipient, dftAmount},
   123  			newcmd(wrongAddr, dftContractData, dftOwner, dftBalance),
   124  			fmt.Sprintf("failed to get privateKey: invalid address #%s", dftOwner),
   125  		}, {
   126  			"WrongAmount",
   127  			[]string{dftOwner, dftRecipient, wrongAmount},
   128  			newcmd(dftContract, dftContractData, dftOwner, dftBalance),
   129  			"failed to parse amount: failed to convert string into big int",
   130  		}, {
   131  			"WrongContractDataRsp",
   132  			[]string{dftOwner, dftRecipient, dftAmount},
   133  			newcmd(dftContract, wrongContractData, dftOwner, dftBalance),
   134  			fmt.Sprintf("failed to parse amount: failed to convert string into int64: strconv.ParseInt: parsing \"%s\": invalid syntax", wrongContractData),
   135  		}, {
   136  			"BalanceNotEnough",
   137  			[]string{dftOwner, dftRecipient, dftAmount},
   138  			newcmd(dftContract, dftContractData, accountAddr.String(), "0"),
   139  			"failed to pass balance check: balance is not enough",
   140  		}, {
   141  			"ShouldPass",
   142  			[]string{dftOwner, dftRecipient, dftAmount},
   143  			newcmd(dftContract, dftContractData, accountAddr.String(), dftBalance),
   144  			"",
   145  		}}
   146  
   147  	for _, test := range tests {
   148  		t.Run(test.name, func(t *testing.T) {
   149  			cmd := test.newcmd
   150  			result, err := util.ExecuteCmd(cmd, test.args...)
   151  			if test.expectedErr == "" {
   152  				require.NoError(err)
   153  				require.Contains(result, "Action has been sent to blockchain.\nWait for several seconds and query this action by hash:")
   154  			} else {
   155  				require.Equal(test.expectedErr, err.Error())
   156  			}
   157  		})
   158  	}
   159  }