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 }