## Description Closes: #11794 - Remove `AddedAt` from member request on group creation and member update - Set member `AddedAt` field properly on member update. --- ### 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/main/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/main/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/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)
1168 lines
26 KiB
Go
1168 lines
26 KiB
Go
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")
|
|
member3 = sdk.AccAddress("member3")
|
|
member4 = sdk.AccAddress("member4")
|
|
member5 = sdk.AccAddress("member5")
|
|
)
|
|
|
|
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.MemberRequest{
|
|
{
|
|
Address: "invalid address",
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
"address: decoding bech32 failed",
|
|
},
|
|
{
|
|
"negitive member's weight not allowed",
|
|
&group.MsgCreateGroup{
|
|
Admin: admin.String(),
|
|
Members: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "-1",
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
"expected a non-negative decimal",
|
|
},
|
|
{
|
|
"zero member's weight not allowed",
|
|
&group.MsgCreateGroup{
|
|
Admin: admin.String(),
|
|
Members: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "0",
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"duplicate member not allowed",
|
|
&group.MsgCreateGroup{
|
|
Admin: admin.String(),
|
|
Members: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
},
|
|
},
|
|
true,
|
|
"duplicate value",
|
|
},
|
|
{
|
|
"valid test case with single member",
|
|
&group.MsgCreateGroup{
|
|
Admin: admin.String(),
|
|
Members: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"minimum fields",
|
|
&group.MsgCreateGroup{
|
|
Admin: admin.String(),
|
|
Members: []group.MemberRequest{},
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"valid test case with multiple members",
|
|
&group.MsgCreateGroup{
|
|
Admin: admin.String(),
|
|
Members: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
{
|
|
Address: member2.String(),
|
|
Weight: "1",
|
|
Metadata: "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(), sdk.MsgTypeURL(&group.MsgCreateGroup{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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(), sdk.MsgTypeURL(&group.MsgUpdateGroupAdmin{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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: "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(), sdk.MsgTypeURL(&group.MsgUpdateGroupMetadata{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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.MemberRequest{},
|
|
},
|
|
true,
|
|
"member updates: value is empty",
|
|
},
|
|
{
|
|
"valid test",
|
|
&group.MsgUpdateGroupMembers{
|
|
GroupId: 1,
|
|
Admin: admin.String(),
|
|
MemberUpdates: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
},
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"valid test with zero weight",
|
|
&group.MsgUpdateGroupMembers{
|
|
GroupId: 1,
|
|
Admin: admin.String(),
|
|
MemberUpdates: []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "0",
|
|
Metadata: "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(), sdk.MsgTypeURL(&group.MsgUpdateGroupMembers{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMsgCreateGroupWithPolicy(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
msg func() *group.MsgCreateGroupWithPolicy
|
|
expErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
"invalid admin address",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
admin := "admin"
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin, members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"admin: decoding bech32 failed",
|
|
},
|
|
{
|
|
"invalid member address",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: "invalid_address",
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"address: decoding bech32 failed",
|
|
},
|
|
{
|
|
"negative member's weight not allowed",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "-1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a non-negative decimal",
|
|
},
|
|
{
|
|
"zero member's weight not allowed",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "0",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"duplicate member not allowed",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"duplicate value",
|
|
},
|
|
{
|
|
"invalid threshold policy",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("-1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"valid test case with single member",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"valid test case with multiple members",
|
|
func() *group.MsgCreateGroupWithPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
members := []group.MemberRequest{
|
|
{
|
|
Address: member1.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
{
|
|
Address: member2.String(),
|
|
Weight: "1",
|
|
Metadata: "metadata",
|
|
},
|
|
}
|
|
req, err := group.NewMsgCreateGroupWithPolicy(admin.String(), members, "group_metadata", "group_policy_metadata", false, 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(), sdk.MsgTypeURL(&group.MsgCreateGroupWithPolicy{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"invalid voting period",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("-1", time.Duration(0), 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"invalid execution period",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("-1", time.Minute, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"valid test case, only voting period",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"valid test case, voting and execution, empty min exec period",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"valid test case, voting and execution, non-empty min exec period",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
policy := group.NewThresholdDecisionPolicy("1", time.Second, time.Minute)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", policy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"invalid percentage decision policy with zero value",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
percentagePolicy := group.NewPercentageDecisionPolicy("0", time.Second, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"invalid percentage decision policy with negative value",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
percentagePolicy := group.NewPercentageDecisionPolicy("-0.2", time.Second, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"expected a positive decimal",
|
|
},
|
|
{
|
|
"invalid percentage decision policy with value greater than 1",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
percentagePolicy := group.NewPercentageDecisionPolicy("2", time.Second, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
|
require.NoError(t, err)
|
|
return req
|
|
},
|
|
true,
|
|
"percentage must be > 0 and <= 1",
|
|
},
|
|
{
|
|
"valid test case with percentage decision policy",
|
|
func() *group.MsgCreateGroupPolicy {
|
|
percentagePolicy := group.NewPercentageDecisionPolicy("0.5", time.Second, 0)
|
|
req, err := group.NewMsgCreateGroupPolicy(admin, 1, "metadata", percentagePolicy)
|
|
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(), sdk.MsgTypeURL(&group.MsgCreateGroupPolicy{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMsgUpdateGroupPolicyDecisionPolicy(t *testing.T) {
|
|
validPolicy := group.NewThresholdDecisionPolicy("1", time.Second, 0)
|
|
msg1, err := group.NewMsgUpdateGroupPolicyDecisionPolicy(admin, member1, validPolicy)
|
|
require.NoError(t, err)
|
|
|
|
invalidPolicy := group.NewThresholdDecisionPolicy("-1", time.Second, 0)
|
|
msg2, err := group.NewMsgUpdateGroupPolicyDecisionPolicy(admin, member2, invalidPolicy)
|
|
require.NoError(t, err)
|
|
|
|
validPercentagePolicy := group.NewPercentageDecisionPolicy("0.7", time.Second, 0)
|
|
msg3, err := group.NewMsgUpdateGroupPolicyDecisionPolicy(admin, member3, validPercentagePolicy)
|
|
require.NoError(t, err)
|
|
|
|
invalidPercentagePolicy := group.NewPercentageDecisionPolicy("-0.1", time.Second, 0)
|
|
msg4, err := group.NewMsgUpdateGroupPolicyDecisionPolicy(admin, member4, invalidPercentagePolicy)
|
|
require.NoError(t, err)
|
|
|
|
invalidPercentagePolicy2 := group.NewPercentageDecisionPolicy("2", time.Second, 0)
|
|
msg5, err := group.NewMsgUpdateGroupPolicyDecisionPolicy(admin, member5, invalidPercentagePolicy2)
|
|
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(),
|
|
GroupPolicyAddress: "address",
|
|
},
|
|
true,
|
|
"group policy: decoding bech32 failed",
|
|
},
|
|
{
|
|
"group policy: invalid bech32 address",
|
|
&group.MsgUpdateGroupPolicyDecisionPolicy{
|
|
Admin: admin.String(),
|
|
GroupPolicyAddress: "address",
|
|
},
|
|
true,
|
|
"group policy: decoding bech32 failed",
|
|
},
|
|
{
|
|
"invalid decision policy",
|
|
msg2,
|
|
true,
|
|
"decision policy: threshold: expected a positive decimal",
|
|
},
|
|
{
|
|
"valid decision policy",
|
|
msg1,
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"valid percentage decision policy",
|
|
msg3,
|
|
false,
|
|
"",
|
|
},
|
|
{
|
|
"invalid percentage decision policy with negative value",
|
|
msg4,
|
|
true,
|
|
"decision policy: percentage threshold: expected a positive decimal",
|
|
},
|
|
{
|
|
"invalid percentage decision policy with value greater than 1",
|
|
msg5,
|
|
true,
|
|
"decision policy: percentage must be > 0 and <= 1",
|
|
},
|
|
}
|
|
|
|
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(), sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyDecisionPolicy{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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(),
|
|
GroupPolicyAddress: "address",
|
|
},
|
|
true,
|
|
"group policy: decoding bech32 failed",
|
|
},
|
|
{
|
|
"new admin: invalid bech32 address",
|
|
&group.MsgUpdateGroupPolicyAdmin{
|
|
Admin: admin.String(),
|
|
GroupPolicyAddress: admin.String(),
|
|
NewAdmin: "new-admin",
|
|
},
|
|
true,
|
|
"new admin: decoding bech32 failed",
|
|
},
|
|
{
|
|
"same old and new admin",
|
|
&group.MsgUpdateGroupPolicyAdmin{
|
|
Admin: admin.String(),
|
|
GroupPolicyAddress: admin.String(),
|
|
NewAdmin: admin.String(),
|
|
},
|
|
true,
|
|
"new and old admin are same",
|
|
},
|
|
{
|
|
"valid test",
|
|
&group.MsgUpdateGroupPolicyAdmin{
|
|
Admin: admin.String(),
|
|
GroupPolicyAddress: 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(), sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyAdmin{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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(),
|
|
GroupPolicyAddress: "address",
|
|
},
|
|
true,
|
|
"group policy: decoding bech32 failed",
|
|
},
|
|
{
|
|
"valid testcase",
|
|
&group.MsgUpdateGroupPolicyMetadata{
|
|
Admin: admin.String(),
|
|
GroupPolicyAddress: member1.String(),
|
|
Metadata: "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(), sdk.MsgTypeURL(&group.MsgUpdateGroupPolicyMetadata{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMsgSubmitProposal(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
msg *group.MsgSubmitProposal
|
|
expErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
"invalid group policy address",
|
|
&group.MsgSubmitProposal{
|
|
GroupPolicyAddress: "address",
|
|
},
|
|
true,
|
|
"group policy: decoding bech32 failed",
|
|
},
|
|
{
|
|
"proposers required",
|
|
&group.MsgSubmitProposal{
|
|
GroupPolicyAddress: admin.String(),
|
|
},
|
|
true,
|
|
"proposers: value is empty",
|
|
},
|
|
{
|
|
"valid testcase",
|
|
&group.MsgSubmitProposal{
|
|
GroupPolicyAddress: 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(), sdk.MsgTypeURL(&group.MsgSubmitProposal{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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 option",
|
|
&group.MsgVote{
|
|
Voter: member1.String(),
|
|
ProposalId: 1,
|
|
},
|
|
true,
|
|
"vote option: value is empty",
|
|
},
|
|
{
|
|
"valid test case",
|
|
&group.MsgVote{
|
|
Voter: member1.String(),
|
|
ProposalId: 1,
|
|
Option: group.VOTE_OPTION_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(), sdk.MsgTypeURL(&group.MsgVote{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMsgWithdrawProposal(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
msg *group.MsgWithdrawProposal
|
|
expErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
"invalid address",
|
|
&group.MsgWithdrawProposal{
|
|
Address: "address",
|
|
},
|
|
true,
|
|
"decoding bech32 failed",
|
|
},
|
|
{
|
|
"proposal id is required",
|
|
&group.MsgWithdrawProposal{
|
|
Address: member1.String(),
|
|
},
|
|
true,
|
|
"proposal id: value is empty",
|
|
},
|
|
{
|
|
"valid msg",
|
|
&group.MsgWithdrawProposal{
|
|
Address: member1.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(), sdk.MsgTypeURL(&group.MsgWithdrawProposal{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMsgExec(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
msg *group.MsgExec
|
|
expErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
"invalid signer address",
|
|
&group.MsgExec{
|
|
Executor: "signer",
|
|
},
|
|
true,
|
|
"signer: decoding bech32 failed",
|
|
},
|
|
{
|
|
"proposal is required",
|
|
&group.MsgExec{
|
|
Executor: admin.String(),
|
|
},
|
|
true,
|
|
"proposal id: value is empty",
|
|
},
|
|
{
|
|
"valid testcase",
|
|
&group.MsgExec{
|
|
Executor: 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(), sdk.MsgTypeURL(&group.MsgExec{}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMsgLeaveGroup(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
msg *group.MsgLeaveGroup
|
|
expErr bool
|
|
errMsg string
|
|
}{
|
|
{
|
|
"invalid group member address",
|
|
&group.MsgLeaveGroup{
|
|
Address: "member",
|
|
},
|
|
true,
|
|
"group member: decoding bech32 failed",
|
|
},
|
|
{
|
|
"group id is required",
|
|
&group.MsgLeaveGroup{
|
|
Address: admin.String(),
|
|
},
|
|
true,
|
|
"group-id: value is empty",
|
|
},
|
|
{
|
|
"valid testcase",
|
|
&group.MsgLeaveGroup{
|
|
Address: admin.String(),
|
|
GroupId: 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(), sdk.MsgTypeURL(&group.MsgLeaveGroup{}))
|
|
}
|
|
})
|
|
}
|
|
}
|