ownable_test.gno
5.09 Kb ยท 210 lines
1package ownable
2
3import (
4 "std"
5 "testing"
6
7 "gno.land/p/nt/testutils"
8 "gno.land/p/nt/uassert"
9 "gno.land/p/nt/urequire"
10)
11
12var (
13 alice = testutils.TestAddress("alice")
14 bob = testutils.TestAddress("bob")
15)
16
17func TestNew(t *testing.T) {
18 testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test"))
19 current := std.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(std.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(std.NewUserRealm(alice))
37 crossThrough(std.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 TestTransferOwnership(t *testing.T) {
53 testing.SetRealm(std.NewUserRealm(alice))
54
55 o := New()
56 err := o.TransferOwnership(bob)
57 urequire.NoError(t, err)
58
59 got := o.Owner()
60 uassert.Equal(t, got, bob)
61}
62
63func TestTransferOwnershipUnauthorized(t *testing.T) {
64 var o *Ownable
65
66 testing.SetRealm(std.NewUserRealm(alice))
67 crossThrough(std.NewCodeRealm("gno.land/r/test/test"), func() {
68 o = NewWithOrigin() // owned by alice
69 })
70
71 // Try unauthorized transfer from non-alice realm.
72 crossThrough(std.NewCodeRealm("gno.land/r/test/test"), func() {
73 uassert.ErrorContains(t, o.TransferOwnership(alice), ErrUnauthorized.Error())
74 uassert.ErrorContains(t, o.DropOwnershipByCurrent(), ErrUnauthorized.Error())
75 })
76
77 // Set realm to an unauthorized user bob.
78 testing.SetRealm(std.NewUserRealm(bob))
79 // current is gno.land/r/test/test so of course errors.
80 uassert.ErrorContains(t, o.TransferOwnership(bob), ErrUnauthorized.Error())
81 uassert.ErrorContains(t, o.DropOwnershipByCurrent(), ErrUnauthorized.Error())
82 // Reset realm to alice.
83 testing.SetRealm(std.NewUserRealm(alice))
84 uassert.NoError(t, o.TransferOwnership(alice))
85 uassert.NoError(t, o.DropOwnershipByCurrent())
86}
87
88func TestOwnedByCurrent(t *testing.T) {
89 testing.SetRealm(std.NewUserRealm(alice))
90 o := New()
91 uassert.True(t, o.OwnedByCurrent())
92}
93
94func TestOwnedByCurrentUnauthorized(t *testing.T) {
95 testing.SetOriginCaller(alice)
96 testing.SetRealm(std.NewUserRealm(alice))
97
98 var o *Ownable
99 crossThrough(std.NewCodeRealm("gno.land/r/test/test"), func() {
100 o = NewWithOrigin()
101 })
102
103 uassert.True(t, o.OwnedByCurrent())
104
105 unauthorizedCaller := bob
106 testing.SetRealm(std.NewUserRealm(unauthorizedCaller))
107 uassert.False(t, o.OwnedByCurrent())
108}
109
110func TestOwnedByPrevious(t *testing.T) {
111 testing.SetRealm(std.NewUserRealm(alice))
112 o := New()
113
114 crossThrough(std.NewCodeRealm("gno.land/r/test/test"), func() {
115 uassert.True(t, o.OwnedByPrevious())
116 })
117}
118
119func TestOwnedByPreviousUnauthorized(t *testing.T) {
120 testing.SetRealm(std.NewUserRealm(alice))
121 o := New()
122
123 unauthorizedCaller := bob
124 testing.SetRealm(std.NewUserRealm(unauthorizedCaller))
125 crossThrough(std.NewCodeRealm("gno.land/r/test/test"), func() {
126 uassert.False(t, o.OwnedByPrevious())
127 })
128}
129
130func TestDropOwnershipByCurrent(t *testing.T) {
131 testing.SetRealm(std.NewUserRealm(alice))
132
133 o := New()
134
135 err := o.DropOwnershipByCurrent()
136 urequire.NoError(t, err, "DropOwnership failed")
137
138 owner := o.Owner()
139 uassert.Empty(t, owner, "owner should be empty")
140}
141
142func TestErrInvalidAddress(t *testing.T) {
143 testing.SetRealm(std.NewCodeRealm("gno.land/r/test/test"))
144
145 o := New()
146 err := o.TransferOwnership("")
147 uassert.ErrorContains(t, err, ErrInvalidAddress.Error())
148
149 err = o.TransferOwnership("10000000001000000000100000000010000000001000000000")
150 uassert.ErrorContains(t, err, ErrInvalidAddress.Error())
151}
152
153func TestAssertOwnedByCurrent(t *testing.T) {
154 testing.SetRealm(std.NewUserRealm(alice))
155
156 o := New()
157
158 // Should not panic when caller is owner
159 o.AssertOwnedByCurrent()
160
161 // Should panic when caller is not owner
162 testing.SetRealm(std.NewUserRealm(bob))
163 uassert.PanicsWithMessage(t, ErrUnauthorized.Error(), func() {
164 o.AssertOwnedByCurrent()
165 })
166}
167
168func TestAssertOwnedByPrevious(t *testing.T) {
169 testing.SetRealm(std.NewUserRealm(alice))
170
171 o := New()
172 crossThrough(std.NewCodeRealm("gno.land/r/test/test"), func() {
173 // Should not panic when previous is owner
174 o.AssertOwnedByPrevious()
175
176 // Should panic when previous is not owner
177 testing.SetRealm(std.NewUserRealm(bob))
178 uassert.PanicsWithMessage(t, ErrUnauthorized.Error(), func() {
179 o.AssertOwnedByCurrent()
180 })
181 })
182}
183
184func TestNilReceiver(t *testing.T) {
185 var o *Ownable
186
187 owner := o.Owner()
188 if owner != std.Address("") {
189 t.Errorf("expected empty address but got %v", owner)
190 }
191
192 isOwner := o.OwnedByPrevious()
193 uassert.False(t, isOwner)
194
195 defer func() {
196 r := recover()
197 if r == nil {
198 t.Error("expected panic but got none")
199 }
200 if r != ErrUnauthorized {
201 t.Errorf("expected ErrUnauthorized but got %v", r)
202 }
203 }()
204 o.AssertOwnedByPrevious()
205}
206
207func crossThrough(rlm std.Realm, cr func()) {
208 testing.SetRealm(rlm)
209 cr()
210}