proposal_test.gno
7.34 Kb ยท 254 lines
1package proposal
2
3import (
4 "chain"
5 "testing"
6
7 "gno.land/p/nt/testutils"
8 "gno.land/p/nt/ufmt"
9 "gno.land/p/nt/urequire"
10 "gno.land/r/gnops/valopers"
11 "gno.land/r/gov/dao"
12 daoinit "gno.land/r/gov/dao/v3/init" // so that the govdao initializer is executed
13 susers "gno.land/r/sys/users"
14)
15
16var g1user = testutils.TestAddress("g1user")
17
18func init() {
19 daoinit.InitWithUsers(g1user)
20 registerTestUsers(g1user)
21}
22
23const gUsersV1Path = "gno.land/r/gnoland/users/v1"
24
25// Register a namespace for every addresses
26// Necessary to test GovDAO Vote
27func registerTestUsers(addrs ...address) {
28 // Set realm to users admin to register test user
29 testing.SetRealm(testing.NewCodeRealm(gUsersV1Path))
30 for _, addr := range addrs {
31 err := susers.RegisterUser(cross, addr.String()[1:], addr)
32 if err != nil {
33 panic(err.Error() + " : " + addr.String())
34 }
35 }
36}
37
38func TestValopers_ProposeNewValidator(t *testing.T) {
39 const (
40 registerMinFee int64 = 20 * 1_000_000 // minimum gnot must be paid to register.
41 proposalMinFee int64 = 100 * 1_000_000
42
43 moniker string = "moniker"
44 description string = "description"
45 pubKey = "gpub1pggj7ard9eg82cjtv4u52epjx56nzwgjyg9zqwpdwpd0f9fvqla089ndw5g9hcsufad77fml2vlu73fk8q8sh8v72cza5p"
46 )
47
48 // Set origin caller
49 testing.SetRealm(testing.NewUserRealm(g1user))
50
51 t.Run("remove an unexisting validator", func(t *testing.T) {
52 // Send coins to be able to register a valoper
53 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", registerMinFee)})
54
55 urequire.NotPanics(t, func() {
56 valopers.Register(cross, moniker, description, g1user, pubKey)
57 valopers.UpdateKeepRunning(cross, g1user, false)
58 })
59
60 urequire.NotPanics(t, func() {
61 valopers.GetByAddr(g1user)
62 })
63
64 // Send coins to be able to make a proposal
65 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", proposalMinFee)})
66
67 urequire.AbortsWithMessage(t, ErrValidatorMissing.Error(), func(cur realm) {
68 pr := NewValidatorProposalRequest(cur, g1user)
69
70 dao.MustCreateProposal(cross, pr)
71 })
72 })
73
74 t.Run("proposal successfully created", func(t *testing.T) {
75 // Send coins to be able to register a valoper
76 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", registerMinFee)})
77
78 urequire.NotPanics(t, func() {
79 valopers.UpdateKeepRunning(cross, g1user, true)
80 })
81
82 var valoper valopers.Valoper
83
84 urequire.NotPanics(t, func() {
85 valoper = valopers.GetByAddr(g1user)
86 })
87
88 // Send coins to be able to make a proposal
89 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", proposalMinFee)})
90
91 var pid dao.ProposalID
92 urequire.NotPanics(t, func(cur realm) {
93 testing.SetRealm(testing.NewUserRealm(g1user))
94 pr := NewValidatorProposalRequest(cur, g1user)
95
96 pid = dao.MustCreateProposal(cross, pr)
97 })
98
99 proposal, err := dao.GetProposal(cross, pid) // index starts from 0
100 urequire.NoError(t, err, "proposal not found")
101
102 description := ufmt.Sprintf("Valoper profile: [%s](/r/gnops/valopers:%s)\n\n%s",
103 valoper.Moniker,
104 valoper.Address,
105 valoper.Render(),
106 )
107
108 // Check that the proposal is correct
109 urequire.Equal(t, description, proposal.Description())
110 })
111
112 t.Run("try to update a validator with the same values", func(t *testing.T) {
113 // Send coins to be able to register a valoper
114 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", registerMinFee)})
115
116 urequire.NotPanics(t, func() {
117 valopers.GetByAddr(g1user)
118 })
119
120 urequire.NotPanics(t, func() {
121 // Vote the proposal created in the previous test
122 dao.MustVoteOnProposal(cross, dao.VoteRequest{
123 Option: dao.YesVote,
124 ProposalID: dao.ProposalID(0),
125 })
126
127 // Execute the proposal
128 dao.ExecuteProposal(cross, dao.ProposalID(0))
129 })
130
131 // Send coins to be able to make a proposal
132 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", proposalMinFee)})
133
134 urequire.AbortsWithMessage(t, ErrSameValues.Error(), func() {
135 pr := NewValidatorProposalRequest(cross, g1user)
136 dao.MustCreateProposal(cross, pr)
137 })
138 })
139}
140
141func TestValopers_ProposeNewInstructions(t *testing.T) {
142 const proposalMinFee int64 = 100 * 1_000_000
143
144 newInstructions := "new instructions"
145 description := ufmt.Sprintf("Update the instructions to: \n\n%s", newInstructions)
146
147 // Set origin caller
148 testing.SetRealm(testing.NewUserRealm(g1user))
149
150 // Send coins to be able to make a proposal
151 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", proposalMinFee)})
152
153 var pid dao.ProposalID
154 urequire.NotPanics(t, func() {
155 pr := ProposeNewInstructionsProposalRequest(cross, newInstructions)
156
157 pid = dao.MustCreateProposal(cross, pr)
158 })
159
160 proposal, err := dao.GetProposal(cross, pid) // index starts from 0
161 urequire.NoError(t, err, "proposal not found")
162 if proposal == nil {
163 panic("PROPOSAL NOT FOUND")
164 }
165
166 // Check that the proposal is correct
167 urequire.Equal(t, description, proposal.Description())
168}
169
170func TestValopers_ProposeNewMinFee(t *testing.T) {
171 const proposalMinFee int64 = 100 * 1_000_000
172 newMinFee := int64(10)
173 description := ufmt.Sprintf("Update the minimum register fee to: %d ugnot", newMinFee)
174
175 // Set origin caller
176 testing.SetRealm(testing.NewUserRealm(g1user))
177
178 // Send coins to be able to make a proposal
179 testing.SetOriginSend(chain.Coins{chain.NewCoin("ugnot", proposalMinFee)})
180
181 var pid dao.ProposalID
182 urequire.NotPanics(t, func() {
183 pr := ProposeNewMinFeeProposalRequest(cross, newMinFee)
184
185 pid = dao.MustCreateProposal(cross, pr)
186 })
187
188 proposal, err := dao.GetProposal(cross, pid) // index starts from 0
189 urequire.NoError(t, err, "proposal not found")
190 // Check that the proposal is correct
191 urequire.Equal(t, description, proposal.Description())
192}
193
194/* TODO fix this @moul
195func TestValopers_ProposeNewValidator2(t *testing.T) {
196 const (
197 registerMinFee int64 = 20 * 1_000_000 // minimum gnot must be paid to register.
198 proposalMinFee int64 = 100 * 1_000_000
199
200 moniker string = "moniker"
201 description string = "description"
202 pubKey = "gpub1pggj7ard9eg82cjtv4u52epjx56nzwgjyg9zqwpdwpd0f9fvqla089ndw5g9hcsufad77fml2vlu73fk8q8sh8v72cza5p"
203 )
204
205 // Set origin caller
206 testing.SetRealm(std.NewUserRealm(g1user))
207
208 t.Run("create valid proposal", func(t *testing.T) {
209 // Validator exists, should not panic
210 urequire.NotPanics(t, func() {
211 _ = valopers.MustGetValoper(g1user)
212 })
213
214 // Create the proposal
215 urequire.NotPanics(t, func() {
216 cross(valopers.Register)(moniker, description, g1user, pubKey)
217 })
218
219 // Verify proposal details
220 urequire.NotPanics(t, func() {
221 valoper := valopers.MustGetValoper(g1user)
222 urequire.Equal(t, moniker, valoper.Moniker)
223 urequire.Equal(t, description, valoper.Description)
224 })
225 // Execute proposal with admin rights
226 urequire.NotPanics(t, func() {
227 std.TestSetOrigCaller(std.Admin)
228 cross(dao.ExecuteProposal)(dao.ProposalID(0))
229 })
230 // Check if valoper was updated
231 urequire.NotPanics(t, func() {
232 valoper := valopers.MustGetValoper(g1user)
233 urequire.Equal(t, moniker, valoper.Moniker)
234 urequire.Equal(t, description, valoper.Description)
235 })
236
237 // Expect ExecuteProposal to pass
238 urequire.NotPanics(t, func() {
239 cross(dao.ExecuteProposal)(dao.ProposalID(0))
240 })
241 // Check if valoper was updated
242 urequire.NotPanics(t, func() {
243 valoper := valopers.MustGetValoper(g1user)
244 urequire.Equal(t, moniker, valoper.Moniker)
245 urequire.Equal(t, description, valoper.Description)
246 })
247 // Execute proposal with admin rights
248 urequire.NotPanics(t, func() {
249 std.TestSetOrigCaller(std.Admin)
250 cross(dao.ExecuteProposal)(dao.ProposalID(0))
251 })
252 })
253}
254*/