Kind Realm (renderable)
Name definition
Namespace akkadia / beta
Exported functions 7
Module gno.land/r/akkadia/beta/definition
gno 0.9 gno
render_test.gno gno
⧉
1 package definition 2 3 import ( 4 "net/url" 5 "strconv" 6 "strings" 7 "testing" 8 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})
Get (key string) []map[string]string
GetField (key string, fieldKey string) map[string]string
GetKeyCount () int
ListKeys (page int, count int) []string
Render (path string) string
SetDefinitions (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}, keys string, values string)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
9 "gno.land/p/nt/uassert/v0"
10 )
11
12 func TestRenderSearchAndEscaping(cur realm, t *testing.T) {
13 setupDefinition(cross(cur), t)
14 testing.SetRealm(testing.NewUserRealm(definitionAdmin))
15 key := "한글\"<&[key] & ? :"
16 setTestDefinition(cross(cur), key, []Field{
17 { "text" , "한글\n```\n<script>alert(1)</script>\n**bold**" },
18 { "link" , "https://example.com/a(b)?x=1&y=2" },
19 { "unsafe" , "javascript:alert(1)" },
20 { "mixed" , "https://example.com/ text" },
21 { "empty" , "" },
22 })
23 page := Render( "" )
24 uassert.True(t, strings.Contains(page, "<gno-form path=\"search\">" ))
25 uassert.True(t, strings.Contains(page, "name=\"key\"" ))
26 uassert.False(t, strings.Contains(page, "name=\"type\"" ))
27 uassert.True(t, strings.Contains(page, "search?key=" +url.QueryEscape(key)))
28 result := Render( "search?key=" + url.QueryEscape(key) + "&page=2" )
29 uassert.True(t, strings.Contains(result, "value=\"한글"<&[key] & ? :\"" ))
30 uassert.True(t, strings.Contains(result, "[Back to list](./definition:list?page=2)" ))
31 uassert.True(t, strings.Contains(result, "````\n한글\n```\n<script>alert(1)</script>\n**bold**\n````" ))
32 uassert.True(t, strings.Contains(result, "](<https://example.com/a(b)?x=1&y=2>)" ))
33 uassert.True(t, strings.Contains(result, "```\njavascript:alert(1)\n```" ))
34 uassert.True(t, strings.Contains(result, "```\nhttps://example.com/ text\n```" ))
35 for _, tc := range [] struct { path, message string }{
36 { "search" , "Key is required" }, { "search?key=missing" , "Entry not found" },
37 { "list?page=0" , "Invalid page" }, { "?page=999999999999999999999999" , "Invalid page" },
38 { "?key=%zz" , "Invalid query" }, { "other" , "Page not found" },
39 } {
40 result := Render(tc.path)
41 uassert.True(t, strings.Contains(result, tc.message))
42 uassert.True(t, strings.Contains(result, "<gno-form path=\"search\">" ))
43 }
44 uassert.True(t, strings.Contains(Render( "search?key=missing" ), "value=\"missing\"" ))
45 }
46
47 func TestRenderPagination(cur realm, t *testing.T) {
48 setupDefinition(cross(cur), t)
49 testing.SetRealm(testing.NewUserRealm(definitionAdmin))
50 uassert.True(t, strings.Contains(Render( "" ), "No entries" ))
51 batch := []testEntry{}
52 for i := 100 ; i < 141 ; i++ {
53 batch = append(batch, testEntry{strconv.Itoa(i), []Field{{ "key" , "item_" + strconv.Itoa(i)}}})
54 }
55 setTestDefinitions(cross(cur), batch)
56 for _, tc := range [] struct {
57 page, count int
58 previous, next bool
59 }{
60 { 1 , 20 , false , true }, { 2 , 20 , true , true }, { 3 , 1 , true , false }, { 4 , 0 , true , false },
61 } {
62 page := Render( "list?page=" + strconv.Itoa(tc.page))
63 uassert.Equal(t, tc.count, strings.Count(page, "./definition:search?key=" ))
64 uassert.Equal(t, tc.previous, strings.Contains(page, "[Previous]" ))
65 uassert.Equal(t, tc.next, strings.Contains(page, "[Next]" ))
66 uassert.True(t, strings.Contains(page, "Page " +strconv.Itoa(tc.page)+ " / 3" ))
67 }
68 first := Render( "" )
69 uassert.True(t, strings.Contains(first, "* [100 — item\\_100](./definition:search?key=100&page=1)" ))
70 uassert.True(t, strings.Contains(first, "search?key=119&page=1" ))
71 uassert.False(t, strings.Contains(first, "search?key=120" ))
72 uassert.False(t, strings.Contains(Render( "list?page=9223372036854775807" ), "[Next]" ))
73 }
74
75 func TestRenderReadableHeadings(cur realm, t *testing.T) {
76 setupDefinition(cross(cur), t)
77 testing.SetRealm(testing.NewUserRealm(definitionAdmin))
78 SetDefinitions(cross(cur), "1103015" , "abilities=value&displayMetadata=value&key=wooden_sword" )
79 page := Render( "search?key=1103015&page=10" )
80 uassert.True(t, strings.Contains(page, "## 1103015\n" ))
81 uassert.True(t, strings.Contains(page, "### abilities\n" ))
82 uassert.True(t, strings.Contains(page, "### displayMetadata\n" ))
83 uassert.False(t, strings.Contains(page, "&#" ))
84 uassert.True(t, strings.Contains(Render( "" ), "[1103015 — wooden\\_sword]" ))
85 // Literal entities and markup must remain text, including in the TOC.
86 uassert.Equal(t, `\&\#49\; \<script\> \[x\]\(url\) \*bold\* \~strike\~` , renderLabel( "1 <script> [x](url) *bold* ~strike~" ))
87 uassert.Equal(t, "한글 😀 next line" , renderLabel( "한글 😀\nnext\rline" ))
88 }
89
90 func TestRenderNumericPageOrder(cur realm, t *testing.T) {
91 setupDefinition(cross(cur), t)
92 testing.SetRealm(testing.NewUserRealm(definitionAdmin))
93 entries := []testEntry{}
94 for i := 21 ; i >= 0 ; i-- {
95 entries = append(entries, testEntry{strconv.Itoa(i), []Field{{ "name" , "item" }}})
96 }
97 setTestDefinitions(cross(cur), entries)
98 first := Render( "" )
99 previous := - 1
100 for i := 0 ; i < 20 ; i++ {
101 position := strings.Index(first, "](./definition:search?key=" +strconv.Itoa(i)+ "&page=1)" )
102 uassert.True(t, position > previous)
103 previous = position
104 }
105 uassert.False(t, strings.Contains(first, "search?key=20&" ))
106 second := Render( "list?page=2" )
107 uassert.Equal(t, 2 , strings.Count(second, "](./definition:search?key=" ))
108 uassert.True(t, strings.Contains(second, "search?key=20&page=2" ))
109 uassert.True(t, strings.Contains(second, "search?key=21&page=2" ))
110 }
111
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.