github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/resources/page/pagination_test.go (about)

     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     interface{}
   258  		v2     interface{}
   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  }