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