Files
gochat/backend/pkg/pagination/pagination_test.go
T

178 lines
3.7 KiB
Go

package pagination
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)
func init() {
gin.SetMode(gin.TestMode)
}
func newContext(query string) *gin.Context {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodGet, "/?"+query, nil)
return c
}
func TestParse_Defaults(t *testing.T) {
c := newContext("")
p := Parse(c)
assert.Equal(t, 1, p.Page)
assert.Equal(t, DefaultPerPage, p.PerPage)
assert.Equal(t, 0, p.Offset)
}
func TestParse_ValidParams(t *testing.T) {
c := newContext("page=3&per_page=10")
p := Parse(c)
assert.Equal(t, 3, p.Page)
assert.Equal(t, 10, p.PerPage)
assert.Equal(t, 20, p.Offset) // (3-1)*10
}
func TestParse_PageZero(t *testing.T) {
c := newContext("page=0")
p := Parse(c)
assert.Equal(t, 1, p.Page)
assert.Equal(t, DefaultPerPage, p.PerPage)
assert.Equal(t, 0, p.Offset)
}
func TestParse_NegativePage(t *testing.T) {
c := newContext("page=-5")
p := Parse(c)
assert.Equal(t, 1, p.Page)
assert.Equal(t, 0, p.Offset)
}
func TestParse_PerPageZero(t *testing.T) {
c := newContext("per_page=0")
p := Parse(c)
assert.Equal(t, 1, p.Page)
assert.Equal(t, DefaultPerPage, p.PerPage)
assert.Equal(t, 0, p.Offset)
}
func TestParse_NegativePerPage(t *testing.T) {
c := newContext("per_page=-10")
p := Parse(c)
assert.Equal(t, DefaultPerPage, p.PerPage)
}
func TestParse_PerPageExceedsMax(t *testing.T) {
c := newContext("per_page=500")
p := Parse(c)
assert.Equal(t, MaxPerPage, p.PerPage)
}
func TestParse_PerPageExactlyMax(t *testing.T) {
c := newContext("per_page=100")
p := Parse(c)
assert.Equal(t, MaxPerPage, p.PerPage)
}
func TestParse_PerPageJustAboveMax(t *testing.T) {
c := newContext("per_page=101")
p := Parse(c)
assert.Equal(t, MaxPerPage, p.PerPage)
}
func TestParse_PerPageJustBelowMax(t *testing.T) {
c := newContext("per_page=99")
p := Parse(c)
assert.Equal(t, 99, p.PerPage)
}
func TestParse_NonNumericPage(t *testing.T) {
// strconv.Atoi returns 0 for non-numeric, which gets clamped to 1
c := newContext("page=abc")
p := Parse(c)
assert.Equal(t, 1, p.Page)
}
func TestParse_NonNumericPerPage(t *testing.T) {
c := newContext("per_page=abc")
p := Parse(c)
assert.Equal(t, DefaultPerPage, p.PerPage)
}
func TestParse_OffsetCalculation(t *testing.T) {
tests := []struct {
page, perPage, expectedOffset int
}{
{1, 25, 0},
{2, 25, 25},
{3, 10, 20},
{10, 50, 450},
{1, 1, 0},
}
for _, tt := range tests {
c := newContext("")
// Manually set query params
c.Request.URL.RawQuery = "page=" + itoa(tt.page) + "&per_page=" + itoa(tt.perPage)
p := Parse(c)
assert.Equal(t, tt.expectedOffset, p.Offset, "page=%d perPage=%d", tt.page, tt.perPage)
}
}
func TestOffsetToPage_NormalCases(t *testing.T) {
tests := []struct {
offset, perPage, expected int
}{
{0, 25, 1},
{24, 25, 1},
{25, 25, 2},
{50, 25, 3},
{0, 10, 1},
{9, 10, 1},
{10, 10, 2},
{100, 50, 3},
}
for _, tt := range tests {
result := OffsetToPage(tt.offset, tt.perPage)
assert.Equal(t, tt.expected, result, "offset=%d perPage=%d", tt.offset, tt.perPage)
}
}
func TestOffsetToPage_ZeroPerPage(t *testing.T) {
assert.Equal(t, 1, OffsetToPage(100, 0))
}
func TestOffsetToPage_NegativePerPage(t *testing.T) {
assert.Equal(t, 1, OffsetToPage(100, -5))
}
func TestOffsetToPage_ZeroOffset(t *testing.T) {
assert.Equal(t, 1, OffsetToPage(0, 25))
}
// itoa is a small helper to avoid importing strconv in test
func itoa(n int) string {
if n == 0 {
return "0"
}
neg := false
if n < 0 {
neg = true
n = -n
}
var buf [20]byte
i := len(buf)
for n > 0 {
i--
buf[i] = byte('0' + n%10)
n /= 10
}
if neg {
i--
buf[i] = '-'
}
return string(buf[i:])
}