github.com/cosmos/cosmos-sdk@v0.50.10/x/distribution/client/cli/tx_test.go (about)

     1  package cli_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"testing"
     8  
     9  	abci "github.com/cometbft/cometbft/abci/types"
    10  	rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
    11  	"github.com/cosmos/gogoproto/proto"
    12  	"github.com/stretchr/testify/suite"
    13  
    14  	sdkmath "cosmossdk.io/math"
    15  
    16  	"github.com/cosmos/cosmos-sdk/client"
    17  	"github.com/cosmos/cosmos-sdk/client/flags"
    18  	"github.com/cosmos/cosmos-sdk/codec/address"
    19  	"github.com/cosmos/cosmos-sdk/crypto/keyring"
    20  	svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
    21  	"github.com/cosmos/cosmos-sdk/testutil"
    22  	clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
    23  	"github.com/cosmos/cosmos-sdk/testutil/network"
    24  	sdk "github.com/cosmos/cosmos-sdk/types"
    25  	testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
    26  	"github.com/cosmos/cosmos-sdk/x/bank"
    27  	"github.com/cosmos/cosmos-sdk/x/distribution/client/cli"
    28  	distrtestutil "github.com/cosmos/cosmos-sdk/x/distribution/testutil"
    29  	"github.com/cosmos/cosmos-sdk/x/gov"
    30  	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
    31  )
    32  
    33  type CLITestSuite struct {
    34  	suite.Suite
    35  
    36  	kr        keyring.Keyring
    37  	encCfg    testutilmod.TestEncodingConfig
    38  	baseCtx   client.Context
    39  	clientCtx client.Context
    40  }
    41  
    42  func TestCLITestSuite(t *testing.T) {
    43  	suite.Run(t, new(CLITestSuite))
    44  }
    45  
    46  func (s *CLITestSuite) SetupSuite() {
    47  	s.encCfg = testutilmod.MakeTestEncodingConfig(gov.AppModuleBasic{}, bank.AppModuleBasic{})
    48  	s.kr = keyring.NewInMemory(s.encCfg.Codec)
    49  	s.baseCtx = client.Context{}.
    50  		WithKeyring(s.kr).
    51  		WithTxConfig(s.encCfg.TxConfig).
    52  		WithCodec(s.encCfg.Codec).
    53  		WithClient(clitestutil.MockCometRPC{Client: rpcclientmock.Client{}}).
    54  		WithAccountRetriever(client.MockAccountRetriever{}).
    55  		WithOutput(io.Discard).
    56  		WithChainID("test-chain")
    57  
    58  	ctxGen := func() client.Context {
    59  		bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
    60  		c := clitestutil.NewMockCometRPC(abci.ResponseQuery{
    61  			Value: bz,
    62  		})
    63  		return s.baseCtx.WithClient(c)
    64  	}
    65  	s.clientCtx = ctxGen()
    66  
    67  	cfg, err := network.DefaultConfigWithAppConfig(distrtestutil.AppConfig)
    68  	s.Require().NoError(err)
    69  
    70  	genesisState := cfg.GenesisState
    71  	var mintData minttypes.GenesisState
    72  	s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData))
    73  
    74  	inflation := sdkmath.LegacyMustNewDecFromStr("1.0")
    75  	mintData.Minter.Inflation = inflation
    76  	mintData.Params.InflationMin = inflation
    77  	mintData.Params.InflationMax = inflation
    78  
    79  	mintDataBz, err := cfg.Codec.MarshalJSON(&mintData)
    80  	s.Require().NoError(err)
    81  	genesisState[minttypes.ModuleName] = mintDataBz
    82  	cfg.GenesisState = genesisState
    83  }
    84  
    85  func (s *CLITestSuite) TestTxWithdrawRewardsCmd() {
    86  	val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
    87  
    88  	testCases := []struct {
    89  		name         string
    90  		valAddr      fmt.Stringer
    91  		args         []string
    92  		expectErrMsg string
    93  	}{
    94  		{
    95  			"invalid validator address",
    96  			val[0].Address,
    97  			[]string{
    98  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
    99  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   100  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   101  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   102  			},
   103  			"hrp does not match bech32 prefix",
   104  		},
   105  		{
   106  			"valid transaction",
   107  			sdk.ValAddress(val[0].Address),
   108  			[]string{
   109  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   110  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   111  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   112  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   113  			},
   114  			"",
   115  		},
   116  		{
   117  			"valid transaction (with commission)",
   118  			sdk.ValAddress(val[0].Address),
   119  			[]string{
   120  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   121  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   122  				fmt.Sprintf("--%s=true", cli.FlagCommission),
   123  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   124  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   125  			},
   126  			"",
   127  		},
   128  	}
   129  
   130  	for _, tc := range testCases {
   131  		tc := tc
   132  
   133  		s.Run(tc.name, func() {
   134  			args := append([]string{tc.valAddr.String()}, tc.args...)
   135  
   136  			ctx := svrcmd.CreateExecuteContext(context.Background())
   137  			cmd := cli.NewWithdrawRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
   138  			cmd.SetContext(ctx)
   139  			cmd.SetArgs(args)
   140  			s.Require().NoError(client.SetCmdClientContextHandler(s.clientCtx, cmd))
   141  
   142  			out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
   143  			if tc.expectErrMsg != "" {
   144  				s.Require().Error(err)
   145  				s.Require().Contains(err.Error(), tc.expectErrMsg)
   146  			} else {
   147  				s.Require().NoError(err)
   148  				msg := &sdk.TxResponse{}
   149  				s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   150  			}
   151  		})
   152  	}
   153  }
   154  
   155  func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() {
   156  	val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
   157  
   158  	testCases := []struct {
   159  		name         string
   160  		args         []string
   161  		expectErrMsg string
   162  	}{
   163  		{
   164  			"invalid transaction (offline)",
   165  			[]string{
   166  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   167  				fmt.Sprintf("--%s=true", flags.FlagOffline),
   168  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   169  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   170  			},
   171  			"cannot generate tx in offline mode",
   172  		},
   173  		{
   174  			"valid transaction",
   175  			[]string{
   176  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   177  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   178  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   179  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   180  			},
   181  			"",
   182  		},
   183  	}
   184  
   185  	for _, tc := range testCases {
   186  		tc := tc
   187  
   188  		s.Run(tc.name, func() {
   189  			cmd := cli.NewWithdrawAllRewardsCmd(address.NewBech32Codec("cosmosvaloper"), address.NewBech32Codec("cosmos"))
   190  
   191  			out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
   192  			if tc.expectErrMsg != "" {
   193  				s.Require().Error(err)
   194  				s.Require().Contains(err.Error(), tc.expectErrMsg)
   195  			} else {
   196  				s.Require().NoError(err)
   197  				msg := &sdk.TxResponse{}
   198  				s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), msg), out.String())
   199  			}
   200  		})
   201  	}
   202  }
   203  
   204  func (s *CLITestSuite) TestTxSetWithdrawAddrCmd() {
   205  	val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
   206  
   207  	testCases := []struct {
   208  		name      string
   209  		args      []string
   210  		expectErr bool
   211  		respType  proto.Message
   212  	}{
   213  		{
   214  			"invalid withdraw address",
   215  			[]string{
   216  				"foo",
   217  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   218  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   219  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   220  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   221  			},
   222  			true, nil,
   223  		},
   224  		{
   225  			"valid transaction",
   226  			[]string{
   227  				val[0].Address.String(),
   228  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   229  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   230  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   231  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   232  			},
   233  			false, &sdk.TxResponse{},
   234  		},
   235  	}
   236  
   237  	for _, tc := range testCases {
   238  		tc := tc
   239  
   240  		s.Run(tc.name, func() {
   241  			cmd := cli.NewSetWithdrawAddrCmd(address.NewBech32Codec("cosmos"))
   242  
   243  			out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
   244  			if tc.expectErr {
   245  				s.Require().Error(err)
   246  			} else {
   247  				s.Require().NoError(err)
   248  				s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   249  			}
   250  		})
   251  	}
   252  }
   253  
   254  func (s *CLITestSuite) TestTxFundCommunityPoolCmd() {
   255  	val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
   256  
   257  	testCases := []struct {
   258  		name      string
   259  		args      []string
   260  		expectErr bool
   261  		respType  proto.Message
   262  	}{
   263  		{
   264  			"invalid funding amount",
   265  			[]string{
   266  				"-43foocoin",
   267  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   268  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   269  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   270  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   271  			},
   272  			true, nil,
   273  		},
   274  		{
   275  			"valid transaction",
   276  			[]string{
   277  				sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(5431))).String(),
   278  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
   279  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   280  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   281  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
   282  			},
   283  			false, &sdk.TxResponse{},
   284  		},
   285  	}
   286  
   287  	for _, tc := range testCases {
   288  		tc := tc
   289  
   290  		s.Run(tc.name, func() {
   291  			cmd := cli.NewFundCommunityPoolCmd(address.NewBech32Codec("cosmos"))
   292  
   293  			out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
   294  			if tc.expectErr {
   295  				s.Require().Error(err)
   296  			} else {
   297  				s.Require().NoError(err)
   298  				s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   299  			}
   300  		})
   301  	}
   302  }