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

render_test.gno

4.84 Kb · 110 lines
  1package definition
  2
  3import (
  4	"net/url"
  5	"strconv"
  6	"strings"
  7	"testing"
  8
  9	"gno.land/p/nt/uassert/v0"
 10)
 11
 12func 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=\"한글&#34;&lt;&amp;[key] &amp; ? :\""))
 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
 47func 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
 75func 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("&#49; <script> [x](url) *bold* ~strike~"))
 87	uassert.Equal(t, "한글 😀 next line", renderLabel("한글 😀\nnext\rline"))
 88}
 89
 90func 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}