From 2e30929c7e20f599c1e296243d017c847ccc0370 Mon Sep 17 00:00:00 2001 From: MD Aleem <72057206+aleem1314@users.noreply.github.com> Date: Tue, 11 Jan 2022 20:52:18 +0530 Subject: [PATCH] feat(group): add units tests for msgs (#10920) ## Description Closes: #10905 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- x/group/client/testutil/tx.go | 2 +- x/group/msgs.go | 51 ++- x/group/msgs_test.go | 770 ++++++++++++++++++++++++++++++++++ 3 files changed, 804 insertions(+), 19 deletions(-) create mode 100644 x/group/msgs_test.go diff --git a/x/group/client/testutil/tx.go b/x/group/client/testutil/tx.go index 3185786ea..397d5a792 100644 --- a/x/group/client/testutil/tx.go +++ b/x/group/client/testutil/tx.go @@ -285,7 +285,7 @@ func (s *IntegrationTestSuite) TestTxCreateGroup() { commonFlags..., ), true, - "message validation failed: members: address: empty address string is not allowed", + "message validation failed: address: empty address string is not allowed", nil, 0, }, diff --git a/x/group/msgs.go b/x/group/msgs.go index ef1069dff..622203cba 100644 --- a/x/group/msgs.go +++ b/x/group/msgs.go @@ -17,12 +17,12 @@ import ( const ( TypeMsgCreateGroup = "create_group" TypeMsgUpdateGroupAdmin = "update_group_admin" - TypeMsgUpdateGroupComment = "update_group_comment" + TypeMsgUpdateGroupMetadata = "update_group_metadata" TypeMsgUpdateGroupMembers = "update_group_members" TypeMsgCreateGroupPolicy = "create_group_policy" TypeMsgUpdateGroupPolicyAdmin = "update_group_policy_admin" TypeMsgUpdateGroupPolicyDecisionPolicy = "update_group_policy_decision_policy" - TypeMsgUpdateGroupPolicyComment = "update_group_policy_comment" + TypeMsgUpdateGroupPolicyMetadata = "update_group_policy_metadata" TypeMsgCreateProposal = "create_proposal" TypeMsgVote = "vote" TypeMsgExec = "exec" @@ -57,16 +57,29 @@ func (m MsgCreateGroup) ValidateBasic() error { return sdkerrors.Wrap(err, "admin") } - members := Members{Members: m.Members} - if err := members.ValidateBasic(); err != nil { - return sdkerrors.Wrap(err, "members") - } + return m.validateMembers() +} + +func (m MsgCreateGroup) validateMembers() error { + index := make(map[string]struct{}, len(m.Members)) for i := range m.Members { member := m.Members[i] - if _, err := math.NewPositiveDecFromString(member.Weight); err != nil { - return sdkerrors.Wrap(err, "member weight") + _, err := sdk.AccAddressFromBech32(member.Address) + if err != nil { + return sdkerrors.Wrap(err, "address") } + + if _, err := math.NewPositiveDecFromString(member.Weight); err != nil { + return sdkerrors.Wrap(err, "weight") + } + + addr := member.Address + if _, exists := index[addr]; exists { + return sdkerrors.Wrapf(errors.ErrDuplicate, "address: %s", addr) + } + index[addr] = struct{}{} } + return nil } @@ -75,6 +88,7 @@ func (m Member) ValidateBasic() error { if err != nil { return sdkerrors.Wrap(err, "address") } + if _, err := math.NewNonNegativeDecFromString(m.Weight); err != nil { return sdkerrors.Wrap(err, "weight") } @@ -109,7 +123,7 @@ func (m MsgUpdateGroupAdmin) GetSigners() []sdk.AccAddress { // ValidateBasic does a sanity check on the provided data func (m MsgUpdateGroupAdmin) ValidateBasic() error { if m.GroupId == 0 { - return sdkerrors.Wrap(errors.ErrEmpty, "group") + return sdkerrors.Wrap(errors.ErrEmpty, "group id") } admin, err := sdk.AccAddressFromBech32(m.Admin) @@ -140,7 +154,7 @@ func (m MsgUpdateGroupMetadata) Route() string { } // Type Implements Msg. -func (m MsgUpdateGroupMetadata) Type() string { return TypeMsgUpdateGroupComment } +func (m MsgUpdateGroupMetadata) Type() string { return TypeMsgUpdateGroupMetadata } // GetSignBytes Implements Msg. func (m MsgUpdateGroupMetadata) GetSignBytes() []byte { @@ -159,13 +173,14 @@ func (m MsgUpdateGroupMetadata) GetSigners() []sdk.AccAddress { // ValidateBasic does a sanity check on the provided data func (m MsgUpdateGroupMetadata) ValidateBasic() error { if m.GroupId == 0 { - return sdkerrors.Wrap(errors.ErrEmpty, "group") + return sdkerrors.Wrap(errors.ErrEmpty, "group id") } _, err := sdk.AccAddressFromBech32(m.Admin) if err != nil { return sdkerrors.Wrap(err, "admin") } + return nil } @@ -202,7 +217,7 @@ func (m MsgUpdateGroupMembers) GetSigners() []sdk.AccAddress { // ValidateBasic does a sanity check on the provided data func (m MsgUpdateGroupMembers) ValidateBasic() error { if m.GroupId == 0 { - return sdkerrors.Wrap(errors.ErrEmpty, "group") + return sdkerrors.Wrap(errors.ErrEmpty, "group id") } _, err := sdk.AccAddressFromBech32(m.Admin) @@ -255,7 +270,7 @@ func (m MsgCreateGroupPolicy) ValidateBasic() error { return sdkerrors.Wrap(err, "admin") } if m.GroupId == 0 { - return sdkerrors.Wrap(errors.ErrEmpty, "group") + return sdkerrors.Wrap(errors.ErrEmpty, "group id") } policy := m.GetDecisionPolicy() @@ -311,7 +326,7 @@ func (m MsgUpdateGroupPolicyAdmin) ValidateBasic() error { } if admin.Equals(newAdmin) { - return sdkerrors.Wrap(errors.ErrInvalid, "new and old admin are the same") + return sdkerrors.Wrap(errors.ErrInvalid, "new and old admin are same") } return nil } @@ -334,7 +349,7 @@ func NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin sdk.AccAddress, address func (m *MsgUpdateGroupPolicyDecisionPolicy) SetDecisionPolicy(decisionPolicy DecisionPolicy) error { msg, ok := decisionPolicy.(proto.Message) if !ok { - return fmt.Errorf("can't proto marshal %T", msg) + return sdkerrors.ErrInvalidType.Wrapf("can't proto marshal %T", msg) } any, err := types.NewAnyWithValue(msg) if err != nil { @@ -414,7 +429,7 @@ func (m MsgUpdateGroupPolicyMetadata) Route() string { } // Type Implements Msg. -func (m MsgUpdateGroupPolicyMetadata) Type() string { return TypeMsgUpdateGroupPolicyComment } +func (m MsgUpdateGroupPolicyMetadata) Type() string { return TypeMsgUpdateGroupPolicyMetadata } // GetSignBytes Implements Msg. func (m MsgUpdateGroupPolicyMetadata) GetSignBytes() []byte { @@ -630,7 +645,7 @@ func (m MsgVote) ValidateBasic() error { return sdkerrors.Wrap(err, "voter") } if m.ProposalId == 0 { - return sdkerrors.Wrap(errors.ErrEmpty, "proposal") + return sdkerrors.Wrap(errors.ErrEmpty, "proposal id") } if m.Choice == Choice_CHOICE_UNSPECIFIED { return sdkerrors.Wrap(errors.ErrEmpty, "choice") @@ -672,7 +687,7 @@ func (m MsgExec) ValidateBasic() error { return sdkerrors.Wrap(err, "signer") } if m.ProposalId == 0 { - return sdkerrors.Wrap(errors.ErrEmpty, "proposal") + return sdkerrors.Wrap(errors.ErrEmpty, "proposal id") } return nil } diff --git a/x/group/msgs_test.go b/x/group/msgs_test.go new file mode 100644 index 000000000..83ebd9af7 --- /dev/null +++ b/x/group/msgs_test.go @@ -0,0 +1,770 @@ +package group_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/group" +) + +var ( + admin = sdk.AccAddress("admin") + member1 = sdk.AccAddress("member1") + member2 = sdk.AccAddress("member2") +) + +func TestMsgCreateGroup(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgCreateGroup + expErr bool + errMsg string + }{ + { + "invalid admin address", + &group.MsgCreateGroup{ + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "invalid member address", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{ + group.Member{ + Address: "invalid address", + }, + }, + }, + true, + "address: decoding bech32 failed", + }, + { + "negitive member's weight not allowed", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "-1", + }, + }, + }, + true, + "expected a positive decimal", + }, + { + "zero member's weight not allowed", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "0", + }, + }, + }, + true, + "expected a positive decimal", + }, + { + "duplicate member not allowed", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "1", + Metadata: []byte("metadata"), + }, + group.Member{ + Address: member1.String(), + Weight: "1", + Metadata: []byte("metadata"), + }, + }, + }, + true, + "duplicate value", + }, + { + "valid test case with single member", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "1", + Metadata: []byte("metadata"), + }, + }, + }, + false, + "", + }, + { + "minimum fields", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{}, + }, + false, + "", + }, + { + "valid test case with multiple members", + &group.MsgCreateGroup{ + Admin: admin.String(), + Members: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "1", + Metadata: []byte("metadata"), + }, + group.Member{ + Address: member2.String(), + Weight: "1", + Metadata: []byte("metadata"), + }, + }, + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, tc.msg.Type(), group.TypeMsgCreateGroup) + } + }) + } +} + +func TestMsgUpdateGroupAdmin(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgUpdateGroupAdmin + expErr bool + errMsg string + }{ + { + "empty group id", + &group.MsgUpdateGroupAdmin{ + Admin: admin.String(), + NewAdmin: member1.String(), + }, + true, + "group id: value is empty", + }, + { + "admin: invalid bech32 address", + &group.MsgUpdateGroupAdmin{ + GroupId: 1, + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "new admin: invalid bech32 address", + &group.MsgUpdateGroupAdmin{ + GroupId: 1, + Admin: admin.String(), + NewAdmin: "new-admin", + }, + true, + "new admin: decoding bech32 failed", + }, + { + "admin & new admin is same", + &group.MsgUpdateGroupAdmin{ + GroupId: 1, + Admin: admin.String(), + NewAdmin: admin.String(), + }, + true, + "new and old admin are the same", + }, + { + "valid case", + &group.MsgUpdateGroupAdmin{ + GroupId: 1, + Admin: admin.String(), + NewAdmin: member1.String(), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, tc.msg.Type(), group.TypeMsgUpdateGroupAdmin) + } + }) + } +} + +func TestMsgUpdateGroupMetadata(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgUpdateGroupMetadata + expErr bool + errMsg string + }{ + { + "empty group id", + &group.MsgUpdateGroupMetadata{ + Admin: admin.String(), + }, + true, + "group id: value is empty", + }, + { + "admin: invalid bech32 address", + &group.MsgUpdateGroupMetadata{ + GroupId: 1, + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "valid test", + &group.MsgUpdateGroupMetadata{ + GroupId: 1, + Admin: admin.String(), + Metadata: []byte("metadata"), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, tc.msg.Type(), group.TypeMsgUpdateGroupMetadata) + } + }) + } +} + +func TestMsgUpdateGroupMembers(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgUpdateGroupMembers + expErr bool + errMsg string + }{ + { + "empty group id", + &group.MsgUpdateGroupMembers{}, + true, + "group id: value is empty", + }, + { + "admin: invalid bech32 address", + &group.MsgUpdateGroupMembers{ + GroupId: 1, + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "empty member list", + &group.MsgUpdateGroupMembers{ + GroupId: 1, + Admin: admin.String(), + MemberUpdates: []group.Member{}, + }, + true, + "member updates: value is empty", + }, + { + "valid test", + &group.MsgUpdateGroupMembers{ + GroupId: 1, + Admin: admin.String(), + MemberUpdates: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "1", + Metadata: []byte("metadata"), + }, + }, + }, + false, + "", + }, + { + "valid test with zero weight", + &group.MsgUpdateGroupMembers{ + GroupId: 1, + Admin: admin.String(), + MemberUpdates: []group.Member{ + group.Member{ + Address: member1.String(), + Weight: "0", + Metadata: []byte("metadata"), + }, + }, + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, tc.msg.Type(), group.TypeMsgUpdateGroupMembers) + } + }) + } +} + +func TestMsgCreateGroupPolicy(t *testing.T) { + testCases := []struct { + name string + msg func() *group.MsgCreateGroupPolicy + expErr bool + errMsg string + }{ + { + "empty group id", + func() *group.MsgCreateGroupPolicy { + return &group.MsgCreateGroupPolicy{ + Admin: admin.String(), + } + }, + true, + "group id: value is empty", + }, + { + "admin: invalid bech32 address", + func() *group.MsgCreateGroupPolicy { + return &group.MsgCreateGroupPolicy{ + Admin: "admin", + GroupId: 1, + } + }, + true, + "admin: decoding bech32 failed", + }, + { + "invalid threshold policy", + func() *group.MsgCreateGroupPolicy { + policy := group.NewThresholdDecisionPolicy("-1", time.Second) + req, err := group.NewMsgCreateGroupPolicy(admin, 1, []byte("metadata"), policy) + require.NoError(t, err) + return req + }, + true, + "expected a positive decimal", + }, + { + "valid test case", + func() *group.MsgCreateGroupPolicy { + policy := group.NewThresholdDecisionPolicy("1", time.Second) + req, err := group.NewMsgCreateGroupPolicy(admin, 1, []byte("metadata"), policy) + require.NoError(t, err) + return req + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg() + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgCreateGroupPolicy) + } + }) + } +} + +func TestMsgUpdateGroupPolicyDecisionPolicy(t *testing.T) { + validPolicy := group.NewThresholdDecisionPolicy("1", time.Second) + msg1, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member1, validPolicy) + require.NoError(t, err) + + invalidPolicy := group.NewThresholdDecisionPolicy("-1", time.Second) + msg2, err := group.NewMsgUpdateGroupPolicyDecisionPolicyRequest(admin, member2, invalidPolicy) + require.NoError(t, err) + + testCases := []struct { + name string + msg *group.MsgUpdateGroupPolicyDecisionPolicy + expErr bool + errMsg string + }{ + { + "admin: invalid bech32 address", + &group.MsgUpdateGroupPolicyDecisionPolicy{ + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "group policy: invalid bech32 address", + &group.MsgUpdateGroupPolicyDecisionPolicy{ + Admin: admin.String(), + Address: "address", + }, + true, + "group policy: decoding bech32 failed", + }, + { + "group policy: invalid bech32 address", + &group.MsgUpdateGroupPolicyDecisionPolicy{ + Admin: admin.String(), + Address: "address", + }, + true, + "group policy: decoding bech32 failed", + }, + { + "invalid decision policy", + msg2, + true, + "decision policy: threshold: expected a positive decimal", + }, + { + "invalid decision policy", + msg1, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgUpdateGroupPolicyDecisionPolicy) + } + }) + } +} + +func TestMsgUpdateGroupPolicyAdmin(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgUpdateGroupPolicyAdmin + expErr bool + errMsg string + }{ + { + "admin: invalid bech32 address", + &group.MsgUpdateGroupPolicyAdmin{ + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "policy address: invalid bech32 address", + &group.MsgUpdateGroupPolicyAdmin{ + Admin: admin.String(), + NewAdmin: member1.String(), + Address: "address", + }, + true, + "group policy: decoding bech32 failed", + }, + { + "new admin: invalid bech32 address", + &group.MsgUpdateGroupPolicyAdmin{ + Admin: admin.String(), + Address: admin.String(), + NewAdmin: "new-admin", + }, + true, + "new admin: decoding bech32 failed", + }, + { + "same old and new admin", + &group.MsgUpdateGroupPolicyAdmin{ + Admin: admin.String(), + Address: admin.String(), + NewAdmin: admin.String(), + }, + true, + "new and old admin are same", + }, + { + "valid test", + &group.MsgUpdateGroupPolicyAdmin{ + Admin: admin.String(), + Address: admin.String(), + NewAdmin: member1.String(), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgUpdateGroupPolicyAdmin) + } + }) + } +} + +func TestMsgUpdateGroupPolicyMetadata(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgUpdateGroupPolicyMetadata + expErr bool + errMsg string + }{ + { + "admin: invalid bech32 address", + &group.MsgUpdateGroupPolicyMetadata{ + Admin: "admin", + }, + true, + "admin: decoding bech32 failed", + }, + { + "group policy address: invalid bech32 address", + &group.MsgUpdateGroupPolicyMetadata{ + Admin: admin.String(), + Address: "address", + }, + true, + "group policy: decoding bech32 failed", + }, + { + "valid testcase", + &group.MsgUpdateGroupPolicyMetadata{ + Admin: admin.String(), + Address: member1.String(), + Metadata: []byte("metadata"), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgUpdateGroupPolicyMetadata) + } + }) + } +} + +func TestMsgCreateProposal(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgCreateProposal + expErr bool + errMsg string + }{ + { + "invalid group policy address", + &group.MsgCreateProposal{ + Address: "address", + }, + true, + "group policy: decoding bech32 failed", + }, + { + "proposers required", + &group.MsgCreateProposal{ + Address: admin.String(), + }, + true, + "proposers: value is empty", + }, + { + "valid testcase", + &group.MsgCreateProposal{ + Address: admin.String(), + Proposers: []string{member1.String(), member2.String()}, + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgCreateProposal) + } + }) + } +} + +func TestMsgVote(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgVote + expErr bool + errMsg string + }{ + { + "invalid voter address", + &group.MsgVote{ + Voter: "voter", + }, + true, + "voter: decoding bech32 failed", + }, + { + "proposal id is required", + &group.MsgVote{ + Voter: member1.String(), + }, + true, + "proposal id: value is empty", + }, + { + "unspecified vote choice", + &group.MsgVote{ + Voter: member1.String(), + ProposalId: 1, + }, + true, + "choice: value is empty", + }, + { + "valid test case", + &group.MsgVote{ + Voter: member1.String(), + ProposalId: 1, + Choice: group.Choice_CHOICE_YES, + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgVote) + } + }) + } +} + +func TestMsgExec(t *testing.T) { + testCases := []struct { + name string + msg *group.MsgExec + expErr bool + errMsg string + }{ + { + "invalid signer address", + &group.MsgExec{ + Signer: "signer", + }, + true, + "signer: decoding bech32 failed", + }, + { + "proposal is required", + &group.MsgExec{ + Signer: admin.String(), + }, + true, + "proposal id: value is empty", + }, + { + "valid testcase", + &group.MsgExec{ + Signer: admin.String(), + ProposalId: 1, + }, + false, + "", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := tc.msg + err := msg.ValidateBasic() + if tc.expErr { + require.Error(t, err) + require.Contains(t, err.Error(), tc.errMsg) + } else { + require.NoError(t, err) + require.Equal(t, msg.Type(), group.TypeMsgExec) + } + }) + } +}