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

     1  package testutil
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	ostcli "github.com/Finschia/ostracon/libs/cli"
     9  	"github.com/gogo/protobuf/proto"
    10  	"github.com/stretchr/testify/suite"
    11  
    12  	"github.com/Finschia/finschia-sdk/client/flags"
    13  	"github.com/Finschia/finschia-sdk/testutil"
    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  	"github.com/Finschia/finschia-sdk/x/distribution/client/cli"
    18  	minttypes "github.com/Finschia/finschia-sdk/x/mint/types"
    19  )
    20  
    21  type IntegrationTestSuite struct {
    22  	suite.Suite
    23  
    24  	cfg     network.Config
    25  	network *network.Network
    26  }
    27  
    28  func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
    29  	return &IntegrationTestSuite{cfg: cfg}
    30  }
    31  
    32  // SetupTest creates a new network for _each_ integration test. We create a new
    33  // network for each test because there are some state modifications that are
    34  // needed to be made in order to make useful queries. However, we don't want
    35  // these state changes to be present in other tests.
    36  func (s *IntegrationTestSuite) SetupTest() {
    37  	s.T().Log("setting up integration test suite")
    38  
    39  	genesisState := s.cfg.GenesisState
    40  	var mintData minttypes.GenesisState
    41  	s.Require().NoError(s.cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData))
    42  
    43  	inflation := sdk.MustNewDecFromStr("1.0")
    44  	mintData.Minter.Inflation = inflation
    45  	mintData.Params.InflationMin = inflation
    46  	mintData.Params.InflationMax = inflation
    47  
    48  	mintDataBz, err := s.cfg.Codec.MarshalJSON(&mintData)
    49  	s.Require().NoError(err)
    50  	genesisState[minttypes.ModuleName] = mintDataBz
    51  	s.cfg.GenesisState = genesisState
    52  
    53  	s.network = network.New(s.T(), s.cfg)
    54  
    55  	_, err = s.network.WaitForHeight(1)
    56  	s.Require().NoError(err)
    57  }
    58  
    59  // TearDownTest cleans up the curret test network after _each_ test.
    60  func (s *IntegrationTestSuite) TearDownTest() {
    61  	s.T().Log("tearing down integration test suite")
    62  	s.network.Cleanup()
    63  }
    64  
    65  func (s *IntegrationTestSuite) TestGetCmdQueryParams() {
    66  	val := s.network.Validators[0]
    67  
    68  	testCases := []struct {
    69  		name           string
    70  		args           []string
    71  		expectedOutput string
    72  	}{
    73  		{
    74  			"json output",
    75  			[]string{fmt.Sprintf("--%s=json", ostcli.OutputFlag)},
    76  			`{"community_tax":"0.020000000000000000","base_proposer_reward":"0.010000000000000000","bonus_proposer_reward":"0.040000000000000000","withdraw_addr_enabled":true}`,
    77  		},
    78  		{
    79  			"text output",
    80  			[]string{fmt.Sprintf("--%s=text", ostcli.OutputFlag)},
    81  			`base_proposer_reward: "0.010000000000000000"
    82  bonus_proposer_reward: "0.040000000000000000"
    83  community_tax: "0.020000000000000000"
    84  withdraw_addr_enabled: true`,
    85  		},
    86  	}
    87  
    88  	for _, tc := range testCases {
    89  		s.Run(tc.name, func() {
    90  			cmd := cli.GetCmdQueryParams()
    91  			clientCtx := val.ClientCtx
    92  
    93  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
    94  			s.Require().NoError(err)
    95  			s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
    96  		})
    97  	}
    98  }
    99  
   100  func (s *IntegrationTestSuite) TestGetCmdQueryValidatorOutstandingRewards() {
   101  	val := s.network.Validators[0]
   102  
   103  	_, err := s.network.WaitForHeight(4)
   104  	s.Require().NoError(err)
   105  
   106  	testCases := []struct {
   107  		name           string
   108  		args           []string
   109  		expectErr      bool
   110  		expectedOutput string
   111  	}{
   112  		{
   113  			"invalid validator address",
   114  			[]string{
   115  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   116  				"foo",
   117  			},
   118  			true,
   119  			"",
   120  		},
   121  		{
   122  			"json output",
   123  			[]string{
   124  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   125  				sdk.ValAddress(val.Address).String(),
   126  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   127  			},
   128  			false,
   129  			`{"rewards":[{"denom":"stake","amount":"1164.240000000000000000"}]}`,
   130  		},
   131  		{
   132  			"text output",
   133  			[]string{
   134  				fmt.Sprintf("--%s=text", ostcli.OutputFlag),
   135  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   136  				sdk.ValAddress(val.Address).String(),
   137  			},
   138  			false,
   139  			`rewards:
   140  - amount: "1164.240000000000000000"
   141    denom: stake`,
   142  		},
   143  	}
   144  
   145  	for _, tc := range testCases {
   146  		s.Run(tc.name, func() {
   147  			cmd := cli.GetCmdQueryValidatorOutstandingRewards()
   148  			clientCtx := val.ClientCtx
   149  
   150  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   151  			if tc.expectErr {
   152  				s.Require().Error(err)
   153  			} else {
   154  				s.Require().NoError(err)
   155  				s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
   156  			}
   157  		})
   158  	}
   159  }
   160  
   161  func (s *IntegrationTestSuite) TestGetCmdQueryValidatorCommission() {
   162  	val := s.network.Validators[0]
   163  
   164  	_, err := s.network.WaitForHeight(4)
   165  	s.Require().NoError(err)
   166  
   167  	testCases := []struct {
   168  		name           string
   169  		args           []string
   170  		expectErr      bool
   171  		expectedOutput string
   172  	}{
   173  		{
   174  			"invalid validator address",
   175  			[]string{
   176  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   177  				"foo",
   178  			},
   179  			true,
   180  			"",
   181  		},
   182  		{
   183  			"json output",
   184  			[]string{
   185  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   186  				sdk.ValAddress(val.Address).String(),
   187  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   188  			},
   189  			false,
   190  			`{"commission":[{"denom":"stake","amount":"464.520000000000000000"}]}`,
   191  		},
   192  		{
   193  			"text output",
   194  			[]string{
   195  				fmt.Sprintf("--%s=text", ostcli.OutputFlag),
   196  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   197  				sdk.ValAddress(val.Address).String(),
   198  			},
   199  			false,
   200  			`commission:
   201  - amount: "464.520000000000000000"
   202    denom: stake`,
   203  		},
   204  	}
   205  
   206  	for _, tc := range testCases {
   207  		s.Run(tc.name, func() {
   208  			cmd := cli.GetCmdQueryValidatorCommission()
   209  			clientCtx := val.ClientCtx
   210  
   211  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   212  			if tc.expectErr {
   213  				s.Require().Error(err)
   214  			} else {
   215  				s.Require().NoError(err)
   216  				s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
   217  			}
   218  		})
   219  	}
   220  }
   221  
   222  func (s *IntegrationTestSuite) TestGetCmdQueryValidatorSlashes() {
   223  	val := s.network.Validators[0]
   224  
   225  	_, err := s.network.WaitForHeight(4)
   226  	s.Require().NoError(err)
   227  
   228  	testCases := []struct {
   229  		name           string
   230  		args           []string
   231  		expectErr      bool
   232  		expectedOutput string
   233  	}{
   234  		{
   235  			"invalid validator address",
   236  			[]string{
   237  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   238  				"foo", "1", "3",
   239  			},
   240  			true,
   241  			"",
   242  		},
   243  		{
   244  			"invalid start height",
   245  			[]string{
   246  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   247  				sdk.ValAddress(val.Address).String(), "-1", "3",
   248  			},
   249  			true,
   250  			"",
   251  		},
   252  		{
   253  			"invalid end height",
   254  			[]string{
   255  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   256  				sdk.ValAddress(val.Address).String(), "1", "-3",
   257  			},
   258  			true,
   259  			"",
   260  		},
   261  		{
   262  			"json output",
   263  			[]string{
   264  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   265  				sdk.ValAddress(val.Address).String(), "1", "3",
   266  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   267  			},
   268  			false,
   269  			"{\"slashes\":[],\"pagination\":{\"next_key\":null,\"total\":\"0\"}}",
   270  		},
   271  		{
   272  			"text output",
   273  			[]string{
   274  				fmt.Sprintf("--%s=text", ostcli.OutputFlag),
   275  				fmt.Sprintf("--%s=3", flags.FlagHeight),
   276  				sdk.ValAddress(val.Address).String(), "1", "3",
   277  			},
   278  			false,
   279  			"pagination:\n  next_key: null\n  total: \"0\"\nslashes: []",
   280  		},
   281  	}
   282  
   283  	for _, tc := range testCases {
   284  		s.Run(tc.name, func() {
   285  			cmd := cli.GetCmdQueryValidatorSlashes()
   286  			clientCtx := val.ClientCtx
   287  
   288  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   289  			if tc.expectErr {
   290  				s.Require().Error(err)
   291  			} else {
   292  				s.Require().NoError(err)
   293  				s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
   294  			}
   295  		})
   296  	}
   297  }
   298  
   299  func (s *IntegrationTestSuite) TestGetCmdQueryDelegatorRewards() {
   300  	val := s.network.Validators[0]
   301  	addr := val.Address
   302  	valAddr := sdk.ValAddress(addr)
   303  
   304  	_, err := s.network.WaitForHeightWithTimeout(11, time.Minute)
   305  	s.Require().NoError(err)
   306  
   307  	testCases := []struct {
   308  		name           string
   309  		args           []string
   310  		expectErr      bool
   311  		expectedOutput string
   312  	}{
   313  		{
   314  			"invalid delegator address",
   315  			[]string{
   316  				fmt.Sprintf("--%s=5", flags.FlagHeight),
   317  				"foo", valAddr.String(),
   318  			},
   319  			true,
   320  			"",
   321  		},
   322  		{
   323  			"invalid validator address",
   324  			[]string{
   325  				fmt.Sprintf("--%s=5", flags.FlagHeight),
   326  				addr.String(), "foo",
   327  			},
   328  			true,
   329  			"",
   330  		},
   331  		{
   332  			"json output",
   333  			[]string{
   334  				fmt.Sprintf("--%s=5", flags.FlagHeight),
   335  				addr.String(),
   336  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   337  			},
   338  			false,
   339  			fmt.Sprintf(`{"rewards":[{"validator_address":"%s","reward":[{"denom":"stake","amount":"387.100000000000000000"}]}],"total":[{"denom":"stake","amount":"387.100000000000000000"}]}`, valAddr.String()),
   340  		},
   341  		{
   342  			"json output (specific validator)",
   343  			[]string{
   344  				fmt.Sprintf("--%s=5", flags.FlagHeight),
   345  				addr.String(), valAddr.String(),
   346  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   347  			},
   348  			false,
   349  			`{"rewards":[{"denom":"stake","amount":"387.100000000000000000"}]}`,
   350  		},
   351  		{
   352  			"text output",
   353  			[]string{
   354  				fmt.Sprintf("--%s=text", ostcli.OutputFlag),
   355  				fmt.Sprintf("--%s=5", flags.FlagHeight),
   356  				addr.String(),
   357  			},
   358  			false,
   359  			fmt.Sprintf(`rewards:
   360  - reward:
   361    - amount: "387.100000000000000000"
   362      denom: stake
   363    validator_address: %s
   364  total:
   365  - amount: "387.100000000000000000"
   366    denom: stake`, valAddr.String()),
   367  		},
   368  		{
   369  			"text output (specific validator)",
   370  			[]string{
   371  				fmt.Sprintf("--%s=text", ostcli.OutputFlag),
   372  				fmt.Sprintf("--%s=5", flags.FlagHeight),
   373  				addr.String(), valAddr.String(),
   374  			},
   375  			false,
   376  			`rewards:
   377  - amount: "387.100000000000000000"
   378    denom: stake`,
   379  		},
   380  	}
   381  
   382  	for _, tc := range testCases {
   383  		s.Run(tc.name, func() {
   384  			cmd := cli.GetCmdQueryDelegatorRewards()
   385  			clientCtx := val.ClientCtx
   386  
   387  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   388  			if tc.expectErr {
   389  				s.Require().Error(err)
   390  			} else {
   391  				s.Require().NoError(err)
   392  				s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
   393  			}
   394  		})
   395  	}
   396  }
   397  
   398  func (s *IntegrationTestSuite) TestGetCmdQueryCommunityPool() {
   399  	val := s.network.Validators[0]
   400  
   401  	_, err := s.network.WaitForHeight(4)
   402  	s.Require().NoError(err)
   403  
   404  	testCases := []struct {
   405  		name           string
   406  		args           []string
   407  		expectedOutput string
   408  	}{
   409  		{
   410  			"json output",
   411  			[]string{fmt.Sprintf("--%s=3", flags.FlagHeight), fmt.Sprintf("--%s=json", ostcli.OutputFlag)},
   412  			`{"pool":[{"denom":"stake","amount":"4.740000000000000000"}]}`,
   413  		},
   414  		{
   415  			"text output",
   416  			[]string{fmt.Sprintf("--%s=text", ostcli.OutputFlag), fmt.Sprintf("--%s=3", flags.FlagHeight)},
   417  			`pool:
   418  - amount: "4.740000000000000000"
   419    denom: stake`,
   420  		},
   421  	}
   422  
   423  	for _, tc := range testCases {
   424  		s.Run(tc.name, func() {
   425  			cmd := cli.GetCmdQueryCommunityPool()
   426  			clientCtx := val.ClientCtx
   427  
   428  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   429  			s.Require().NoError(err)
   430  			s.Require().Equal(tc.expectedOutput, strings.TrimSpace(out.String()))
   431  		})
   432  	}
   433  }
   434  
   435  func (s *IntegrationTestSuite) TestNewWithdrawRewardsCmd() {
   436  	val := s.network.Validators[0]
   437  
   438  	testCases := []struct {
   439  		name         string
   440  		valAddr      fmt.Stringer
   441  		args         []string
   442  		expectErr    bool
   443  		expectedCode uint32
   444  		respType     proto.Message
   445  	}{
   446  		{
   447  			"invalid validator address",
   448  			val.Address,
   449  			[]string{
   450  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   451  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   452  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   453  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   454  			},
   455  			true, 0, nil,
   456  		},
   457  		{
   458  			"valid transaction",
   459  			sdk.ValAddress(val.Address),
   460  			[]string{
   461  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   462  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   463  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   464  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   465  			},
   466  			false, 0, &sdk.TxResponse{},
   467  		},
   468  		{
   469  			"valid transaction (with commission)",
   470  			sdk.ValAddress(val.Address),
   471  			[]string{
   472  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   473  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   474  				fmt.Sprintf("--%s=true", cli.FlagCommission),
   475  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   476  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   477  			},
   478  			false, 0, &sdk.TxResponse{},
   479  		},
   480  	}
   481  
   482  	for _, tc := range testCases {
   483  		s.Run(tc.name, func() {
   484  			clientCtx := val.ClientCtx
   485  
   486  			bz, err := MsgWithdrawDelegatorRewardExec(clientCtx, tc.valAddr, tc.args...)
   487  			if tc.expectErr {
   488  				s.Require().Error(err)
   489  			} else {
   490  				s.Require().NoError(err)
   491  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(bz, tc.respType), string(bz))
   492  
   493  				txResp := tc.respType.(*sdk.TxResponse)
   494  				s.Require().Equal(tc.expectedCode, txResp.Code)
   495  			}
   496  		})
   497  	}
   498  }
   499  
   500  func (s *IntegrationTestSuite) TestNewWithdrawAllRewardsCmd() {
   501  	val := s.network.Validators[0]
   502  
   503  	testCases := []struct {
   504  		name         string
   505  		args         []string
   506  		expectErr    bool
   507  		expectedCode uint32
   508  		respType     proto.Message
   509  	}{
   510  		{
   511  			"valid transaction (offline)",
   512  			[]string{
   513  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   514  				fmt.Sprintf("--%s=true", flags.FlagOffline),
   515  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   516  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   517  			},
   518  			true, 0, nil,
   519  		},
   520  		{
   521  			"valid transaction",
   522  			[]string{
   523  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   524  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   525  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   526  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   527  			},
   528  			false, 0, &sdk.TxResponse{},
   529  		},
   530  	}
   531  
   532  	for _, tc := range testCases {
   533  		s.Run(tc.name, func() {
   534  			cmd := cli.NewWithdrawAllRewardsCmd()
   535  			clientCtx := val.ClientCtx
   536  
   537  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   538  			if tc.expectErr {
   539  				s.Require().Error(err)
   540  			} else {
   541  				s.Require().NoError(err)
   542  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   543  
   544  				txResp := tc.respType.(*sdk.TxResponse)
   545  				s.Require().Equal(tc.expectedCode, txResp.Code)
   546  			}
   547  		})
   548  	}
   549  }
   550  
   551  func (s *IntegrationTestSuite) TestNewSetWithdrawAddrCmd() {
   552  	val := s.network.Validators[0]
   553  
   554  	testCases := []struct {
   555  		name         string
   556  		args         []string
   557  		expectErr    bool
   558  		expectedCode uint32
   559  		respType     proto.Message
   560  	}{
   561  		{
   562  			"invalid withdraw address",
   563  			[]string{
   564  				"foo",
   565  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   566  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   567  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   568  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   569  			},
   570  			true, 0, nil,
   571  		},
   572  		{
   573  			"valid transaction",
   574  			[]string{
   575  				val.Address.String(),
   576  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   577  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   578  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   579  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   580  			},
   581  			false, 0, &sdk.TxResponse{},
   582  		},
   583  	}
   584  
   585  	for _, tc := range testCases {
   586  		s.Run(tc.name, func() {
   587  			cmd := cli.NewSetWithdrawAddrCmd()
   588  			clientCtx := val.ClientCtx
   589  
   590  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   591  			if tc.expectErr {
   592  				s.Require().Error(err)
   593  			} else {
   594  				s.Require().NoError(err)
   595  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   596  
   597  				txResp := tc.respType.(*sdk.TxResponse)
   598  				s.Require().Equal(tc.expectedCode, txResp.Code)
   599  			}
   600  		})
   601  	}
   602  }
   603  
   604  func (s *IntegrationTestSuite) TestNewFundCommunityPoolCmd() {
   605  	val := s.network.Validators[0]
   606  
   607  	testCases := []struct {
   608  		name         string
   609  		args         []string
   610  		expectErr    bool
   611  		expectedCode uint32
   612  		respType     proto.Message
   613  	}{
   614  		{
   615  			"invalid funding amount",
   616  			[]string{
   617  				"-43foocoin",
   618  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   619  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   620  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   621  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   622  			},
   623  			true, 0, nil,
   624  		},
   625  		{
   626  			"valid transaction",
   627  			[]string{
   628  				sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431))).String(),
   629  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   630  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   631  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   632  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   633  			},
   634  			false, 0, &sdk.TxResponse{},
   635  		},
   636  	}
   637  
   638  	for _, tc := range testCases {
   639  		s.Run(tc.name, func() {
   640  			cmd := cli.NewFundCommunityPoolCmd()
   641  			clientCtx := val.ClientCtx
   642  
   643  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   644  			if tc.expectErr {
   645  				s.Require().Error(err)
   646  			} else {
   647  				s.Require().NoError(err)
   648  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   649  
   650  				txResp := tc.respType.(*sdk.TxResponse)
   651  				s.Require().Equal(tc.expectedCode, txResp.Code)
   652  			}
   653  		})
   654  	}
   655  }
   656  
   657  func (s *IntegrationTestSuite) TestGetCmdSubmitProposal() {
   658  	val := s.network.Validators[0]
   659  	invalidProp := `{
   660    "title": "",
   661    "description": "Pay me some Atoms!",
   662    "recipient": "foo",
   663    "amount": "-343foocoin",
   664    "deposit": -324foocoin
   665  }`
   666  
   667  	invalidPropFile := testutil.WriteToNewTempFile(s.T(), invalidProp)
   668  
   669  	validProp := fmt.Sprintf(`{
   670    "title": "Community Pool Spend",
   671    "description": "Pay me some Atoms!",
   672    "recipient": "%s",
   673    "amount": "%s",
   674    "deposit": "%s"
   675  }`, val.Address.String(), sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)), sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)))
   676  
   677  	validPropFile := testutil.WriteToNewTempFile(s.T(), validProp)
   678  	testCases := []struct {
   679  		name         string
   680  		args         []string
   681  		expectErr    bool
   682  		expectedCode uint32
   683  		respType     proto.Message
   684  	}{
   685  		{
   686  			"invalid proposal",
   687  			[]string{
   688  				invalidPropFile.Name(),
   689  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   690  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   691  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
   692  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   693  			},
   694  			true, 0, nil,
   695  		},
   696  		{
   697  			"valid transaction",
   698  			[]string{
   699  				validPropFile.Name(),
   700  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   701  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   702  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), // sync mode as there are no funds yet
   703  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   704  			},
   705  			false, 0, &sdk.TxResponse{},
   706  		},
   707  	}
   708  
   709  	for _, tc := range testCases {
   710  		s.Run(tc.name, func() {
   711  			cmd := cli.GetCmdSubmitProposal()
   712  			clientCtx := val.ClientCtx
   713  			flags.AddTxFlagsToCmd(cmd)
   714  
   715  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   716  			if tc.expectErr {
   717  				s.Require().Error(err)
   718  			} else {
   719  				s.Require().NoError(err)
   720  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   721  
   722  				txResp := tc.respType.(*sdk.TxResponse)
   723  				s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
   724  			}
   725  		})
   726  	}
   727  }