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

     1  package testutil
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	ostcli "github.com/Finschia/ostracon/libs/cli"
     8  	"github.com/gogo/protobuf/proto"
     9  	"github.com/stretchr/testify/suite"
    10  
    11  	"github.com/Finschia/finschia-sdk/client/flags"
    12  	"github.com/Finschia/finschia-sdk/testutil"
    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  	"github.com/Finschia/finschia-sdk/x/gov/client/cli"
    17  	"github.com/Finschia/finschia-sdk/x/gov/types"
    18  )
    19  
    20  type IntegrationTestSuite struct {
    21  	suite.Suite
    22  
    23  	cfg     network.Config
    24  	network *network.Network
    25  }
    26  
    27  func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
    28  	return &IntegrationTestSuite{cfg: cfg}
    29  }
    30  
    31  func (s *IntegrationTestSuite) SetupSuite() {
    32  	s.T().Log("setting up integration test suite")
    33  
    34  	s.network = network.New(s.T(), s.cfg)
    35  
    36  	_, err := s.network.WaitForHeight(1)
    37  	s.Require().NoError(err)
    38  
    39  	val := s.network.Validators[0]
    40  
    41  	// create a proposal with deposit
    42  	_, err = MsgSubmitProposal(val.ClientCtx, val.Address.String(),
    43  		"Text Proposal 1", "Where is the title!?", types.ProposalTypeText,
    44  		fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens).String()))
    45  	s.Require().NoError(err)
    46  	_, err = s.network.WaitForHeight(1)
    47  	s.Require().NoError(err)
    48  
    49  	// vote for proposal
    50  	_, err = MsgVote(val.ClientCtx, val.Address.String(), "1", "yes")
    51  	s.Require().NoError(err)
    52  
    53  	// create a proposal without deposit
    54  	_, err = MsgSubmitProposal(val.ClientCtx, val.Address.String(),
    55  		"Text Proposal 2", "Where is the title!?", types.ProposalTypeText)
    56  	s.Require().NoError(err)
    57  	_, err = s.network.WaitForHeight(1)
    58  	s.Require().NoError(err)
    59  
    60  	// create a proposal3 with deposit
    61  	_, err = MsgSubmitProposal(val.ClientCtx, val.Address.String(),
    62  		"Text Proposal 3", "Where is the title!?", types.ProposalTypeText,
    63  		fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens).String()))
    64  	s.Require().NoError(err)
    65  	_, err = s.network.WaitForHeight(1)
    66  	s.Require().NoError(err)
    67  
    68  	// vote for proposal3 as val
    69  	_, err = MsgVote(val.ClientCtx, val.Address.String(), "3", "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05")
    70  	s.Require().NoError(err)
    71  }
    72  
    73  func (s *IntegrationTestSuite) TearDownSuite() {
    74  	s.T().Log("tearing down integration test suite")
    75  	s.network.Cleanup()
    76  }
    77  
    78  func (s *IntegrationTestSuite) TestCmdParams() {
    79  	val := s.network.Validators[0]
    80  
    81  	testCases := []struct {
    82  		name           string
    83  		args           []string
    84  		expectedOutput string
    85  	}{
    86  		{
    87  			"json output",
    88  			[]string{fmt.Sprintf("--%s=json", ostcli.OutputFlag)},
    89  			`{"voting_params":{"voting_period":"172800000000000"},"tally_params":{"quorum":"0.334000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"},"deposit_params":{"min_deposit":[{"denom":"stake","amount":"10000000"}],"max_deposit_period":"172800000000000"}}`,
    90  		},
    91  		{
    92  			"text output",
    93  			[]string{},
    94  			`
    95  deposit_params:
    96    max_deposit_period: "172800000000000"
    97    min_deposit:
    98    - amount: "10000000"
    99      denom: stake
   100  tally_params:
   101    quorum: "0.334000000000000000"
   102    threshold: "0.500000000000000000"
   103    veto_threshold: "0.334000000000000000"
   104  voting_params:
   105    voting_period: "172800000000000"
   106  	`,
   107  		},
   108  	}
   109  
   110  	for _, tc := range testCases {
   111  		s.Run(tc.name, func() {
   112  			cmd := cli.GetCmdQueryParams()
   113  			clientCtx := val.ClientCtx
   114  
   115  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   116  			s.Require().NoError(err)
   117  			s.Require().Equal(strings.TrimSpace(tc.expectedOutput), strings.TrimSpace(out.String()))
   118  		})
   119  	}
   120  }
   121  
   122  func (s *IntegrationTestSuite) TestCmdParam() {
   123  	val := s.network.Validators[0]
   124  
   125  	testCases := []struct {
   126  		name           string
   127  		args           []string
   128  		expectedOutput string
   129  	}{
   130  		{
   131  			"voting params",
   132  			[]string{
   133  				"voting",
   134  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   135  			},
   136  			`{"voting_period":"172800000000000"}`,
   137  		},
   138  		{
   139  			"tally params",
   140  			[]string{
   141  				"tallying",
   142  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   143  			},
   144  			`{"quorum":"0.334000000000000000","threshold":"0.500000000000000000","veto_threshold":"0.334000000000000000"}`,
   145  		},
   146  		{
   147  			"deposit params",
   148  			[]string{
   149  				"deposit",
   150  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   151  			},
   152  			`{"min_deposit":[{"denom":"stake","amount":"10000000"}],"max_deposit_period":"172800000000000"}`,
   153  		},
   154  	}
   155  
   156  	for _, tc := range testCases {
   157  		s.Run(tc.name, func() {
   158  			cmd := cli.GetCmdQueryParam()
   159  			clientCtx := val.ClientCtx
   160  
   161  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   162  			s.Require().NoError(err)
   163  			s.Require().Equal(strings.TrimSpace(tc.expectedOutput), strings.TrimSpace(out.String()))
   164  		})
   165  	}
   166  }
   167  
   168  func (s *IntegrationTestSuite) TestCmdProposer() {
   169  	val := s.network.Validators[0]
   170  
   171  	testCases := []struct {
   172  		name           string
   173  		args           []string
   174  		expectErr      bool
   175  		expectedOutput string
   176  	}{
   177  		{
   178  			"without proposal id",
   179  			[]string{
   180  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   181  			},
   182  			true,
   183  			``,
   184  		},
   185  		{
   186  			"json output",
   187  			[]string{
   188  				"1",
   189  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   190  			},
   191  			false,
   192  			fmt.Sprintf("{\"proposal_id\":\"%s\",\"proposer\":\"%s\"}", "1", val.Address.String()),
   193  		},
   194  	}
   195  
   196  	for _, tc := range testCases {
   197  		s.Run(tc.name, func() {
   198  			cmd := cli.GetCmdQueryProposer()
   199  			clientCtx := val.ClientCtx
   200  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   201  
   202  			if tc.expectErr {
   203  				s.Require().Error(err)
   204  			} else {
   205  				s.Require().NoError(err)
   206  				s.Require().Equal(strings.TrimSpace(tc.expectedOutput), strings.TrimSpace(out.String()))
   207  			}
   208  		})
   209  	}
   210  }
   211  
   212  func (s *IntegrationTestSuite) TestCmdTally() {
   213  	val := s.network.Validators[0]
   214  
   215  	testCases := []struct {
   216  		name           string
   217  		args           []string
   218  		expectErr      bool
   219  		expectedOutput types.TallyResult
   220  	}{
   221  		{
   222  			"without proposal id",
   223  			[]string{
   224  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   225  			},
   226  			true,
   227  			types.TallyResult{},
   228  		},
   229  		{
   230  			"json output",
   231  			[]string{
   232  				"2",
   233  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   234  			},
   235  			false,
   236  			types.NewTallyResult(sdk.NewInt(0), sdk.NewInt(0), sdk.NewInt(0), sdk.NewInt(0)),
   237  		},
   238  		{
   239  			"json output",
   240  			[]string{
   241  				"1",
   242  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   243  			},
   244  			false,
   245  			types.NewTallyResult(s.cfg.BondedTokens, sdk.NewInt(0), sdk.NewInt(0), sdk.NewInt(0)),
   246  		},
   247  	}
   248  
   249  	for _, tc := range testCases {
   250  		s.Run(tc.name, func() {
   251  			cmd := cli.GetCmdQueryTally()
   252  			clientCtx := val.ClientCtx
   253  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   254  
   255  			if tc.expectErr {
   256  				s.Require().Error(err)
   257  			} else {
   258  				var tally types.TallyResult
   259  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &tally), out.String())
   260  				s.Require().Equal(tally, tc.expectedOutput)
   261  			}
   262  		})
   263  	}
   264  }
   265  
   266  func (s *IntegrationTestSuite) TestNewCmdSubmitProposal() {
   267  	val := s.network.Validators[0]
   268  	invalidProp := `{
   269  	  "title": "",
   270  		"description": "Where is the title!?",
   271  		"type": "Text",
   272  	  "deposit": "-324foocoin"
   273  	}`
   274  	invalidPropFile := testutil.WriteToNewTempFile(s.T(), invalidProp)
   275  	validProp := fmt.Sprintf(`{
   276  	  "title": "Text Proposal",
   277  		"description": "Hello, World!",
   278  		"type": "Text",
   279  	  "deposit": "%s"
   280  	}`, sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)))
   281  	validPropFile := testutil.WriteToNewTempFile(s.T(), validProp)
   282  	testCases := []struct {
   283  		name         string
   284  		args         []string
   285  		expectErr    bool
   286  		expectedCode uint32
   287  		respType     proto.Message
   288  	}{
   289  		{
   290  			"invalid proposal (file)",
   291  			[]string{
   292  				fmt.Sprintf("--%s=%s", cli.FlagProposal, invalidPropFile.Name()),
   293  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   294  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   295  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   296  			},
   297  			true, 0, nil,
   298  		},
   299  		{
   300  			"invalid proposal",
   301  			[]string{
   302  				fmt.Sprintf("--%s='Where is the title!?'", cli.FlagDescription),
   303  				fmt.Sprintf("--%s=%s", cli.FlagProposalType, types.ProposalTypeText),
   304  				fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)).String()),
   305  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   306  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   307  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   308  			},
   309  			true, 0, nil,
   310  		},
   311  		{
   312  			"valid transaction (file)",
   313  			[]string{
   314  				fmt.Sprintf("--%s=%s", cli.FlagProposal, validPropFile.Name()),
   315  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   316  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   317  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   318  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   319  			},
   320  			false, 0, &sdk.TxResponse{},
   321  		},
   322  		{
   323  			"valid transaction",
   324  			[]string{
   325  				fmt.Sprintf("--%s='Text Proposal'", cli.FlagTitle),
   326  				fmt.Sprintf("--%s='Where is the title!?'", cli.FlagDescription),
   327  				fmt.Sprintf("--%s=%s", cli.FlagProposalType, types.ProposalTypeText),
   328  				fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(5431)).String()),
   329  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   330  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   331  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   332  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   333  			},
   334  			false, 0, &sdk.TxResponse{},
   335  		},
   336  	}
   337  
   338  	for _, tc := range testCases {
   339  		s.Run(tc.name, func() {
   340  			cmd := cli.NewCmdSubmitProposal()
   341  			clientCtx := val.ClientCtx
   342  
   343  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   344  			if tc.expectErr {
   345  				s.Require().Error(err)
   346  			} else {
   347  				s.Require().NoError(err)
   348  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
   349  				txResp := tc.respType.(*sdk.TxResponse)
   350  				s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
   351  			}
   352  		})
   353  	}
   354  }
   355  
   356  func (s *IntegrationTestSuite) TestCmdGetProposal() {
   357  	val := s.network.Validators[0]
   358  
   359  	title := "Text Proposal 1"
   360  
   361  	testCases := []struct {
   362  		name      string
   363  		args      []string
   364  		expectErr bool
   365  	}{
   366  		{
   367  			"get non existing proposal",
   368  			[]string{
   369  				"10",
   370  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   371  			},
   372  			true,
   373  		},
   374  		{
   375  			"get proposal with json response",
   376  			[]string{
   377  				"1",
   378  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   379  			},
   380  			false,
   381  		},
   382  	}
   383  
   384  	for _, tc := range testCases {
   385  		s.Run(tc.name, func() {
   386  			cmd := cli.GetCmdQueryProposal()
   387  			clientCtx := val.ClientCtx
   388  
   389  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   390  			if tc.expectErr {
   391  				s.Require().Error(err)
   392  			} else {
   393  				s.Require().NoError(err)
   394  				var proposal types.Proposal
   395  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &proposal), out.String())
   396  				s.Require().Equal(title, proposal.GetTitle())
   397  			}
   398  		})
   399  	}
   400  }
   401  
   402  func (s *IntegrationTestSuite) TestCmdGetProposals() {
   403  	val := s.network.Validators[0]
   404  
   405  	testCases := []struct {
   406  		name      string
   407  		args      []string
   408  		expectErr bool
   409  	}{
   410  		{
   411  			"get proposals as json response",
   412  			[]string{
   413  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   414  			},
   415  			false,
   416  		},
   417  		{
   418  			"get proposals with invalid status",
   419  			[]string{
   420  				"--status=unknown",
   421  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   422  			},
   423  			true,
   424  		},
   425  		{
   426  			"wrong number of arguments",
   427  			[]string{
   428  				"extra",
   429  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   430  			},
   431  			true,
   432  		},
   433  	}
   434  
   435  	for _, tc := range testCases {
   436  		s.Run(tc.name, func() {
   437  			cmd := cli.GetCmdQueryProposals()
   438  			clientCtx := val.ClientCtx
   439  
   440  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   441  			if tc.expectErr {
   442  				s.Require().Error(err)
   443  			} else {
   444  				s.Require().NoError(err)
   445  				var proposals types.QueryProposalsResponse
   446  
   447  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &proposals), out.String())
   448  				s.Require().Len(proposals.Proposals, 3)
   449  			}
   450  		})
   451  	}
   452  }
   453  
   454  func (s *IntegrationTestSuite) TestCmdQueryDeposits() {
   455  	val := s.network.Validators[0]
   456  
   457  	testCases := []struct {
   458  		name      string
   459  		args      []string
   460  		expectErr bool
   461  	}{
   462  		{
   463  			"get deposits of non existing proposal",
   464  			[]string{
   465  				"10",
   466  			},
   467  			true,
   468  		},
   469  		{
   470  			"get deposits(valid req)",
   471  			[]string{
   472  				"1",
   473  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   474  			},
   475  			false,
   476  		},
   477  	}
   478  
   479  	for _, tc := range testCases {
   480  		s.Run(tc.name, func() {
   481  			cmd := cli.GetCmdQueryDeposits()
   482  			clientCtx := val.ClientCtx
   483  
   484  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   485  
   486  			if tc.expectErr {
   487  				s.Require().Error(err)
   488  			} else {
   489  				s.Require().NoError(err)
   490  
   491  				var deposits types.QueryDepositsResponse
   492  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &deposits), out.String())
   493  				s.Require().Len(deposits.Deposits, 1)
   494  			}
   495  		})
   496  	}
   497  }
   498  
   499  func (s *IntegrationTestSuite) TestCmdQueryDeposit() {
   500  	val := s.network.Validators[0]
   501  	depositAmount := sdk.NewCoin(s.cfg.BondDenom, types.DefaultMinDepositTokens)
   502  
   503  	testCases := []struct {
   504  		name      string
   505  		args      []string
   506  		expectErr bool
   507  	}{
   508  		{
   509  			"get deposit with no depositer",
   510  			[]string{
   511  				"1",
   512  			},
   513  			true,
   514  		},
   515  		{
   516  			"get deposit with wrong deposit address",
   517  			[]string{
   518  				"1",
   519  				"wrong address",
   520  			},
   521  			true,
   522  		},
   523  		{
   524  			"get deposit (valid req)",
   525  			[]string{
   526  				"1",
   527  				val.Address.String(),
   528  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   529  			},
   530  			false,
   531  		},
   532  	}
   533  
   534  	for _, tc := range testCases {
   535  		s.Run(tc.name, func() {
   536  			cmd := cli.GetCmdQueryDeposit()
   537  			clientCtx := val.ClientCtx
   538  
   539  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   540  
   541  			if tc.expectErr {
   542  				s.Require().Error(err)
   543  			} else {
   544  				s.Require().NoError(err)
   545  
   546  				var deposit types.Deposit
   547  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &deposit), out.String())
   548  				s.Require().Equal(depositAmount.String(), deposit.Amount.String())
   549  			}
   550  		})
   551  	}
   552  }
   553  
   554  func (s *IntegrationTestSuite) TestNewCmdDeposit() {
   555  	val := s.network.Validators[0]
   556  
   557  	testCases := []struct {
   558  		name         string
   559  		args         []string
   560  		expectErr    bool
   561  		expectedCode uint32
   562  	}{
   563  		{
   564  			"without proposal id",
   565  			[]string{
   566  				sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)).String(), // 10stake
   567  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   568  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   569  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   570  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   571  			},
   572  			true, 0,
   573  		},
   574  		{
   575  			"without deposit amount",
   576  			[]string{
   577  				"1",
   578  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   579  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   580  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   581  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   582  			},
   583  			true, 0,
   584  		},
   585  		{
   586  			"deposit on non existing proposal",
   587  			[]string{
   588  				"10",
   589  				sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)).String(), // 10stake
   590  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   591  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   592  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   593  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   594  			},
   595  			false, 2,
   596  		},
   597  		{
   598  			"deposit on non existing proposal",
   599  			[]string{
   600  				"1",
   601  				sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)).String(), // 10stake
   602  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   603  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   604  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   605  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   606  			},
   607  			false, 0,
   608  		},
   609  	}
   610  
   611  	for _, tc := range testCases {
   612  		var resp sdk.TxResponse
   613  
   614  		s.Run(tc.name, func() {
   615  			cmd := cli.NewCmdDeposit()
   616  			clientCtx := val.ClientCtx
   617  
   618  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   619  			if tc.expectErr {
   620  				s.Require().Error(err)
   621  			} else {
   622  				s.Require().NoError(err)
   623  
   624  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String())
   625  				s.Require().Equal(tc.expectedCode, resp.Code, out.String())
   626  			}
   627  		})
   628  	}
   629  }
   630  
   631  func (s *IntegrationTestSuite) TestCmdQueryVotes() {
   632  	val := s.network.Validators[0]
   633  
   634  	testCases := []struct {
   635  		name      string
   636  		args      []string
   637  		expectErr bool
   638  	}{
   639  		{
   640  			"get votes with no proposal id",
   641  			[]string{},
   642  			true,
   643  		},
   644  		{
   645  			"get votes of non existed proposal",
   646  			[]string{
   647  				"10",
   648  			},
   649  			true,
   650  		},
   651  		{
   652  			"vote for invalid proposal",
   653  			[]string{
   654  				"1",
   655  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   656  			},
   657  			false,
   658  		},
   659  	}
   660  
   661  	for _, tc := range testCases {
   662  		s.Run(tc.name, func() {
   663  			cmd := cli.GetCmdQueryVotes()
   664  			clientCtx := val.ClientCtx
   665  
   666  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   667  
   668  			if tc.expectErr {
   669  				s.Require().Error(err)
   670  			} else {
   671  				s.Require().NoError(err)
   672  
   673  				var votes types.QueryVotesResponse
   674  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &votes), out.String())
   675  				s.Require().Len(votes.Votes, 1)
   676  			}
   677  		})
   678  	}
   679  }
   680  
   681  func (s *IntegrationTestSuite) TestCmdQueryVote() {
   682  	val := s.network.Validators[0]
   683  
   684  	testCases := []struct {
   685  		name           string
   686  		args           []string
   687  		expectErr      bool
   688  		expVoteOptions types.WeightedVoteOptions
   689  	}{
   690  		{
   691  			"get vote of non existing proposal",
   692  			[]string{
   693  				"10",
   694  				val.Address.String(),
   695  			},
   696  			true,
   697  			types.NewNonSplitVoteOption(types.OptionYes),
   698  		},
   699  		{
   700  			"get vote by wrong voter",
   701  			[]string{
   702  				"1",
   703  				"wrong address",
   704  			},
   705  			true,
   706  			types.NewNonSplitVoteOption(types.OptionYes),
   707  		},
   708  		{
   709  			"vote for valid proposal",
   710  			[]string{
   711  				"1",
   712  				val.Address.String(),
   713  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   714  			},
   715  			false,
   716  			types.NewNonSplitVoteOption(types.OptionYes),
   717  		},
   718  		{
   719  			"split vote for valid proposal",
   720  			[]string{
   721  				"3",
   722  				val.Address.String(),
   723  				fmt.Sprintf("--%s=json", ostcli.OutputFlag),
   724  			},
   725  			false,
   726  			types.WeightedVoteOptions{
   727  				types.WeightedVoteOption{Option: types.OptionYes, Weight: sdk.NewDecWithPrec(60, 2)},
   728  				types.WeightedVoteOption{Option: types.OptionNo, Weight: sdk.NewDecWithPrec(30, 2)},
   729  				types.WeightedVoteOption{Option: types.OptionAbstain, Weight: sdk.NewDecWithPrec(5, 2)},
   730  				types.WeightedVoteOption{Option: types.OptionNoWithVeto, Weight: sdk.NewDecWithPrec(5, 2)},
   731  			},
   732  		},
   733  	}
   734  
   735  	for _, tc := range testCases {
   736  		s.Run(tc.name, func() {
   737  			cmd := cli.GetCmdQueryVote()
   738  			clientCtx := val.ClientCtx
   739  
   740  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   741  
   742  			if tc.expectErr {
   743  				s.Require().Error(err)
   744  			} else {
   745  				s.Require().NoError(err)
   746  
   747  				var vote types.Vote
   748  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &vote), out.String())
   749  				s.Require().Equal(len(vote.Options), len(tc.expVoteOptions))
   750  				for i, option := range tc.expVoteOptions {
   751  					s.Require().Equal(option.Option, vote.Options[i].Option)
   752  					s.Require().True(option.Weight.Equal(vote.Options[i].Weight))
   753  				}
   754  			}
   755  		})
   756  	}
   757  }
   758  
   759  func (s *IntegrationTestSuite) TestNewCmdVote() {
   760  	val := s.network.Validators[0]
   761  
   762  	testCases := []struct {
   763  		name         string
   764  		args         []string
   765  		expectErr    bool
   766  		expectedCode uint32
   767  	}{
   768  		{
   769  			"invalid vote",
   770  			[]string{},
   771  			true, 0,
   772  		},
   773  		{
   774  			"vote for invalid proposal",
   775  			[]string{
   776  				"10",
   777  				"yes",
   778  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   779  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   780  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   781  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   782  			},
   783  			false, 2,
   784  		},
   785  		{
   786  			"valid vote",
   787  			[]string{
   788  				"1",
   789  				"yes",
   790  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   791  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   792  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   793  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   794  			},
   795  			false, 0,
   796  		},
   797  	}
   798  
   799  	for _, tc := range testCases {
   800  		s.Run(tc.name, func() {
   801  			cmd := cli.NewCmdVote()
   802  			clientCtx := val.ClientCtx
   803  			var txResp sdk.TxResponse
   804  
   805  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   806  
   807  			if tc.expectErr {
   808  				s.Require().Error(err)
   809  			} else {
   810  				s.Require().NoError(err)
   811  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String())
   812  				s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
   813  			}
   814  		})
   815  	}
   816  }
   817  
   818  func (s *IntegrationTestSuite) TestNewCmdWeightedVote() {
   819  	val := s.network.Validators[0]
   820  
   821  	testCases := []struct {
   822  		name         string
   823  		args         []string
   824  		expectErr    bool
   825  		expectedCode uint32
   826  	}{
   827  		{
   828  			"invalid vote",
   829  			[]string{},
   830  			true, 0,
   831  		},
   832  		{
   833  			"vote for invalid proposal",
   834  			[]string{
   835  				"10",
   836  				"yes",
   837  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   838  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   839  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   840  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   841  			},
   842  			false, 2,
   843  		},
   844  		{
   845  			"valid vote",
   846  			[]string{
   847  				"1",
   848  				"yes",
   849  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   850  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   851  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   852  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   853  			},
   854  			false, 0,
   855  		},
   856  		{
   857  			"invalid valid split vote string",
   858  			[]string{
   859  				"1",
   860  				"yes/0.6,no/0.3,abstain/0.05,no_with_veto/0.05",
   861  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   862  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   863  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   864  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   865  			},
   866  			true, 0,
   867  		},
   868  		{
   869  			"valid split vote",
   870  			[]string{
   871  				"1",
   872  				"yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05",
   873  				fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
   874  				fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
   875  				fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
   876  				fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
   877  			},
   878  			false, 0,
   879  		},
   880  	}
   881  
   882  	for _, tc := range testCases {
   883  		s.Run(tc.name, func() {
   884  			cmd := cli.NewCmdWeightedVote()
   885  			clientCtx := val.ClientCtx
   886  			var txResp sdk.TxResponse
   887  
   888  			out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
   889  
   890  			if tc.expectErr {
   891  				s.Require().Error(err)
   892  			} else {
   893  				s.Require().NoError(err)
   894  				s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String())
   895  				s.Require().Equal(tc.expectedCode, txResp.Code, out.String())
   896  			}
   897  		})
   898  	}
   899  }