pagination_test.go (8781B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package page
15
16 import (
17 "fmt"
18 "html/template"
19 "testing"
20
21 "github.com/gohugoio/hugo/config"
22
23 qt "github.com/frankban/quicktest"
24 "github.com/gohugoio/hugo/output"
25 )
26
27 func TestSplitPages(t *testing.T) {
28 t.Parallel()
29 c := qt.New(t)
30 pages := createTestPages(21)
31 chunks := splitPages(pages, 5)
32 c.Assert(len(chunks), qt.Equals, 5)
33
34 for i := 0; i < 4; i++ {
35 c.Assert(chunks[i].Len(), qt.Equals, 5)
36 }
37
38 lastChunk := chunks[4]
39 c.Assert(lastChunk.Len(), qt.Equals, 1)
40 }
41
42 func TestSplitPageGroups(t *testing.T) {
43 t.Parallel()
44 c := qt.New(t)
45 pages := createTestPages(21)
46 groups, _ := pages.GroupBy("Weight", "desc")
47 chunks := splitPageGroups(groups, 5)
48 c.Assert(len(chunks), qt.Equals, 5)
49
50 firstChunk := chunks[0]
51
52 // alternate weight 5 and 10
53 if groups, ok := firstChunk.(PagesGroup); ok {
54 c.Assert(groups.Len(), qt.Equals, 5)
55 for _, pg := range groups {
56 // first group 10 in weight
57 c.Assert(pg.Key, qt.Equals, 10)
58 for _, p := range pg.Pages {
59 c.Assert(p.FuzzyWordCount()%2 == 0, qt.Equals, true) // magic test
60 }
61 }
62 } else {
63 t.Fatal("Excepted PageGroup")
64 }
65
66 lastChunk := chunks[4]
67
68 if groups, ok := lastChunk.(PagesGroup); ok {
69 c.Assert(groups.Len(), qt.Equals, 1)
70 for _, pg := range groups {
71 // last should have 5 in weight
72 c.Assert(pg.Key, qt.Equals, 5)
73 for _, p := range pg.Pages {
74 c.Assert(p.FuzzyWordCount()%2 != 0, qt.Equals, true) // magic test
75 }
76 }
77 } else {
78 t.Fatal("Excepted PageGroup")
79 }
80 }
81
82 func TestPager(t *testing.T) {
83 t.Parallel()
84 c := qt.New(t)
85 pages := createTestPages(21)
86 groups, _ := pages.GroupBy("Weight", "desc")
87
88 urlFactory := func(page int) string {
89 return fmt.Sprintf("page/%d/", page)
90 }
91
92 _, err := newPaginatorFromPages(pages, -1, urlFactory)
93 c.Assert(err, qt.Not(qt.IsNil))
94
95 _, err = newPaginatorFromPageGroups(groups, -1, urlFactory)
96 c.Assert(err, qt.Not(qt.IsNil))
97
98 pag, err := newPaginatorFromPages(pages, 5, urlFactory)
99 c.Assert(err, qt.IsNil)
100 doTestPages(t, pag)
101 first := pag.Pagers()[0].First()
102 c.Assert(first.String(), qt.Equals, "Pager 1")
103 c.Assert(first.Pages(), qt.Not(qt.HasLen), 0)
104 c.Assert(first.PageGroups(), qt.HasLen, 0)
105
106 pag, err = newPaginatorFromPageGroups(groups, 5, urlFactory)
107 c.Assert(err, qt.IsNil)
108 doTestPages(t, pag)
109 first = pag.Pagers()[0].First()
110 c.Assert(first.PageGroups(), qt.Not(qt.HasLen), 0)
111 c.Assert(first.Pages(), qt.HasLen, 0)
112 }
113
114 func doTestPages(t *testing.T, paginator *Paginator) {
115 c := qt.New(t)
116 paginatorPages := paginator.Pagers()
117
118 c.Assert(len(paginatorPages), qt.Equals, 5)
119 c.Assert(paginator.TotalNumberOfElements(), qt.Equals, 21)
120 c.Assert(paginator.PageSize(), qt.Equals, 5)
121 c.Assert(paginator.TotalPages(), qt.Equals, 5)
122
123 first := paginatorPages[0]
124 c.Assert(first.URL(), qt.Equals, template.HTML("page/1/"))
125 c.Assert(first.First(), qt.Equals, first)
126 c.Assert(first.HasNext(), qt.Equals, true)
127 c.Assert(first.Next(), qt.Equals, paginatorPages[1])
128 c.Assert(first.HasPrev(), qt.Equals, false)
129 c.Assert(first.Prev(), qt.IsNil)
130 c.Assert(first.NumberOfElements(), qt.Equals, 5)
131 c.Assert(first.PageNumber(), qt.Equals, 1)
132
133 third := paginatorPages[2]
134 c.Assert(third.HasNext(), qt.Equals, true)
135 c.Assert(third.HasPrev(), qt.Equals, true)
136 c.Assert(third.Prev(), qt.Equals, paginatorPages[1])
137
138 last := paginatorPages[4]
139 c.Assert(last.URL(), qt.Equals, template.HTML("page/5/"))
140 c.Assert(last.Last(), qt.Equals, last)
141 c.Assert(last.HasNext(), qt.Equals, false)
142 c.Assert(last.Next(), qt.IsNil)
143 c.Assert(last.HasPrev(), qt.Equals, true)
144 c.Assert(last.NumberOfElements(), qt.Equals, 1)
145 c.Assert(last.PageNumber(), qt.Equals, 5)
146 }
147
148 func TestPagerNoPages(t *testing.T) {
149 t.Parallel()
150 c := qt.New(t)
151 pages := createTestPages(0)
152 groups, _ := pages.GroupBy("Weight", "desc")
153
154 urlFactory := func(page int) string {
155 return fmt.Sprintf("page/%d/", page)
156 }
157
158 paginator, _ := newPaginatorFromPages(pages, 5, urlFactory)
159 doTestPagerNoPages(t, paginator)
160
161 first := paginator.Pagers()[0].First()
162 c.Assert(first.PageGroups(), qt.HasLen, 0)
163 c.Assert(first.Pages(), qt.HasLen, 0)
164
165 paginator, _ = newPaginatorFromPageGroups(groups, 5, urlFactory)
166 doTestPagerNoPages(t, paginator)
167
168 first = paginator.Pagers()[0].First()
169 c.Assert(first.PageGroups(), qt.HasLen, 0)
170 c.Assert(first.Pages(), qt.HasLen, 0)
171 }
172
173 func doTestPagerNoPages(t *testing.T, paginator *Paginator) {
174 paginatorPages := paginator.Pagers()
175 c := qt.New(t)
176 c.Assert(len(paginatorPages), qt.Equals, 1)
177 c.Assert(paginator.TotalNumberOfElements(), qt.Equals, 0)
178 c.Assert(paginator.PageSize(), qt.Equals, 5)
179 c.Assert(paginator.TotalPages(), qt.Equals, 0)
180
181 // pageOne should be nothing but the first
182 pageOne := paginatorPages[0]
183 c.Assert(pageOne.First(), qt.Not(qt.IsNil))
184 c.Assert(pageOne.HasNext(), qt.Equals, false)
185 c.Assert(pageOne.HasPrev(), qt.Equals, false)
186 c.Assert(pageOne.Next(), qt.IsNil)
187 c.Assert(len(pageOne.Pagers()), qt.Equals, 1)
188 c.Assert(pageOne.Pages().Len(), qt.Equals, 0)
189 c.Assert(pageOne.NumberOfElements(), qt.Equals, 0)
190 c.Assert(pageOne.TotalNumberOfElements(), qt.Equals, 0)
191 c.Assert(pageOne.TotalPages(), qt.Equals, 0)
192 c.Assert(pageOne.PageNumber(), qt.Equals, 1)
193 c.Assert(pageOne.PageSize(), qt.Equals, 5)
194 }
195
196 func TestPaginationURLFactory(t *testing.T) {
197 t.Parallel()
198 c := qt.New(t)
199 cfg := config.New()
200 cfg.Set("paginatePath", "zoo")
201
202 for _, uglyURLs := range []bool{false, true} {
203 c.Run(fmt.Sprintf("uglyURLs=%t", uglyURLs), func(c *qt.C) {
204 tests := []struct {
205 name string
206 d TargetPathDescriptor
207 baseURL string
208 page int
209 expected string
210 expectedUgly string
211 }{
212 {
213 "HTML home page 32",
214 TargetPathDescriptor{Kind: KindHome, Type: output.HTMLFormat},
215 "http://example.com/", 32, "/zoo/32/", "/zoo/32.html",
216 },
217 {
218 "JSON home page 42",
219 TargetPathDescriptor{Kind: KindHome, Type: output.JSONFormat},
220 "http://example.com/", 42, "/zoo/42/index.json", "/zoo/42.json",
221 },
222 }
223
224 for _, test := range tests {
225 d := test.d
226 cfg.Set("baseURL", test.baseURL)
227 cfg.Set("uglyURLs", uglyURLs)
228 d.UglyURLs = uglyURLs
229
230 pathSpec := newTestPathSpecFor(cfg)
231 d.PathSpec = pathSpec
232
233 factory := newPaginationURLFactory(d)
234
235 got := factory(test.page)
236
237 if uglyURLs {
238 c.Assert(got, qt.Equals, test.expectedUgly)
239 } else {
240 c.Assert(got, qt.Equals, test.expected)
241 }
242
243 }
244 })
245 }
246 }
247
248 func TestProbablyEqualPageLists(t *testing.T) {
249 t.Parallel()
250 fivePages := createTestPages(5)
251 zeroPages := createTestPages(0)
252 zeroPagesByWeight, _ := createTestPages(0).GroupBy("Weight", "asc")
253 fivePagesByWeight, _ := createTestPages(5).GroupBy("Weight", "asc")
254 ninePagesByWeight, _ := createTestPages(9).GroupBy("Weight", "asc")
255
256 for i, this := range []struct {
257 v1 any
258 v2 any
259 expect bool
260 }{
261 {nil, nil, true},
262 {"a", "b", true},
263 {"a", fivePages, false},
264 {fivePages, "a", false},
265 {fivePages, createTestPages(2), false},
266 {fivePages, fivePages, true},
267 {zeroPages, zeroPages, true},
268 {fivePagesByWeight, fivePagesByWeight, true},
269 {zeroPagesByWeight, fivePagesByWeight, false},
270 {zeroPagesByWeight, zeroPagesByWeight, true},
271 {fivePagesByWeight, fivePages, false},
272 {fivePagesByWeight, ninePagesByWeight, false},
273 } {
274 result := probablyEqualPageLists(this.v1, this.v2)
275
276 if result != this.expect {
277 t.Errorf("[%d] got %t but expected %t", i, result, this.expect)
278 }
279 }
280 }
281
282 func TestPaginationPage(t *testing.T) {
283 t.Parallel()
284 c := qt.New(t)
285 urlFactory := func(page int) string {
286 return fmt.Sprintf("page/%d/", page)
287 }
288
289 fivePages := createTestPages(7)
290 fivePagesFuzzyWordCount, _ := createTestPages(7).GroupBy("FuzzyWordCount", "asc")
291
292 p1, _ := newPaginatorFromPages(fivePages, 2, urlFactory)
293 p2, _ := newPaginatorFromPageGroups(fivePagesFuzzyWordCount, 2, urlFactory)
294
295 f1 := p1.pagers[0].First()
296 f2 := p2.pagers[0].First()
297
298 page11, _ := f1.page(1)
299 page1Nil, _ := f1.page(3)
300
301 page21, _ := f2.page(1)
302 page2Nil, _ := f2.page(3)
303
304 c.Assert(page11.FuzzyWordCount(), qt.Equals, 3)
305 c.Assert(page1Nil, qt.IsNil)
306
307 c.Assert(page21, qt.Not(qt.IsNil))
308 c.Assert(page21.FuzzyWordCount(), qt.Equals, 3)
309 c.Assert(page2Nil, qt.IsNil)
310 }