Kind Realm (renderable)
Name lotto
Namespace akkadia / beta
Exported functions 5
Module gno.land/r/akkadia/beta/lotto
gno 0.9 render_test.gno gno
⧉
1 package lotto 2 3 import ( 4 "net/url" 5 "strconv" 6 "strings" 7 "testing" 8 AddNumber (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, owner string, number uint64)
DeleteAll (cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})
GetNumberCount (number uint64, owner string) uint64
ListOwnersByNumber (number uint64, afterOwner string, limit int) []map[string]string
Render (path string) string
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.
9 "gno.land/p/nt/testutils/v0"
10 "gno.land/p/nt/uassert/v0"
11 )
12
13 func TestRenderInput(cur realm, t *testing.T) {
14 setupLotto(cross(cur))
15 home := Render( "" )
16 uassert.True(t, strings.Contains(home, "# AKKADIA Lotto" ))
17 uassert.True(t, strings.Contains(home, `<gno-form path="number">` ))
18 uassert.True(t, strings.Contains(home, `name="number"` ))
19 for _, tc := range [] struct { path, message string }{
20 { "%" , "Invalid URL" },
21 { "number?number=%zz" , "Invalid query" },
22 { "unknown" , "Page not found" },
23 { "number" , "Number is required" },
24 { "number?number=-1" , "Invalid number" },
25 { "number?number=1.5" , "Invalid number" },
26 { "number?number=18446744073709551616" , "Invalid number" },
27 { "number?number=" + url.QueryEscape( `<script>alert(1)</script>` ), "Invalid number" },
28 { "number?number=1&afterOwner=" + url.QueryEscape( `[x](javascript:alert(1))` ), "Invalid cursor address" },
29 { "number?number=1&afterOwner=invalid" , "Invalid cursor address" },
30 } {
31 result := Render(tc.path)
32 uassert.True(t, strings.Contains(result, tc.message))
33 uassert.True(t, strings.Contains(result, `<gno-form path="number">` ))
34 uassert.False(t, strings.Contains(result, "<script>" ))
35 uassert.False(t, strings.Contains(result, "javascript:" ))
36 }
37 for _, number := range [] string { "0" , "18446744073709551615" } {
38 result := Render( "number?number=" + number)
39 uassert.True(t, strings.Contains(result, "## Number " +number+ "\n" ))
40 uassert.True(t, strings.Contains(result, "No owners on this page." ))
41 uassert.False(t, strings.Contains(result, "[Next]" ))
42 }
43 uassert.Equal(t, holdings.Size(), 0 )
44 }
45
46 func TestRenderPagination(cur realm, t *testing.T) {
47 setupLotto(cross(cur))
48 for i := 0 ; i < 41 ; i++ {
49 testing.SetRealm(testing.NewUserRealm(testAdmin))
50 owner := testutils.TestAddress( "lottoRender" + strconv.Itoa(i))
51 AddNumber(cross(cur), owner, 123 )
52 AddNumber(cross(cur), owner, 123 )
53 }
54 testing.SetRealm(testing.NewUserRealm(testAdmin))
55 AddNumber(cross(cur), testOther, 1234 )
56 route := "number?number=000123"
57 afterOwner := ""
58 for _, expectedCount := range [] int { 20 , 20 , 1 } {
59 expected := ListOwnersByNumber( 123 , afterOwner, 20 )
60 result := Render(route)
61 uassert.True(t, strings.Contains(result, "## Number 123\n" ))
62 uassert.True(t, strings.Contains(result, "[Home](./lotto:)" ))
63 uassert.False(t, strings.Contains(result, testOther.String()))
64 uassert.Equal(t, strings.Count(result, " | 2 |\n" ), expectedCount)
65 uassert.Equal(t, strings.Contains(result, "[First page]" ), afterOwner != "" )
66 previous := - 1
67 for _, item := range expected {
68 position := strings.Index(result, "| " +item[ "owner" ]+ " | 2 |" )
69 uassert.True(t, position > previous)
70 previous = position
71 uassert.Equal(t, GetNumberCount( 123 , address(item[ "owner" ])), uint64 ( 2 ))
72 }
73 if expected[ 0 ][ "nextOwner" ] != "" {
74 route = "number?number=123&afterOwner=" + url.QueryEscape(expected[ 0 ][ "nextOwner" ])
75 uassert.True(t, strings.Contains(result, "[Next](./lotto:" +route+ ")" ))
76 afterOwner = expected[ 0 ][ "nextOwner" ]
77 } else {
78 uassert.False(t, strings.Contains(result, "[Next]" ))
79 last := expected[len(expected)- 1 ][ "owner" ]
80 uassert.True(t, strings.Contains(Render( "number?number=123&afterOwner=" +url.QueryEscape(last)), "No owners on this page." ))
81 }
82 }
83 uassert.Equal(t, holdings.Size(), 42 )
84 }
85