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}