diff --git a/pkg/page/cursor.go b/pkg/page/cursor.go index a231d7bb4..bb0fcb4cb 100644 --- a/pkg/page/cursor.go +++ b/pkg/page/cursor.go @@ -36,14 +36,17 @@ type ( const ( DefaultCursorSize = 25 + MaxCursorSize = 100 Tail Position = "TAIL" Head Position = "HEAD" ) func NewCursor[T OrderField](size int, from *CursorKey, pos Position, orderBy OrderBy[T]) *Cursor[T] { - if size == 0 { + if size <= 0 { size = DefaultCursorSize + } else if size > MaxCursorSize { + size = MaxCursorSize } return &Cursor[T]{ diff --git a/pkg/page/cursor_test.go b/pkg/page/cursor_test.go new file mode 100644 index 000000000..1c6cb6406 --- /dev/null +++ b/pkg/page/cursor_test.go @@ -0,0 +1,71 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package page + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type testOrderField string + +func (f testOrderField) Column() string { return string(f) } +func (f testOrderField) String() string { return string(f) } + +func TestNewCursor(t *testing.T) { + t.Parallel() + + orderBy := OrderBy[testOrderField]{ + Field: testOrderField("created_at"), + Direction: OrderDirectionAsc, + } + + tests := []struct { + name string + size int + expectedSize int + }{ + { + name: "negative size defaults to DefaultCursorSize", + size: -10, + expectedSize: DefaultCursorSize, + }, + { + name: "zero size defaults to DefaultCursorSize", + size: 0, + expectedSize: DefaultCursorSize, + }, + { + name: "valid size is kept as-is", + size: 50, + expectedSize: 50, + }, + { + name: "oversized value is clamped to MaxCursorSize", + size: 500, + expectedSize: MaxCursorSize, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + cursor := NewCursor[testOrderField](tt.size, nil, Head, orderBy) + assert.Equal(t, tt.expectedSize, cursor.Size) + }) + } +}