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, ""))
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),
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}