github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/pagination/pagepagination/pagination_test.go (about)

     1  package pagepagination
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"net/url"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  
    13  	"github.com/ory/x/urlx"
    14  )
    15  
    16  func TestPaginationHeader(t *testing.T) {
    17  	u := urlx.ParseOrPanic("http://example.com")
    18  
    19  	t.Run("Create previous and first but not next or last if at the end", func(t *testing.T) {
    20  		r := httptest.NewRecorder()
    21  		PaginationHeader(r, u, 120, 2, 50)
    22  
    23  		expect := strings.Join([]string{
    24  			"<http://example.com?page=0&per_page=50>; rel=\"first\"",
    25  			"<http://example.com?page=1&per_page=50>; rel=\"prev\"",
    26  		}, ",")
    27  
    28  		assert.EqualValues(t, expect, r.Result().Header.Get("Link"))
    29  		assert.EqualValues(t, "120", r.Result().Header.Get("X-Total-Count"))
    30  	})
    31  
    32  	t.Run("Create next and last, but not previous or first if at the beginning", func(t *testing.T) {
    33  		r := httptest.NewRecorder()
    34  		PaginationHeader(r, u, 120, 0, 50)
    35  
    36  		expect := strings.Join([]string{
    37  			"<http://example.com?page=1&per_page=50>; rel=\"next\"",
    38  			"<http://example.com?page=2&per_page=50>; rel=\"last\"",
    39  		}, ",")
    40  
    41  		assert.EqualValues(t, expect, r.Result().Header.Get("Link"))
    42  		assert.EqualValues(t, "120", r.Result().Header.Get("X-Total-Count"))
    43  	})
    44  
    45  	t.Run("Create previous, next, first, and last if in the middle", func(t *testing.T) {
    46  		r := httptest.NewRecorder()
    47  		PaginationHeader(r, u, 300, 3, 50)
    48  
    49  		expect := strings.Join([]string{
    50  			"<http://example.com?page=0&per_page=50>; rel=\"first\"",
    51  			"<http://example.com?page=4&per_page=50>; rel=\"next\"",
    52  			"<http://example.com?page=2&per_page=50>; rel=\"prev\"",
    53  			"<http://example.com?page=5&per_page=50>; rel=\"last\"",
    54  		}, ",")
    55  
    56  		assert.EqualValues(t, expect, r.Result().Header.Get("Link"))
    57  		assert.EqualValues(t, "300", r.Result().Header.Get("X-Total-Count"))
    58  	})
    59  
    60  	t.Run("Header should default limit to 1 no limit was provided", func(t *testing.T) {
    61  		r := httptest.NewRecorder()
    62  		PaginationHeader(r, u, 100, 20, 0)
    63  
    64  		expect := strings.Join([]string{
    65  			"<http://example.com?page=0&per_page=1>; rel=\"first\"",
    66  			"<http://example.com?page=21&per_page=1>; rel=\"next\"",
    67  			"<http://example.com?page=19&per_page=1>; rel=\"prev\"",
    68  			"<http://example.com?page=99&per_page=1>; rel=\"last\"",
    69  		}, ",")
    70  
    71  		assert.EqualValues(t, expect, r.Result().Header.Get("Link"))
    72  		assert.EqualValues(t, "100", r.Result().Header.Get("X-Total-Count"))
    73  	})
    74  
    75  	t.Run("Create previous, next, first, but not last if in the middle and no total was provided", func(t *testing.T) {
    76  		r := httptest.NewRecorder()
    77  		PaginationHeader(r, u, 0, 3, 50)
    78  
    79  		expect := strings.Join([]string{
    80  			"<http://example.com?page=0&per_page=50>; rel=\"first\"",
    81  			"<http://example.com?page=4&per_page=50>; rel=\"next\"",
    82  			"<http://example.com?page=2&per_page=50>; rel=\"prev\"",
    83  		}, ",")
    84  
    85  		assert.EqualValues(t, expect, r.Result().Header.Get("Link"))
    86  		assert.EqualValues(t, "0", r.Result().Header.Get("X-Total-Count"))
    87  	})
    88  
    89  	t.Run("Create only first if the limits provided exceeds the number of clients found", func(t *testing.T) {
    90  		r := httptest.NewRecorder()
    91  		PaginationHeader(r, u, 5, 0, 50)
    92  
    93  		expect := "<http://example.com?page=0&per_page=5>; rel=\"first\""
    94  
    95  		assert.EqualValues(t, expect, r.Result().Header.Get("Link"))
    96  		assert.EqualValues(t, "5", r.Result().Header.Get("X-Total-Count"))
    97  	})
    98  }
    99  
   100  func TestParsePagination(t *testing.T) {
   101  	for _, tc := range []struct {
   102  		d                    string
   103  		url                  string
   104  		expectedItemsPerPage int
   105  		expectedPage         int
   106  	}{
   107  		{"normal", "http://localhost/foo?per_page=10&page=10", 10, 10},
   108  		{"defaults", "http://localhost/foo", 250, 0},
   109  		{"limits", "http://localhost/foo?per_page=2000", 1000, 0},
   110  		{"negatives", "http://localhost/foo?per_page=-1&page=-1", 1, 0},
   111  		{"invalid_params", "http://localhost/foo?per_page=a&page=b", 250, 0},
   112  	} {
   113  		t.Run(fmt.Sprintf("case=%s", tc.d), func(t *testing.T) {
   114  			u, _ := url.Parse(tc.url)
   115  			page, perPage := new(PagePaginator).ParsePagination(&http.Request{URL: u})
   116  			assert.EqualValues(t, perPage, tc.expectedItemsPerPage, "per_page")
   117  			assert.EqualValues(t, page, tc.expectedPage, "page")
   118  		})
   119  	}
   120  }