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 }