145 lines
4.0 KiB
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])
|
|
}
|