Files
cursor/edge_test.go

145 lines
4.0 KiB
Go

package cursor
import (
"errors"
"testing"
"time"
"gitea.auvem.com/go-toolkit/dbx"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestBuildEdgesHasNextPageTupleOrdering(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
registerMeetingCursorColumns(t)
when := time.Date(2026, 6, 23, 5, 0, 0, 0, time.UTC)
base := NewCursor(
NewStringValue("", Meeting.ID),
Meeting.StartTime,
OrderDescending,
)
type meetingRow struct {
id string
start time.Time
}
items := []*meetingRow{
{id: "3FeXKOY42znOmyxxq3IEk5LJg98", start: time.Date(2026, 6, 26, 2, 0, 0, 0, time.UTC)},
{id: "3FWPfH9K7SOAikWv67BgKniF9E4", start: when},
{id: "3FWPabTpRGdmTydnULNbKpWrWhG", start: when},
}
cursorFunc := func(row *meetingRow) (GenericCursor, error) {
return base.CopyWithVals(
NewStringValue(row.id, Meeting.ID),
NewTimestampValue(row.start, Meeting.StartTime),
), nil
}
var endCursor GenericCursor
countFn := func(_ dbx.Queryable, _, end GenericCursor) (QueryCountResult, error) {
endCursor = end
return QueryCountResult{Total: 3, After: 0}, nil
}
conn, err := BuildEdges(nil, countFn, items, cursorFunc)
require.NoError(err)
require.NotNil(conn)
assert.False(conn.PageInfo.HasNextPage)
require.NotNil(endCursor)
assert.Equal("3FWPabTpRGdmTydnULNbKpWrWhG", endCursor.GenericIndex().(*StringValue).Val)
}
func TestBuildEdgesEmptyList(t *testing.T) {
countFn := func(_ dbx.Queryable, _, _ GenericCursor) (QueryCountResult, error) {
t.Fatal("countFn should not be called for empty list")
return QueryCountResult{}, nil
}
conn, err := BuildEdges(nil, countFn, []*int{}, func(*int) (GenericCursor, error) {
return nil, errors.New("unreachable")
})
require.NoError(t, err)
require.NotNil(t, conn)
assert.Empty(t, conn.Edges)
assert.False(t, conn.PageInfo.HasNextPage)
assert.False(t, conn.PageInfo.HasPreviousPage)
assert.Equal(t, 0, conn.TotalCount)
}
func TestBuildEdgesPaginationFlags(t *testing.T) {
RegisterColumn(User.ID)
cursorFunc := func(id *int) (GenericCursor, error) {
return NewCursor(NewInt64Value(int64(*id), User.ID), User.ID, OrderDescending), nil
}
id1, id2 := 1, 2
conn, err := BuildEdges(nil, func(_ dbx.Queryable, _, _ GenericCursor) (QueryCountResult, error) {
return QueryCountResult{Total: 10, After: 5, Before: 3}, nil
}, []*int{&id1, &id2}, cursorFunc)
require.NoError(t, err)
assert.True(t, conn.PageInfo.HasNextPage)
assert.True(t, conn.PageInfo.HasPreviousPage)
assert.Equal(t, 10, conn.TotalCount)
require.NotNil(t, conn.PageInfo.StartCursor)
require.NotNil(t, conn.PageInfo.EndCursor)
}
func TestBuildEdgesErrors(t *testing.T) {
RegisterColumn(User.ID)
cursorFunc := func(id *int) (GenericCursor, error) {
return NewCursor(NewInt64Value(int64(*id), User.ID), User.ID, OrderDescending), nil
}
countFn := func(_ dbx.Queryable, _, _ GenericCursor) (QueryCountResult, error) {
return QueryCountResult{}, nil
}
t.Run("nil item", func(t *testing.T) {
id := 1
_, err := BuildEdges(nil, countFn, []*int{&id, nil}, cursorFunc)
require.Error(t, err)
assert.Contains(t, err.Error(), "item at index 1 is nil")
})
t.Run("cursor func error", func(t *testing.T) {
cursorErr := errors.New("cursor failed")
id := 1
_, err := BuildEdges(nil, countFn, []*int{&id}, func(*int) (GenericCursor, error) {
return nil, cursorErr
})
require.Error(t, err)
assert.ErrorIs(t, err, cursorErr)
})
t.Run("count fn error", func(t *testing.T) {
countErr := errors.New("count failed")
id := 1
_, err := BuildEdges(nil, func(_ dbx.Queryable, _, _ GenericCursor) (QueryCountResult, error) {
return QueryCountResult{}, countErr
}, []*int{&id}, cursorFunc)
require.Error(t, err)
assert.ErrorIs(t, err, countErr)
})
}
func TestExtractNodes(t *testing.T) {
a, b := 1, 2
conn := &Connection[int]{
Edges: []*Edge[int]{
{Node: &a, Cursor: "c1"},
{Node: &b, Cursor: "c2"},
},
}
nodes := ExtractNodes(conn)
require.Len(t, nodes, 2)
assert.Equal(t, 1, *nodes[0])
assert.Equal(t, 2, *nodes[1])
}