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}