Search Apps Documentation Source Content File Folder Download Copy Actions Download

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*/