Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

basic_nft_test.gno

11.53 Kb · 376 lines
  1package grc721
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/testutils/v0"
  8	"gno.land/p/nt/uassert/v0"
  9)
 10
 11var (
 12	dummyNFTName   = "DummyNFT"
 13	dummyNFTSymbol = "DNFT"
 14)
 15
 16// The IIFE same-realm cross promotes the test's EOA-origin cur into a
 17// /p/grc721 CodeRealm cur so NewBasicNFT's IsCurrent + non-empty PkgPath
 18// checks pass.
 19func newDummyNFT(_ int, rlm realm) *BasicNFT {
 20	var nft *BasicNFT
 21	func(cur realm) {
 22		nft = NewBasicNFT(0, cur, dummyNFTName, dummyNFTSymbol)
 23	}(cross(rlm))
 24	return nft
 25}
 26
 27func TestNewBasicNFTValidation(cur realm, t *testing.T) {
 28	const (
 29		nameErr   = "invalid token name"
 30		symbolErr = "invalid token symbol"
 31	)
 32
 33	uassert.AbortsContains(t, cur, nameErr, func(cur realm) {
 34		NewBasicNFT(0, cur, "", "OK")
 35	}, "empty name")
 36	uassert.AbortsContains(t, cur, symbolErr, func(cur realm) {
 37		NewBasicNFT(0, cur, "Name", "")
 38	}, "empty symbol")
 39	uassert.AbortsContains(t, cur, nameErr, func(cur realm) {
 40		NewBasicNFT(0, cur, strings.Repeat("a", MaxNameLen+1), "OK")
 41	}, "name too long")
 42	uassert.AbortsContains(t, cur, symbolErr, func(cur realm) {
 43		NewBasicNFT(0, cur, "Name", strings.Repeat("A", MaxSymbolLen+1))
 44	}, "symbol too long")
 45	uassert.AbortsContains(t, cur, nameErr, func(cur realm) {
 46		NewBasicNFT(0, cur, "bad\x01name", "OK")
 47	}, "name with control char")
 48	uassert.AbortsContains(t, cur, symbolErr, func(cur realm) {
 49		NewBasicNFT(0, cur, "Name", "BA.D")
 50	}, "symbol with dot")
 51	uassert.AbortsContains(t, cur, symbolErr, func(cur realm) {
 52		NewBasicNFT(0, cur, "Name", "BA D")
 53	}, "symbol with space")
 54
 55	uassert.NotAborts(t, cur, func(cur realm) {
 56		NewBasicNFT(0, cur, strings.Repeat("a", MaxNameLen), strings.Repeat("A", MaxSymbolLen))
 57	}, "boundary name+symbol should succeed")
 58}
 59
 60func TestNewBasicNFT(cur realm, t *testing.T) {
 61	dummy := newDummyNFT(0, cur)
 62	uassert.True(t, dummy != nil, "should not be nil")
 63}
 64
 65func TestName(cur realm, t *testing.T) {
 66	dummy := newDummyNFT(0, cur)
 67	uassert.True(t, dummy != nil, "should not be nil")
 68
 69	name := dummy.Name()
 70	uassert.Equal(t, dummyNFTName, name)
 71}
 72
 73func TestSymbol(cur realm, t *testing.T) {
 74	dummy := newDummyNFT(0, cur)
 75	uassert.True(t, dummy != nil, "should not be nil")
 76
 77	symbol := dummy.Symbol()
 78	uassert.Equal(t, dummyNFTSymbol, symbol)
 79}
 80
 81func TestTokenCount(cur realm, t *testing.T) {
 82	dummy := newDummyNFT(0, cur)
 83	uassert.True(t, dummy != nil, "should not be nil")
 84
 85	count := dummy.TokenCount()
 86	uassert.Equal(t, int64(0), count)
 87
 88	dummy.mint("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm", TokenID("1"))
 89	dummy.mint("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm", TokenID("2"))
 90
 91	count = dummy.TokenCount()
 92	uassert.Equal(t, int64(2), count)
 93}
 94
 95func TestBalanceOf(cur realm, t *testing.T) {
 96	dummy := newDummyNFT(0, cur)
 97	uassert.True(t, dummy != nil, "should not be nil")
 98
 99	addr1 := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
100	addr2 := address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj")
101
102	balanceAddr1, err := dummy.BalanceOf(addr1)
103	uassert.NoError(t, err, "should not result in error")
104	uassert.Equal(t, int64(0), balanceAddr1)
105
106	dummy.mint(addr1, TokenID("1"))
107	dummy.mint(addr1, TokenID("2"))
108	dummy.mint(addr2, TokenID("3"))
109
110	balanceAddr1, err = dummy.BalanceOf(addr1)
111	uassert.NoError(t, err, "should not result in error")
112
113	balanceAddr2, err := dummy.BalanceOf(addr2)
114	uassert.NoError(t, err, "should not result in error")
115
116	uassert.Equal(t, int64(2), balanceAddr1)
117	uassert.Equal(t, int64(1), balanceAddr2)
118}
119
120func TestOwnerOf(cur realm, t *testing.T) {
121	dummy := newDummyNFT(0, cur)
122	uassert.True(t, dummy != nil, "should not be nil")
123
124	addr1 := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
125	addr2 := address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj")
126
127	owner, err := dummy.OwnerOf(TokenID("invalid"))
128	uassert.Error(t, err, "should not result in error")
129
130	dummy.mint(addr1, TokenID("1"))
131	dummy.mint(addr2, TokenID("2"))
132
133	// Checking for token id "1"
134	owner, err = dummy.OwnerOf(TokenID("1"))
135	uassert.NoError(t, err, "should not result in error")
136	uassert.Equal(t, addr1.String(), owner.String())
137
138	// Checking for token id "2"
139	owner, err = dummy.OwnerOf(TokenID("2"))
140	uassert.NoError(t, err, "should not result in error")
141	uassert.Equal(t, addr2.String(), owner.String())
142}
143
144func TestIsApprovedForAll(cur realm, t *testing.T) {
145	dummy := newDummyNFT(0, cur)
146	uassert.True(t, dummy != nil, "should not be nil")
147
148	addr1 := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
149	addr2 := address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj")
150
151	isApprovedForAll := dummy.IsApprovedForAll(addr1, addr2)
152	uassert.False(t, isApprovedForAll)
153}
154
155func TestSetApprovalForAll(cur realm, t *testing.T) {
156	dummy := newDummyNFT(0, cur)
157	uassert.True(t, dummy != nil, "should not be nil")
158
159	caller := testutils.TestAddress("caller")
160	addr := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
161
162	// Test setting approval to true
163	isApprovedForAll := dummy.IsApprovedForAll(caller, addr)
164	uassert.False(t, isApprovedForAll)
165
166	err := dummy.SetApprovalForAll(caller, addr, true)
167	uassert.NoError(t, err, "should not result in error")
168
169	isApprovedForAll = dummy.IsApprovedForAll(caller, addr)
170	uassert.True(t, isApprovedForAll)
171
172	// Test setting approval to false
173	err = dummy.SetApprovalForAll(caller, addr, false)
174	uassert.NoError(t, err, "should not result in error")
175
176	isApprovedForAll = dummy.IsApprovedForAll(caller, addr)
177	uassert.False(t, isApprovedForAll)
178}
179
180func TestGetApproved(cur realm, t *testing.T) {
181	dummy := newDummyNFT(0, cur)
182	uassert.True(t, dummy != nil, "should not be nil")
183
184	_, err := dummy.GetApproved(TokenID("invalid"))
185	uassert.Error(t, err, "should result in error")
186}
187
188func TestApprove(cur realm, t *testing.T) {
189	alice := testutils.TestAddress("alice")
190
191	dummy := newDummyNFT(0, cur)
192	uassert.True(t, dummy != nil, "should not be nil")
193
194	addr := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
195
196	err := dummy.mint(alice, TokenID("1"))
197	uassert.NoError(t, err, "failed to mint")
198
199	_, err = dummy.GetApproved(TokenID("1"))
200	uassert.Error(t, err, "should result in error")
201
202	err = dummy.Approve(alice, addr, TokenID("1"))
203	uassert.NoError(t, err, "should not result in error")
204
205	approvedAddr, err := dummy.GetApproved(TokenID("1"))
206	uassert.NoError(t, err, "should result in error")
207	uassert.Equal(t, addr.String(), approvedAddr.String())
208}
209
210func TestTransferFrom(cur realm, t *testing.T) {
211	alice := testutils.TestAddress("alice")
212
213	dummy := newDummyNFT(0, cur)
214	uassert.True(t, dummy != nil, "should not be nil")
215
216	addr := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
217
218	dummy.mint(alice, TokenID("1"))
219	dummy.mint(alice, TokenID("2"))
220
221	err := dummy.TransferFrom(alice, alice, addr, TokenID("1"))
222	uassert.NoError(t, err, "should result in error")
223
224	// Check balance of alice after transfer
225	balanceOfAlice, err := dummy.BalanceOf(alice)
226	uassert.NoError(t, err, "should result in error")
227	uassert.Equal(t, int64(1), balanceOfAlice)
228
229	// Check balance of addr after transfer
230	balanceOfAddr, err := dummy.BalanceOf(addr)
231	uassert.NoError(t, err, "should not result in error")
232	uassert.Equal(t, int64(1), balanceOfAddr)
233
234	// Check Owner of transferred Token id
235	owner, err := dummy.OwnerOf(TokenID("1"))
236	uassert.NoError(t, err, "should result in error")
237	uassert.Equal(t, addr.String(), owner.String())
238}
239
240func TestSafeTransferFrom(cur realm, t *testing.T) {
241	alice := testutils.TestAddress("alice")
242
243	dummy := newDummyNFT(0, cur)
244	uassert.True(t, dummy != nil, "should not be nil")
245
246	addr := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
247
248	dummy.mint(alice, TokenID("1"))
249	dummy.mint(alice, TokenID("2"))
250
251	err := dummy.SafeTransferFrom(alice, alice, addr, TokenID("1"))
252	uassert.NoError(t, err, "should not result in error")
253
254	// Check balance of alice after transfer
255	balanceOfAlice, err := dummy.BalanceOf(alice)
256	uassert.NoError(t, err, "should not result in error")
257	uassert.Equal(t, int64(1), balanceOfAlice)
258
259	// Check balance of addr after transfer
260	balanceOfAddr, err := dummy.BalanceOf(addr)
261	uassert.NoError(t, err, "should not result in error")
262	uassert.Equal(t, int64(1), balanceOfAddr)
263
264	// Check Owner of transferred Token id
265	owner, err := dummy.OwnerOf(TokenID("1"))
266	uassert.NoError(t, err, "should not result in error")
267	uassert.Equal(t, addr.String(), owner.String())
268}
269
270func TestMint(cur realm, t *testing.T) {
271	dummy := newDummyNFT(0, cur)
272	uassert.True(t, dummy != nil, "should not be nil")
273
274	addr1 := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
275	addr2 := address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj")
276
277	err := dummy.Mint(addr1, TokenID("1"))
278	uassert.NoError(t, err, "should not result in error")
279	err = dummy.Mint(addr1, TokenID("2"))
280	uassert.NoError(t, err, "should not result in error")
281	err = dummy.Mint(addr2, TokenID("3"))
282	uassert.NoError(t, err, "should not result in error")
283
284	// Try minting duplicate token id
285	err = dummy.Mint(addr2, TokenID("1"))
286	uassert.Error(t, err, "should not result in error")
287
288	// Check Owner of Token id
289	owner, err := dummy.OwnerOf(TokenID("1"))
290	uassert.NoError(t, err, "should not result in error")
291	uassert.Equal(t, addr1.String(), owner.String())
292}
293
294func TestBurn(cur realm, t *testing.T) {
295	dummy := newDummyNFT(0, cur)
296	uassert.True(t, dummy != nil, "should not be nil")
297
298	addr := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
299
300	dummy.mint(addr, TokenID("1"))
301	dummy.mint(addr, TokenID("2"))
302
303	err := dummy.Burn(TokenID("1"))
304	uassert.NoError(t, err, "should not result in error")
305
306	// Check Owner of Token id
307	_, err = dummy.OwnerOf(TokenID("1"))
308	uassert.Error(t, err, "should result in error")
309}
310
311func TestSetTokenURI(cur realm, t *testing.T) {
312	dummy := newDummyNFT(0, cur)
313	uassert.True(t, dummy != nil, "should not be nil")
314
315	addr1 := address("g1var589z07ppjsjd24ukm4uguzwdt0tw7g47cgm")
316	addr2 := address("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj")
317	tokenURI := "http://example.com/token"
318
319	dummy.mint(addr1, TokenID("1"))
320
321	_, derr := dummy.SetTokenURI(addr1, TokenID("1"), TokenURI(tokenURI))
322	uassert.NoError(t, derr, "should not result in error")
323
324	// Test case: Invalid token ID
325	_, err := dummy.SetTokenURI(addr1, TokenID("3"), TokenURI(tokenURI))
326	uassert.ErrorIs(t, err, ErrInvalidTokenId)
327
328	// addr2 trying to set URI for token 1 (not owner)
329	_, cerr := dummy.SetTokenURI(addr2, TokenID("1"), TokenURI(tokenURI))
330	uassert.ErrorIs(t, cerr, ErrCallerIsNotOwner)
331
332	dummyTokenURI, err := dummy.TokenURI(TokenID("1"))
333	uassert.NoError(t, err, "TokenURI error")
334	uassert.Equal(t, string(tokenURI), string(dummyTokenURI))
335}
336
337func TestIsApprovedOrOwner(cur realm, t *testing.T) {
338	dummy := newDummyNFT(0, cur)
339	uassert.True(t, dummy != nil, "should not be nil")
340
341	var (
342		owner    = testutils.TestAddress("owner")
343		operator = testutils.TestAddress("operator")
344		approved = testutils.TestAddress("approved")
345		other    = testutils.TestAddress("other")
346	)
347
348	tid := TokenID("1")
349
350	err := dummy.mint(owner, tid)
351	uassert.NoError(t, err)
352
353	// check owner
354	isApprovedOrOwner := dummy.isApprovedOrOwner(owner, tid)
355	uassert.True(t, isApprovedOrOwner, "owner should be approved")
356
357	// check operator
358	err = dummy.SetApprovalForAll(owner, operator, true)
359	uassert.NoError(t, err)
360	isApprovedOrOwner = dummy.isApprovedOrOwner(operator, tid)
361	uassert.True(t, isApprovedOrOwner, "operator should be approved")
362
363	// check approved
364	err = dummy.Approve(owner, approved, tid)
365	uassert.NoError(t, err)
366	isApprovedOrOwner = dummy.isApprovedOrOwner(approved, tid)
367	uassert.True(t, isApprovedOrOwner, "approved address should be approved")
368
369	// check other
370	isApprovedOrOwner = dummy.isApprovedOrOwner(other, tid)
371	uassert.False(t, isApprovedOrOwner, "other address should not be approved")
372
373	// check non-existent token
374	isApprovedOrOwner = dummy.isApprovedOrOwner(owner, TokenID("999"))
375	uassert.False(t, isApprovedOrOwner, "non-existent token should not be approved")
376}