mgroup_test.gno

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