add cli, grpc, keeper test for new split vote

This commit is contained in:
antstalepresh 2020-10-29 22:24:55 +10:00
parent 0cb2c70b4d
commit 7e87b5d998
5 changed files with 119 additions and 25 deletions

View File

@ -33,7 +33,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
s.cfg = network.DefaultConfig()
s.cfg.NumValidators = 1
s.cfg.NumValidators = 2
s.network = network.New(s.T(), s.cfg)
@ -41,6 +41,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.Require().NoError(err)
val := s.network.Validators[0]
val2 := s.network.Validators[1]
// create a proposal with deposit
_, err = govtestutil.MsgSubmitProposal(val.ClientCtx, val.Address.String(),
@ -54,6 +55,10 @@ func (s *IntegrationTestSuite) SetupSuite() {
_, err = govtestutil.MsgVote(val.ClientCtx, val.Address.String(), "1", "yes")
s.Require().NoError(err)
// vote for proposal as val2
_, err = govtestutil.MsgVote(val2.ClientCtx, val2.Address.String(), "1", "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05")
s.Require().NoError(err)
// create a proposal without deposit
_, err = govtestutil.MsgSubmitProposal(val.ClientCtx, val.Address.String(),
"Text Proposal 2", "Where is the title!?", types.ProposalTypeText)
@ -679,7 +684,7 @@ func (s *IntegrationTestSuite) TestCmdQueryVotes() {
var votes types.QueryVotesResponse
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &votes), out.String())
s.Require().Len(votes.Votes, 1)
s.Require().Len(votes.Votes, 2)
}
})
}
@ -687,11 +692,13 @@ func (s *IntegrationTestSuite) TestCmdQueryVotes() {
func (s *IntegrationTestSuite) TestCmdQueryVote() {
val := s.network.Validators[0]
val2 := s.network.Validators[1]
testCases := []struct {
name string
args []string
expectErr bool
name string
args []string
expectErr bool
expSubVotes types.SubVotes
}{
{
"get vote of non existing proposal",
@ -700,6 +707,7 @@ func (s *IntegrationTestSuite) TestCmdQueryVote() {
val.Address.String(),
},
true,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"get vote by wrong voter",
@ -708,6 +716,7 @@ func (s *IntegrationTestSuite) TestCmdQueryVote() {
"wrong address",
},
true,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"vote for valid proposal",
@ -717,6 +726,22 @@ func (s *IntegrationTestSuite) TestCmdQueryVote() {
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
},
false,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"split vote for valid proposal",
[]string{
"1",
val2.Address.String(),
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
},
false,
types.SubVotes{
types.SubVote{Option: types.OptionYes, Rate: sdk.NewDecWithPrec(60, 2)},
types.SubVote{Option: types.OptionNo, Rate: sdk.NewDecWithPrec(30, 2)},
types.SubVote{Option: types.OptionAbstain, Rate: sdk.NewDecWithPrec(5, 2)},
types.SubVote{Option: types.OptionNoWithVeto, Rate: sdk.NewDecWithPrec(5, 2)},
},
},
}
@ -735,8 +760,11 @@ func (s *IntegrationTestSuite) TestCmdQueryVote() {
var vote types.Vote
s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(out.Bytes(), &vote), out.String())
s.Require().True(len(vote.SubVotes) == 1)
s.Require().Equal(types.OptionYes, vote.SubVotes[0].Option)
s.Require().Equal(len(vote.SubVotes), len(tc.expSubVotes))
for i, subvote := range tc.expSubVotes {
s.Require().Equal(subvote.Option, vote.SubVotes[i].Option)
s.Require().True(subvote.Rate.Equal(vote.SubVotes[i].Rate))
}
}
})
}
@ -780,6 +808,30 @@ func (s *IntegrationTestSuite) TestNewCmdVote() {
},
false, 0,
},
{
"invalid valid split vote string",
[]string{
"1",
fmt.Sprintf("%s", "yes/0.6,no/0.3,abstain/0.05,no_with_veto/0.05"),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
true, 0,
},
{
"valid split vote",
[]string{
"1",
fmt.Sprintf("%s", "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05"),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
},
false, 0,
},
}
for _, tc := range testCases {

View File

@ -30,7 +30,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
s.cfg = network.DefaultConfig()
s.cfg.NumValidators = 1
s.cfg.NumValidators = 2
s.network = network.New(s.T(), s.cfg)
@ -38,6 +38,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.Require().NoError(err)
val := s.network.Validators[0]
val2 := s.network.Validators[1]
// create a proposal with deposit
_, err = govtestutil.MsgSubmitProposal(val.ClientCtx, val.Address.String(),
@ -51,6 +52,10 @@ func (s *IntegrationTestSuite) SetupSuite() {
_, err = govtestutil.MsgVote(val.ClientCtx, val.Address.String(), "1", "yes")
s.Require().NoError(err)
// vote for proposal as val2
_, err = govtestutil.MsgVote(val2.ClientCtx, val2.Address.String(), "1", "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05")
s.Require().NoError(err)
// create a proposal without deposit
_, err = govtestutil.MsgSubmitProposal(val.ClientCtx, val.Address.String(),
"Text Proposal 2", "Where is the title!?", types.ProposalTypeText)
@ -149,33 +154,51 @@ func (s *IntegrationTestSuite) TestGetProposalsGRPC() {
func (s *IntegrationTestSuite) TestGetProposalVoteGRPC() {
val := s.network.Validators[0]
val2 := s.network.Validators[1]
voterAddressBase64 := val.Address.String()
voter2AddressBase64 := val2.Address.String()
testCases := []struct {
name string
url string
expErr bool
name string
url string
expErr bool
expSubVotes types.SubVotes
}{
{
"empty proposal",
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "", voterAddressBase64),
true,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"get non existing proposal",
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "10", voterAddressBase64),
true,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"get proposal with wrong voter address",
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "1", "wrongVoterAddress"),
true,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"get proposal with id",
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "1", voterAddressBase64),
false,
types.SubVotes{types.NewSubVote(types.OptionYes, 1)},
},
{
"get proposal with id for split vote",
fmt.Sprintf("%s/cosmos/gov/v1beta1/proposals/%s/votes/%s", val.APIAddress, "1", voter2AddressBase64),
false,
types.SubVotes{
types.SubVote{Option: types.OptionYes, Rate: sdk.NewDecWithPrec(60, 2)},
types.SubVote{Option: types.OptionNo, Rate: sdk.NewDecWithPrec(30, 2)},
types.SubVote{Option: types.OptionAbstain, Rate: sdk.NewDecWithPrec(5, 2)},
types.SubVote{Option: types.OptionNoWithVeto, Rate: sdk.NewDecWithPrec(5, 2)},
},
},
}
@ -193,8 +216,11 @@ func (s *IntegrationTestSuite) TestGetProposalVoteGRPC() {
} else {
s.Require().NoError(err)
s.Require().NotEmpty(vote.Vote)
s.Require().True(len(vote.Vote.SubVotes) == 1)
s.Require().Equal(types.OptionYes, vote.Vote.SubVotes[0].Option)
s.Require().Equal(len(vote.Vote.SubVotes), len(tc.expSubVotes))
for i, subvote := range tc.expSubVotes {
s.Require().Equal(subvote.Option, vote.Vote.SubVotes[i].Option)
s.Require().True(subvote.Rate.Equal(vote.Vote.SubVotes[i].Rate))
}
}
})
}
@ -233,7 +259,7 @@ func (s *IntegrationTestSuite) TestGetProposalVotesGRPC() {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().Len(votes.Votes, 1)
s.Require().Len(votes.Votes, 2)
}
})
}

