jsonpage_test.gno
5.39 Kb · 174 lines
1package jsonpage
2
3import (
4 "net/url"
5 "strconv"
6 "testing"
7
8 "gno.land/p/nt/bptree/v0"
9 "gno.land/p/nt/mux/v0"
10 "gno.land/p/nt/uassert/v0"
11 "gno.land/p/onbloc/json"
12)
13
14type String string
15
16// Implements JSONRenderer
17func (s String) RenderJSON() *json.Node {
18 return json.StringNode("", string(s))
19}
20
21func TestRender(t *testing.T) {
22 emptyTree := bptree.NewBPTree32()
23 tree100 := bptree.NewBPTree32()
24 for i := 0; i < 100; i++ {
25 tree100.Set(strconv.Itoa(i), i)
26 }
27 tree150 := bptree.NewBPTree32()
28 for i := 0; i < 150; i++ {
29 tree150.Set(strconv.Itoa(i), i)
30 }
31 intRenderer := func(k string, v any) *json.Node {
32 return json.NumberNode("", float64(v.(int)))
33 }
34 treeWithValueRenderer := bptree.NewBPTree32()
35 for i := 0; i < 5; i++ {
36 s := strconv.Itoa(i)
37 treeWithValueRenderer.Set(s, String(s))
38 }
39 tests := []struct {
40 name string
41 tree *bptree.BPTree
42 renderer func(string, any) *json.Node
43 query string
44 expectedJSON string
45 }{
46 {
47 name: "no query empty tree",
48 tree: emptyTree,
49 renderer: nil,
50 query: "",
51 expectedJSON: `{"items":[],"page":1,"total":1}`,
52 },
53 {
54 name: "page=2 query empty tree",
55 tree: emptyTree,
56 renderer: nil,
57 query: "page=2",
58 expectedJSON: `{"items":[],"page":2,"total":1}`,
59 },
60 {
61 name: "no query returns page 1",
62 tree: tree100,
63 renderer: intRenderer,
64 query: "",
65 expectedJSON: `{"items":[0,1,10,11,12,13,14,15,16,17,18,19,2,20,21,22,23,24,25,26],"page":1,"total":5}`,
66 },
67 {
68 name: "page 1",
69 tree: tree100,
70 renderer: intRenderer,
71 query: "page=1",
72 expectedJSON: `{"items":[0,1,10,11,12,13,14,15,16,17,18,19,2,20,21,22,23,24,25,26],"page":1,"total":5}`,
73 },
74 {
75 name: "page 0 returns page 1",
76 tree: tree100,
77 renderer: intRenderer,
78 query: "page=0",
79 expectedJSON: `{"items":[0,1,10,11,12,13,14,15,16,17,18,19,2,20,21,22,23,24,25,26],"page":1,"total":5}`,
80 },
81 {
82 name: "negative page returns page 1",
83 tree: tree100,
84 renderer: intRenderer,
85 query: "page=-2",
86 expectedJSON: `{"items":[0,1,10,11,12,13,14,15,16,17,18,19,2,20,21,22,23,24,25,26],"page":1,"total":5}`,
87 },
88 {
89 name: "page 2",
90 tree: tree100,
91 renderer: intRenderer,
92 query: "page=2",
93 expectedJSON: `{"items":[27,28,29,3,30,31,32,33,34,35,36,37,38,39,4,40,41,42,43,44],"page":2,"total":5}`,
94 },
95 {
96 name: "page == total returns last page",
97 tree: tree100,
98 renderer: intRenderer,
99 query: "page=5",
100 expectedJSON: `{"items":[81,82,83,84,85,86,87,88,89,9,90,91,92,93,94,95,96,97,98,99],"page":5,"total":5}`,
101 },
102 {
103 name: "page > total returns empty result",
104 tree: tree100,
105 renderer: intRenderer,
106 query: "page=7",
107 expectedJSON: `{"items":[],"page":7,"total":5}`,
108 },
109 {
110 name: "page 2 limit 10",
111 tree: tree100,
112 renderer: intRenderer,
113 query: "page=2&limit=10",
114 expectedJSON: `{"items":[18,19,2,20,21,22,23,24,25,26],"page":2,"total":10}`,
115 },
116 {
117 name: "page 2 limit 0 returns default limit",
118 tree: tree100,
119 renderer: intRenderer,
120 query: "page=2&limit=0",
121 expectedJSON: `{"items":[27,28,29,3,30,31,32,33,34,35,36,37,38,39,4,40,41,42,43,44],"page":2,"total":5}`,
122 },
123 {
124 name: "page 2 limit 100 return empty result",
125 tree: tree100,
126 renderer: intRenderer,
127 query: "page=2&limit=100",
128 expectedJSON: `{"items":[],"page":2,"total":1}`,
129 },
130 {
131 name: "page 1 limit 100 return all items",
132 tree: tree100,
133 renderer: intRenderer,
134 query: "limit=100",
135 expectedJSON: `{"items":[0,1,10,11,12,13,14,15,16,17,18,19,2,20,21,22,23,24,25,26,27,28,29,3,30,31,32,33,34,35,36,37,38,39,4,40,41,42,43,44,45,46,47,48,49,5,50,51,52,53,54,55,56,57,58,59,6,60,61,62,63,64,65,66,67,68,69,7,70,71,72,73,74,75,76,77,78,79,8,80,81,82,83,84,85,86,87,88,89,9,90,91,92,93,94,95,96,97,98,99],"page":1,"total":1}`,
136 },
137 {
138 name: "max limit is 100",
139 tree: tree150,
140 renderer: intRenderer,
141 query: "limit=200",
142 expectedJSON: `{"items":[0,1,10,100,101,102,103,104,105,106,107,108,109,11,110,111,112,113,114,115,116,117,118,119,12,120,121,122,123,124,125,126,127,128,129,13,130,131,132,133,134,135,136,137,138,139,14,140,141,142,143,144,145,146,147,148,149,15,16,17,18,19,2,20,21,22,23,24,25,26,27,28,29,3,30,31,32,33,34,35,36,37,38,39,4,40,41,42,43,44,45,46,47,48,49,5,50,51,52,53],"page":1,"total":2}`,
143 },
144 {
145 name: "page=2 max limit is 100",
146 tree: tree150,
147 renderer: intRenderer,
148 query: "limit=200&page=2",
149 expectedJSON: `{"items":[54,55,56,57,58,59,6,60,61,62,63,64,65,66,67,68,69,7,70,71,72,73,74,75,76,77,78,79,8,80,81,82,83,84,85,86,87,88,89,9,90,91,92,93,94,95,96,97,98,99],"page":2,"total":2}`,
150 },
151 {
152 name: "value implements JSONRenderer",
153 tree: treeWithValueRenderer,
154 renderer: nil,
155 query: "",
156 expectedJSON: `{"items":["0","1","2","3","4"],"page":1,"total":1}`,
157 },
158 }
159 for _, tt := range tests {
160 t.Run(tt.name, func(t *testing.T) {
161 v, err := url.ParseQuery(tt.query)
162 if err != nil {
163 t.Fatal(err)
164 }
165 r := &mux.Request{
166 Query: v,
167 }
168
169 n := Render(tt.tree, r, tt.renderer)
170
171 uassert.Equal(t, tt.expectedJSON, n.String())
172 })
173 }
174}