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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

goldenticket_test.gno

4.30 Kb · 143 lines
  1package goldenticket
  2
  3import (
  4	"strings"
  5	"testing"
  6
  7	"gno.land/p/nt/grc721/v0"
  8	"gno.land/p/nt/testutils/v0"
  9	"gno.land/p/nt/uassert/v0"
 10)
 11
 12var (
 13	aliceAddr = testutils.TestAddress("alice")
 14	bobAddr   = testutils.TestAddress("bob")
 15)
 16
 17// reset redoes what init does on chain, with alice as the publisher.
 18func reset(cur realm) {
 19	func(cur realm) {
 20		bootstrap(aliceAddr, cur)
 21	}(cross(cur))
 22}
 23
 24// The reads, called as Adena calls them: the id a quoted string, two values.
 25func TestReads(cur realm, t *testing.T) {
 26	reset(cur)
 27
 28	owner, err := OwnerOf("1")
 29	uassert.NoError(t, err)
 30	uassert.Equal(t, aliceAddr, owner)
 31
 32	n, err := BalanceOf(aliceAddr)
 33	uassert.NoError(t, err)
 34	uassert.Equal(t, int64(1), n)
 35	n, err = BalanceOf(bobAddr)
 36	uassert.NoError(t, err)
 37	uassert.Equal(t, int64(0), n)
 38
 39	uri, err := TokenURI("1")
 40	uassert.NoError(t, err)
 41	uassert.Equal(t, defaultImage, uri)
 42	uassert.True(t, strings.HasPrefix(uri, "https://"))
 43
 44	meta, err := TokenMetadata("1")
 45	uassert.NoError(t, err)
 46	uassert.Equal(t, `{"name":"Golden Ticket #1","description":"A 1/1 on gno.land, minted to check that collections show in Adena.",`+
 47		`"image":"`+defaultImage+`","attributes":[{"traitType":"edition","value":"1 of 1"},{"traitType":"metal","value":"gold"}]}`, meta)
 48
 49	uassert.Equal(t, int64(1), Token.TotalSupply())
 50	uassert.Equal(t, "Golden Ticket", Name())
 51	uassert.Equal(t, "GOLD", Symbol())
 52
 53	// Any other id is an error, not a panic.
 54	for _, bad := range []grc721.TokenID{"", "0", "2", "01", " 1"} {
 55		_, err = OwnerOf(bad)
 56		uassert.ErrorContains(t, err, errNoTicket, string(bad))
 57		_, err = TokenURI(bad)
 58		uassert.ErrorContains(t, err, errNoTicket, string(bad))
 59		_, err = TokenMetadata(bad)
 60		uassert.ErrorContains(t, err, errNoTicket, string(bad))
 61	}
 62}
 63
 64func TestTransfer(cur realm, t *testing.T) {
 65	reset(cur)
 66
 67	// Only the holder moves the ticket.
 68	testing.SetRealm(testing.NewUserRealm(bobAddr))
 69	uassert.AbortsWithMessage(t, cur, errNotOwner, func() {
 70		Transfer(cross(cur), bobAddr)
 71	})
 72
 73	testing.SetRealm(testing.NewUserRealm(aliceAddr))
 74	uassert.AbortsWithMessage(t, cur, errBadOwner, func() {
 75		Transfer(cross(cur), address("nope"))
 76	})
 77	Transfer(cross(cur), bobAddr)
 78	owner, err := OwnerOf("1")
 79	uassert.NoError(t, err)
 80	uassert.Equal(t, bobAddr, owner)
 81	n, _ := BalanceOf(aliceAddr)
 82	uassert.Equal(t, int64(0), n)
 83	n, _ = BalanceOf(bobAddr)
 84	uassert.Equal(t, int64(1), n)
 85
 86	// Not through another realm.
 87	testing.SetRealm(testing.NewCodeRealm("gno.land/r/demo/relay"))
 88	uassert.AbortsWithMessage(t, cur, errNotOwner, func() {
 89		Transfer(cross(cur), aliceAddr)
 90	})
 91}
 92
 93func TestRender(cur realm, t *testing.T) {
 94	reset(cur)
 95	out := Render("")
 96	uassert.True(t, strings.Contains(out, "# Golden Ticket\n"))
 97	uassert.True(t, strings.Contains(out, "!["+tokenName+"]("+defaultImage+")"))
 98	uassert.True(t, strings.Contains(out, "Held by `"+aliceAddr.String()+"`."))
 99}
100
101func TestSetImage(cur realm, t *testing.T) {
102	reset(cur)
103	uassert.Equal(t, aliceAddr, Admin())
104	uassert.Equal(t, defaultImage, Image())
105
106	// Only the admin, and not through another realm.
107	testing.SetRealm(testing.NewUserRealm(bobAddr))
108	uassert.AbortsWithMessage(t, cur, errNotAdmin, func() {
109		SetImage(cross(cur), "https://example.org/a.png")
110	})
111	testing.SetRealm(testing.NewCodeRealm("gno.land/r/demo/relay"))
112	uassert.AbortsWithMessage(t, cur, errNotAdmin, func() {
113		SetImage(cross(cur), "https://example.org/a.png")
114	})
115
116	testing.SetRealm(testing.NewUserRealm(aliceAddr))
117	for _, bad := range []string{
118		"", "http://example.org/a.png", "https://", "javascript:alert(1)",
119		"https://example.org/a b.png", `https://example.org/"a.png`, "https://example.org/a.png)![x](y",
120		"https://example.org/" + strings.Repeat("a", 300),
121	} {
122		uassert.AbortsWithMessage(t, cur, errBadImage, func() {
123			SetImage(cross(cur), bad)
124		})
125	}
126
127	next := "https://ipfs.io/ipfs/bafy123/ticket.png?size=350&v=2"
128	SetImage(cross(cur), next)
129	uassert.Equal(t, next, Image())
130	uri, err := TokenURI("1")
131	uassert.NoError(t, err)
132	uassert.Equal(t, next, uri)
133	meta, _ := TokenMetadata("1")
134	uassert.True(t, strings.Contains(meta, `"image":"`+next+`"`))
135	uassert.True(t, strings.Contains(Render(""), "("+next+")"))
136
137	// The admin stays the publisher after the ticket moves.
138	Transfer(cross(cur), bobAddr)
139	testing.SetRealm(testing.NewUserRealm(bobAddr))
140	uassert.AbortsWithMessage(t, cur, errNotAdmin, func() {
141		SetImage(cross(cur), defaultImage)
142	})
143}