Skip to content

Commit e19b587

Browse files
authored
test(mstaking): implement StakeAuthorization tests
Implements comprehensive test suite for StakeAuthorization in the mstaking module. The tests cover: - Creation of new StakeAuthorization objects - Basic validation of authorization parameters - Message acceptance logic with allow/deny lists - Token limit validation and state updates - Message type URL handling for different authorization types This improves the overall test coverage and helps ensure the reliability of the staking authorization functionality.
1 parent f2cebe1 commit e19b587

File tree

1 file changed

+272
-1
lines changed

1 file changed

+272
-1
lines changed

Diff for: x/mstaking/types/authz_test.go

+272-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,274 @@
11
package types_test
22

3-
// TODO implement test
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
sdk "github.com/cosmos/cosmos-sdk/types"
10+
"github.com/cosmos/cosmos-sdk/x/authz"
11+
12+
"github.com/initia-labs/initia/x/mstaking/types"
13+
)
14+
15+
func TestNewStakeAuthorization(t *testing.T) {
16+
tests := []struct {
17+
name string
18+
allowedValidators []string
19+
deniedValidators []string
20+
authzType types.AuthorizationType
21+
amount sdk.Coins
22+
expectError bool
23+
}{
24+
{
25+
name: "valid authorization with allow list",
26+
allowedValidators: []string{"val1", "val2"},
27+
deniedValidators: nil,
28+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
29+
amount: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
30+
expectError: false,
31+
},
32+
{
33+
name: "valid authorization with deny list",
34+
allowedValidators: nil,
35+
deniedValidators: []string{"val1", "val2"},
36+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
37+
amount: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
38+
expectError: false,
39+
},
40+
}
41+
42+
for _, tc := range tests {
43+
t.Run(tc.name, func(t *testing.T) {
44+
authorization, err := types.NewStakeAuthorization(
45+
tc.allowedValidators,
46+
tc.deniedValidators,
47+
tc.authzType,
48+
tc.amount,
49+
)
50+
51+
if tc.expectError {
52+
require.Error(t, err)
53+
return
54+
}
55+
56+
require.NoError(t, err)
57+
require.NotNil(t, authorization)
58+
59+
if tc.allowedValidators != nil {
60+
require.NotNil(t, authorization.GetAllowList())
61+
require.Equal(t, tc.allowedValidators, authorization.GetAllowList().Address)
62+
}
63+
64+
if tc.deniedValidators != nil {
65+
require.NotNil(t, authorization.GetDenyList())
66+
require.Equal(t, tc.deniedValidators, authorization.GetDenyList().Address)
67+
}
68+
69+
require.Equal(t, tc.authzType, authorization.AuthorizationType)
70+
if tc.amount != nil {
71+
require.Equal(t, tc.amount, authorization.MaxTokens)
72+
}
73+
})
74+
}
75+
}
76+
77+
func TestStakeAuthorization_ValidateBasic(t *testing.T) {
78+
tests := []struct {
79+
name string
80+
auth types.StakeAuthorization
81+
expectError bool
82+
}{
83+
{
84+
name: "valid authorization",
85+
auth: types.StakeAuthorization{
86+
MaxTokens: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
87+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
88+
},
89+
expectError: false,
90+
},
91+
{
92+
name: "invalid - negative coins",
93+
auth: types.StakeAuthorization{
94+
MaxTokens: sdk.Coins{sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-1000)}},
95+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
96+
},
97+
expectError: true,
98+
},
99+
{
100+
name: "invalid - unspecified authorization type",
101+
auth: types.StakeAuthorization{
102+
MaxTokens: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
103+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED,
104+
},
105+
expectError: true,
106+
},
107+
}
108+
109+
for _, tc := range tests {
110+
t.Run(tc.name, func(t *testing.T) {
111+
err := tc.auth.ValidateBasic()
112+
if tc.expectError {
113+
require.Error(t, err)
114+
} else {
115+
require.NoError(t, err)
116+
}
117+
})
118+
}
119+
}
120+
121+
func TestStakeAuthorization_Accept(t *testing.T) {
122+
ctx := sdk.Context{}.WithGasMeter(sdk.NewInfiniteGasMeter())
123+
124+
tests := []struct {
125+
name string
126+
auth types.StakeAuthorization
127+
msg sdk.Msg
128+
expectError bool
129+
}{
130+
{
131+
name: "valid delegate with allow list",
132+
auth: types.StakeAuthorization{
133+
Validators: &types.StakeAuthorization_AllowList{
134+
AllowList: &types.StakeAuthorization_Validators{
135+
Address: []string{"val1"},
136+
},
137+
},
138+
MaxTokens: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
139+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
140+
},
141+
msg: &types.MsgDelegate{
142+
DelegatorAddress: "delegator",
143+
ValidatorAddress: "val1",
144+
Amount: sdk.NewCoin("stake", sdk.NewInt(500)),
145+
},
146+
expectError: false,
147+
},
148+
{
149+
name: "invalid - validator not in allow list",
150+
auth: types.StakeAuthorization{
151+
Validators: &types.StakeAuthorization_AllowList{
152+
AllowList: &types.StakeAuthorization_Validators{
153+
Address: []string{"val1"},
154+
},
155+
},
156+
MaxTokens: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
157+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
158+
},
159+
msg: &types.MsgDelegate{
160+
DelegatorAddress: "delegator",
161+
ValidatorAddress: "val2",
162+
Amount: sdk.NewCoin("stake", sdk.NewInt(500)),
163+
},
164+
expectError: true,
165+
},
166+
{
167+
name: "invalid - validator in deny list",
168+
auth: types.StakeAuthorization{
169+
Validators: &types.StakeAuthorization_DenyList{
170+
DenyList: &types.StakeAuthorization_Validators{
171+
Address: []string{"val1"},
172+
},
173+
},
174+
MaxTokens: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000))),
175+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
176+
},
177+
msg: &types.MsgDelegate{
178+
DelegatorAddress: "delegator",
179+
ValidatorAddress: "val1",
180+
Amount: sdk.NewCoin("stake", sdk.NewInt(500)),
181+
},
182+
expectError: true,
183+
},
184+
{
185+
name: "invalid - exceeds max tokens",
186+
auth: types.StakeAuthorization{
187+
Validators: &types.StakeAuthorization_AllowList{
188+
AllowList: &types.StakeAuthorization_Validators{
189+
Address: []string{"val1"},
190+
},
191+
},
192+
MaxTokens: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(400))),
193+
AuthorizationType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
194+
},
195+
msg: &types.MsgDelegate{
196+
DelegatorAddress: "delegator",
197+
ValidatorAddress: "val1",
198+
Amount: sdk.NewCoin("stake", sdk.NewInt(500)),
199+
},
200+
expectError: true,
201+
},
202+
}
203+
204+
for _, tc := range tests {
205+
t.Run(tc.name, func(t *testing.T) {
206+
resp, err := tc.auth.Accept(context.Background(), tc.msg)
207+
if tc.expectError {
208+
require.Error(t, err)
209+
return
210+
}
211+
212+
require.NoError(t, err)
213+
require.True(t, resp.Accept)
214+
215+
// Check if authorization should be deleted (when max tokens are used up)
216+
if tc.auth.MaxTokens != nil {
217+
msgCoins := sdk.NewCoins(tc.msg.(*types.MsgDelegate).Amount)
218+
if tc.auth.MaxTokens.IsEqual(msgCoins) {
219+
require.True(t, resp.Delete)
220+
}
221+
}
222+
})
223+
}
224+
}
225+
226+
func TestStakeAuthorization_MsgTypeURL(t *testing.T) {
227+
tests := []struct {
228+
name string
229+
authzType types.AuthorizationType
230+
expectError bool
231+
}{
232+
{
233+
name: "delegate authorization",
234+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE,
235+
expectError: false,
236+
},
237+
{
238+
name: "undelegate authorization",
239+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE,
240+
expectError: false,
241+
},
242+
{
243+
name: "redelegate authorization",
244+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE,
245+
expectError: false,
246+
},
247+
{
248+
name: "cancel unbonding delegation authorization",
249+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION,
250+
expectError: false,
251+
},
252+
{
253+
name: "unspecified authorization type",
254+
authzType: types.AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED,
255+
expectError: true,
256+
},
257+
}
258+
259+
for _, tc := range tests {
260+
t.Run(tc.name, func(t *testing.T) {
261+
auth := types.StakeAuthorization{
262+
AuthorizationType: tc.authzType,
263+
}
264+
265+
if tc.expectError {
266+
require.Panics(t, func() { auth.MsgTypeURL() })
267+
return
268+
}
269+
270+
url := auth.MsgTypeURL()
271+
require.NotEmpty(t, url)
272+
})
273+
}
274+
}

0 commit comments

Comments
 (0)