ownable_test.gno
5.36 Kb · 225 lines
1package ownable
2
3import (
4 "chain/runtime"
5 "testing"
6
7 "gno.land/p/nt/testutils/v0"
8 "gno.land/p/nt/uassert/v0"
9 "gno.land/p/nt/urequire/v0"
10)
11
12var (
13 alice = testutils.TestAddress("alice")
14 bob = testutils.TestAddress("bob")
15)
16
17func TestNew(t *testing.T) {
18 testing.SetRealm(testing.NewCodeRealm("gno.land/r/test/test"))
19 current := runtime.CurrentRealm().Address()
20
21 o := New()
22 got := o.Owner()
23 uassert.Equal(t, got, current)
24}
25
26func TestNewWithOriginPanic(t *testing.T) {
27 testing.SetOriginCaller(alice)
28 testing.SetRealm(testing.NewUserRealm(alice))
29
30 uassert.PanicsWithMessage(t, "frame not found: cannot seek beyond origin caller override", func() {
31 NewWithOrigin()
32 })
33}
34
35func TestNewWithOrigin(t *testing.T) {
36 testing.SetRealm(testing.NewUserRealm(alice))
37 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
38 // This is the only way to test crosses from a p package for now.
39 o := NewWithOrigin()
40 got := o.Owner()
41 uassert.Equal(t, got, alice)
42 })
43}
44
45func TestNewWithAddress(t *testing.T) {
46 o := NewWithAddress(alice)
47
48 got := o.Owner()
49 uassert.Equal(t, got, alice)
50}
51
52func TestNewWithAddressByPrevious(t *testing.T) {
53 o := NewWithAddressByPrevious(alice)
54
55 got := o.Owner()
56 uassert.Equal(t, got, alice)
57}
58
59func TestTransferOwnership(t *testing.T) {
60 testing.SetRealm(testing.NewUserRealm(alice))
61
62 o := New()
63 err := o.TransferOwnership(bob)
64 urequire.NoError(t, err)
65
66 got := o.Owner()
67 uassert.Equal(t, got, bob)
68}
69
70func TestTransferOwnershipByPrevious(t *testing.T) {
71 var o *Ownable
72
73 testing.SetRealm(testing.NewUserRealm(alice))
74 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
75 o = NewWithOrigin()
76 })
77
78 testing.SetRealm(testing.NewUserRealm(alice))
79 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
80 err := o.TransferOwnership(bob)
81 urequire.NoError(t, err)
82 })
83
84 got := o.Owner()
85 uassert.Equal(t, got, bob)
86}
87
88func TestTransferOwnershipUnauthorized(t *testing.T) {
89 var o *Ownable
90
91 testing.SetRealm(testing.NewUserRealm(alice))
92 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
93 o = NewWithOrigin() // owned by alice, previous-mode
94 })
95
96 // Bob cannot transfer ownership.
97 testing.SetRealm(testing.NewUserRealm(bob))
98 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
99 uassert.ErrorContains(t, o.TransferOwnership(bob), ErrUnauthorized.Error())
100 })
101}
102
103func TestDropOwnership(t *testing.T) {
104 testing.SetRealm(testing.NewUserRealm(alice))
105
106 o := New()
107
108 err := o.DropOwnership()
109 urequire.NoError(t, err, "DropOwnership failed")
110
111 owner := o.Owner()
112 uassert.Empty(t, owner, "owner should be empty")
113}
114
115func TestDropOwnershipByPrevious(t *testing.T) {
116 var o *Ownable
117
118 testing.SetRealm(testing.NewUserRealm(alice))
119 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
120 o = NewWithOrigin()
121 })
122
123 testing.SetRealm(testing.NewUserRealm(alice))
124 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
125 err := o.DropOwnership()
126 urequire.NoError(t, err, "DropOwnership failed")
127 })
128
129 owner := o.Owner()
130 uassert.Empty(t, owner, "owner should be empty")
131}
132
133func TestDropOwnershipUnauthorized(t *testing.T) {
134 var o *Ownable
135
136 testing.SetRealm(testing.NewUserRealm(alice))
137 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
138 o = NewWithOrigin() // owned by alice
139 })
140
141 testing.SetRealm(testing.NewUserRealm(bob))
142 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
143 uassert.ErrorContains(t, o.DropOwnership(), ErrUnauthorized.Error())
144 })
145}
146
147func TestOwned(t *testing.T) {
148 // Current-mode.
149 testing.SetRealm(testing.NewUserRealm(alice))
150 o := New()
151 uassert.True(t, o.Owned())
152
153 testing.SetRealm(testing.NewUserRealm(bob))
154 uassert.False(t, o.Owned())
155
156 // Previous-mode.
157 var po *Ownable
158 testing.SetRealm(testing.NewUserRealm(alice))
159 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
160 po = NewWithOrigin()
161 })
162
163 // Previous-mode Owned() requires a cross-realm context (PreviousRealm() is only
164 // meaningful when called from a crossing function).
165 testing.SetRealm(testing.NewUserRealm(alice))
166 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
167 uassert.True(t, po.Owned())
168 })
169 testing.SetRealm(testing.NewUserRealm(bob))
170 crossThrough(testing.NewCodeRealm("gno.land/r/test/test"), func() {
171 uassert.False(t, po.Owned())
172 })
173}
174
175func TestAssertOwned(t *testing.T) {
176 testing.SetRealm(testing.NewUserRealm(alice))
177 o := New()
178
179 // Should not panic.
180 o.AssertOwned()
181
182 testing.SetRealm(testing.NewUserRealm(bob))
183 uassert.PanicsWithMessage(t, ErrUnauthorized.Error(), func() {
184 o.AssertOwned()
185 })
186}
187
188func TestErrInvalidAddress(t *testing.T) {
189 testing.SetRealm(testing.NewCodeRealm("gno.land/r/test/test"))
190
191 o := New()
192 err := o.TransferOwnership("")
193 uassert.ErrorContains(t, err, ErrInvalidAddress.Error())
194
195 err = o.TransferOwnership("10000000001000000000100000000010000000001000000000")
196 uassert.ErrorContains(t, err, ErrInvalidAddress.Error())
197}
198
199func TestNilReceiver(t *testing.T) {
200 var o *Ownable
201
202 owner := o.Owner()
203 if owner != address("") {
204 t.Errorf("expected empty address but got %v", owner)
205 }
206
207 isOwner := o.Owned()
208 uassert.False(t, isOwner)
209
210 defer func() {
211 r := recover()
212 if r == nil {
213 t.Error("expected panic but got none")
214 }
215 if r != ErrUnauthorized {
216 t.Errorf("expected ErrUnauthorized but got %v", r)
217 }
218 }()
219 o.AssertOwned()
220}
221
222func crossThrough(rlm runtime.Realm, cr func()) {
223 testing.SetRealm(rlm)
224 cr()
225}