View File

@ -52,7 +52,7 @@ type DepositReq struct {
// VoteReq defines the properties of a vote request's body.
type VoteReq struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
Voter sdk.AccAddress `json:"voter" yaml:"voter"` // address of the voter
Option string `json:"option" yaml:"option"` // option from OptionSet chosen by the voter
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
Voter sdk.AccAddress `json:"voter" yaml:"voter"` // address of the voter
SubVotes string `json:"sub_votes" yaml:"sub_votes"` // option from OptionSet chosen by the voter
}

View File

@ -111,13 +111,14 @@ func newVoteHandlerFn(clientCtx client.Context) http.HandlerFunc {
return
}
voteOption, err := types.VoteOptionFromString(gcutils.NormalizeVoteOption(req.Option))
if rest.CheckBadRequestError(w, err) {
// Figure out which subvotes user chose
subvotes, err := types.SubVotesFromString(gcutils.NormalizeSubVotes(req.SubVotes))
if err != nil {
return
}
// create the message
msg := types.NewMsgVote(req.Voter, proposalID, types.SubVotes{types.NewSubVote(voteOption, 1)})
msg := types.NewMsgVote(req.Voter, proposalID, subvotes)
if rest.CheckBadRequestError(w, msg.ValidateBasic()) {
return
}

View File

@ -51,13 +51,25 @@ func TestVotes(t *testing.T) {
require.Equal(t, types.OptionYes, vote.SubVotes[0].Option)
// Test second vote
require.NoError(t, app.GovKeeper.AddVote(ctx, proposalID, addrs[1], types.SubVotes{types.NewSubVote(types.OptionNoWithVeto, 1)}))
require.NoError(t, app.GovKeeper.AddVote(ctx, proposalID, addrs[1], types.SubVotes{
types.SubVote{Option: types.OptionYes, Rate: sdk.NewDecWithPrec(60, 2)},
types.SubVote{Option: types.OptionNo, Rate: sdk.NewDecWithPrec(30, 2)},
types.SubVote{Option: types.OptionAbstain, Rate: sdk.NewDecWithPrec(5, 2)},
types.SubVote{Option: types.OptionNoWithVeto, Rate: sdk.NewDecWithPrec(5, 2)},
}))
vote, found = app.GovKeeper.GetVote(ctx, proposalID, addrs[1])
require.True(t, found)
require.Equal(t, addrs[1].String(), vote.Voter)
require.Equal(t, proposalID, vote.ProposalId)
require.True(t, len(vote.SubVotes) == 1)
require.Equal(t, types.OptionNoWithVeto, vote.SubVotes[0].Option)
require.True(t, len(vote.SubVotes) == 4)
require.Equal(t, types.OptionYes, vote.SubVotes[0].Option)
require.Equal(t, types.OptionNo, vote.SubVotes[1].Option)
require.Equal(t, types.OptionAbstain, vote.SubVotes[2].Option)
require.Equal(t, types.OptionNoWithVeto, vote.SubVotes[3].Option)
require.True(t, vote.SubVotes[0].Rate.Equal(sdk.NewDecWithPrec(60, 2)))
require.True(t, vote.SubVotes[1].Rate.Equal(sdk.NewDecWithPrec(30, 2)))
require.True(t, vote.SubVotes[2].Rate.Equal(sdk.NewDecWithPrec(5, 2)))
require.True(t, vote.SubVotes[3].Rate.Equal(sdk.NewDecWithPrec(5, 2)))
// Test vote iterator
// NOTE order of deposits is determined by the addresses
@ -70,6 +82,9 @@ func TestVotes(t *testing.T) {
require.Equal(t, types.OptionYes, votes[0].SubVotes[0].Option)
require.Equal(t, addrs[1].String(), votes[1].Voter)
require.Equal(t, proposalID, votes[1].ProposalId)
require.True(t, len(votes[1].SubVotes) == 1)
require.Equal(t, types.OptionNoWithVeto, votes[1].SubVotes[0].Option)
require.True(t, len(votes[1].SubVotes) == 4)
require.True(t, votes[1].SubVotes[0].Rate.Equal(sdk.NewDecWithPrec(60, 2)))
require.True(t, votes[1].SubVotes[1].Rate.Equal(sdk.NewDecWithPrec(30, 2)))
require.True(t, votes[1].SubVotes[2].Rate.Equal(sdk.NewDecWithPrec(5, 2)))
require.True(t, votes[1].SubVotes[3].Rate.Equal(sdk.NewDecWithPrec(5, 2)))
}