mgroup_test.gno
10.43 Kb ยท 376 lines
1package mgroup
2
3import (
4 "testing"
5
6 "gno.land/p/nt/avl"
7 "gno.land/p/nt/ownable"
8 "gno.land/p/nt/uassert"
9)
10
11func TestManagedGroup(t *testing.T) {
12 u1 := testing.NewCodeRealm("gno.land/r/test/test/u1")
13 u2 := testing.NewCodeRealm("gno.land/r/test/test/u2")
14 u3 := testing.NewCodeRealm("gno.land/r/test/test/u3")
15 u4 := testing.NewCodeRealm("gno.land/r/test/test/u4")
16
17 // testUsingPreviousRealm sets the realm to "gno.land/r/test/test"
18 // and uses the SetRealm in the test as the previous caller
19 testUsingPreviousRealm := func(fn func()) {
20 testing.SetRealm(testing.NewCodeRealm("gno.land/r/test/test"))
21 fn()
22 }
23
24 t.Run("AddBackupOwner", func(t *testing.T) {
25 g := New(u1.Address())
26
27 testing.SetRealm(u1)
28 testUsingPreviousRealm(func() {
29 if err := g.AddBackupOwner(u2.Address()); err != nil {
30 t.Errorf("expected nil, got %v", err.Error())
31 }
32 // ensure invalid address is caught
33 var badAddr address
34 if err := g.AddBackupOwner(badAddr); err != ErrInvalidAddress {
35 t.Errorf("expected %v, got %v", ErrInvalidAddress.Error(), err.Error())
36 }
37 })
38
39 testing.SetRealm(u3)
40 testUsingPreviousRealm(func() {
41 // an address that is not the owner should not be allowed to add a backup owner
42 if err := g.AddBackupOwner(u4.Address()); err != ownable.ErrUnauthorized {
43 t.Errorf("expected %v, got %v", ownable.ErrUnauthorized, err.Error())
44 }
45 })
46
47 })
48 t.Run("RemoveBackupOwner", func(t *testing.T) {
49 g := New(u1.Address())
50
51 testing.SetRealm(u1)
52 testUsingPreviousRealm(func() {
53 g.AddBackupOwner(u2.Address())
54 if err := g.RemoveBackupOwner(u2.Address()); err != nil {
55 t.Errorf("expected nil, got %v", err.Error())
56 }
57 // running this twice should not error.
58 if err := g.RemoveBackupOwner(u2.Address()); err != nil {
59 t.Errorf("expected nil, got %v", err.Error())
60 }
61 var badAddr address
62 if err := g.RemoveBackupOwner(badAddr); err != ErrInvalidAddress {
63 t.Errorf("expected %v, got %v", ErrInvalidAddress.Error(), err.Error())
64 }
65 if err := g.RemoveBackupOwner(u1.Address()); err != ErrCannotRemoveOwner {
66 t.Errorf("expected %v, got %v", ErrCannotRemoveOwner.Error(), err.Error())
67 }
68 })
69
70 testing.SetRealm(u3)
71 testUsingPreviousRealm(func() {
72 g.AddBackupOwner(u2.Address())
73 if err := g.RemoveBackupOwner(u2.Address()); err != ownable.ErrUnauthorized {
74 t.Errorf("expected %v, got %v", ownable.ErrUnauthorized, err.Error())
75 }
76 })
77 })
78
79 t.Run("ClaimOwnership", func(t *testing.T) {
80 g := New(u1.Address())
81
82 testing.SetRealm(u1)
83 testUsingPreviousRealm(func() {
84 g.AddBackupOwner(u2.Address())
85 })
86 testing.SetRealm(u2)
87 testUsingPreviousRealm(func() {
88 if err := g.ClaimOwnership(); err != nil {
89 t.Errorf("expected nil, got %v", err.Error())
90 }
91 if g.Owner() != u2.Address() {
92 t.Errorf("expected %v, got %v", u2, g.Owner())
93 }
94 if !g.IsMember(u2.Address()) {
95 t.Errorf("expected %v to be a member", u2)
96 }
97 if err := g.ClaimOwnership(); err != nil {
98 t.Errorf("expected nil, got %v", err.Error())
99 }
100 })
101 testing.SetRealm(u3)
102 testUsingPreviousRealm(func() {
103 if err := g.ClaimOwnership(); err != ErrNotMember {
104 t.Errorf("expected %v, got %v", ErrNotMember.Error(), err.Error())
105 }
106 })
107 })
108
109 t.Run("AddMember", func(t *testing.T) {
110 g := New(u1.Address())
111 testing.SetRealm(u1)
112 testUsingPreviousRealm(func() {
113 if err := g.AddMember(u2.Address()); err != nil {
114 t.Errorf("expected nil, got %v", err.Error())
115 }
116 if !g.IsMember(u2.Address()) {
117 t.Errorf("expected %v to be a member", u2)
118 }
119 var badAddr address
120 if err := g.AddMember(badAddr); err != ErrInvalidAddress {
121 t.Errorf("expected %v, got %v", ErrInvalidAddress, err.Error())
122 }
123 })
124 testing.SetRealm(u3)
125 testUsingPreviousRealm(func() {
126 if err := g.AddMember(u4.Address()); err != ownable.ErrUnauthorized {
127 t.Errorf("expected %v, got %v", ownable.ErrUnauthorized, err.Error())
128 }
129 })
130 })
131
132 t.Run("RemoveMember", func(t *testing.T) {
133 g := New(u1.Address())
134
135 testing.SetRealm(u1)
136 testUsingPreviousRealm(func() {
137 g.AddMember(u2.Address())
138 if err := g.RemoveMember(u2.Address()); err != nil {
139 t.Errorf("expected nil, got %v", err.Error())
140 }
141 if g.IsMember(u2.Address()) {
142 t.Errorf("expected %v to not be a member", u2)
143 }
144 // running this twice should not error
145 if err := g.RemoveMember(u2.Address()); err != nil {
146 t.Errorf("expected nil, got %v", err.Error())
147 }
148 var badAddr address
149 if err := g.RemoveMember(badAddr); err != ErrInvalidAddress {
150 t.Errorf("expected %v, got %v", ErrInvalidAddress.Error(), err.Error())
151 }
152 if err := g.RemoveMember(u1.Address()); err != ErrCannotRemoveOwner {
153 t.Errorf("expected %v, got %v", ErrCannotRemoveOwner.Error(), err.Error())
154 }
155 })
156
157 testing.SetRealm(u2)
158 testUsingPreviousRealm(func() {
159 if err := g.RemoveMember(u3.Address()); err != ownable.ErrUnauthorized {
160 t.Errorf("expected %v, got %v", ownable.ErrUnauthorized.Error(), err.Error())
161 }
162 })
163 })
164
165 t.Run("MemberCount", func(t *testing.T) {
166 g := New(u1.Address())
167 testing.SetRealm(u1)
168 testUsingPreviousRealm(func() {
169 uassert.Equal(t, 1, g.MemberCount())
170 g.AddMember(u2.Address())
171 uassert.Equal(t, 2, g.MemberCount())
172 g.AddMember(u3.Address())
173 uassert.Equal(t, 3, g.MemberCount())
174 g.RemoveMember(u2.Address())
175 uassert.Equal(t, 2, g.MemberCount())
176 })
177 })
178
179 t.Run("BackupOwnerCount", func(t *testing.T) {
180 g := New(u1.Address())
181 testing.SetRealm(u1)
182 testUsingPreviousRealm(func() {
183 uassert.Equal(t, 1, g.BackupOwnerCount())
184 g.AddBackupOwner(u2.Address())
185 uassert.Equal(t, 2, g.BackupOwnerCount())
186 g.AddBackupOwner(u3.Address())
187 uassert.Equal(t, 3, g.BackupOwnerCount())
188 g.RemoveBackupOwner(u2.Address())
189 uassert.Equal(t, 2, g.BackupOwnerCount())
190 })
191 })
192
193 t.Run("IsMember", func(t *testing.T) {
194 g := New(u1.Address())
195 testing.SetRealm(u1)
196 testUsingPreviousRealm(func() {
197 if !g.IsMember(u1.Address()) {
198 t.Errorf("expected %v to be a member", u1)
199 }
200 if g.IsMember(u2.Address()) {
201 t.Errorf("expected %v to not be a member", u2)
202 }
203 g.AddMember(u2.Address())
204 if !g.IsMember(u2.Address()) {
205 t.Errorf("expected %v to be a member", u2)
206 }
207 })
208 })
209 t.Run("IsBackupOwner", func(t *testing.T) {
210 g := New(u1.Address())
211 testing.SetRealm(u1)
212 testUsingPreviousRealm(func() {
213 if !g.IsBackupOwner(u1.Address()) {
214 t.Errorf("expected %v to be a backup owner", u1)
215 }
216 if g.IsBackupOwner(u2.Address()) {
217 t.Errorf("expected %v to not be a backup owner", u2)
218 }
219 g.AddBackupOwner(u2.Address())
220 if !g.IsBackupOwner(u2.Address()) {
221 t.Errorf("expected %v to be a backup owner", u2)
222 }
223 })
224 })
225
226 t.Run("Owner", func(t *testing.T) {
227 g := New(u1.Address())
228 testing.SetRealm(u1)
229 testUsingPreviousRealm(func() {
230 if g.Owner() != u1.Address() {
231 t.Errorf("expected %v, got %v", u1, g.Owner())
232 }
233 g.AddBackupOwner(u2.Address())
234 if g.Owner() != u1.Address() {
235 t.Errorf("expected %v, got %v", u1, g.Owner())
236 }
237 })
238 testing.SetRealm(u2)
239 testUsingPreviousRealm(func() {
240 g.ClaimOwnership()
241 if g.Owner() != u2.Address() {
242 t.Errorf("expected %v, got %v", u2, g.Owner())
243 }
244 })
245 })
246 t.Run("BackupOwners", func(t *testing.T) {
247 g := New(u1.Address())
248 testing.SetRealm(u1)
249 testUsingPreviousRealm(func() {
250 g.AddBackupOwner(u2.Address())
251 g.AddBackupOwner(u3.Address())
252 owners := g.BackupOwners()
253 if len(owners) != 3 {
254 t.Errorf("expected 3, got %v", len(owners))
255 }
256 if owners[0] != u1.Address().String() {
257 t.Errorf("expected %v, got %v", u1, owners[0])
258 }
259 if owners[1] != u2.Address().String() {
260 t.Errorf("expected %v, got %v", u2, owners[1])
261 }
262 if owners[2] != u3.Address().String() {
263 t.Errorf("expected %v, got %v", u3, owners[1])
264 }
265 })
266 })
267 t.Run("Members", func(t *testing.T) {
268 g := New(u1.Address())
269 testing.SetRealm(u1)
270 testUsingPreviousRealm(func() {
271 g.AddMember(u2.Address())
272 g.AddMember(u3.Address())
273 members := g.Members()
274 if len(members) != 3 {
275 t.Errorf("expected 3, got %v", len(members))
276 }
277 if members[0] != u1.Address().String() {
278 t.Errorf("expected %v, got %v", u1, members[0])
279 }
280 if members[1] != u2.Address().String() {
281 t.Errorf("expected %v, got %v", u2, members[1])
282 }
283 if members[2] != u3.Address().String() {
284 t.Errorf("expected %v, got %v", u3, members[1])
285 }
286 })
287 })
288}
289
290func TestSliceWithOffset(t *testing.T) {
291 testTable := []struct {
292 name string
293 slice []string
294 offset int
295 count int
296 expected []string
297 expectedCount int
298 }{
299 {
300 name: "empty",
301 slice: []string{},
302 offset: 0,
303 count: 0,
304 expected: []string{},
305 expectedCount: 0,
306 },
307 {
308 name: "single",
309 slice: []string{"a"},
310 offset: 0,
311 count: 1,
312 expected: []string{"a"},
313 expectedCount: 1,
314 },
315 {
316 name: "single offset",
317 slice: []string{"a"},
318 offset: 1,
319 count: 1,
320 expected: []string{},
321 expectedCount: 0,
322 },
323 {
324 name: "multiple",
325 slice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
326 offset: 0,
327 count: 10,
328 expected: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
329 expectedCount: 10,
330 },
331 {
332 name: "multiple offset",
333 slice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
334 offset: 5,
335 count: 5,
336 expected: []string{"f", "g", "h", "i", "j"},
337 expectedCount: 5,
338 },
339 {
340 name: "multiple offset end",
341 slice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
342 offset: 10,
343 count: 5,
344 expected: []string{},
345 expectedCount: 0,
346 },
347 {
348 name: "multiple offset past end",
349 slice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
350 offset: 11,
351 count: 5,
352 expected: []string{},
353 expectedCount: 0,
354 },
355 {
356 name: "multiple offset count past end",
357 slice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"},
358 offset: 5,
359 count: 20,
360 expected: []string{"f", "g", "h", "i", "j"},
361 expectedCount: 5,
362 },
363 }
364 for _, test := range testTable {
365 t.Run(test.name, func(t *testing.T) {
366 tree := avl.NewTree()
367 for _, s := range test.slice {
368 tree.Set(s, struct{}{})
369 }
370 slice := sliceWithOffset(tree, test.offset, test.count)
371 if len(slice) != test.expectedCount {
372 t.Errorf("expected %v, got %v", test.expectedCount, len(slice))
373 }
374 })
375 }
376}