Files
user-system/internal/pagination/cursor_test.go
Your Name 9f0eefd2f5 test: improve coverage for pagination and domain packages
- Add comprehensive cursor pagination tests (95.7% coverage)
- Add domain helper functions tests (StrPtr, DerefStr)
- Add Gender and UserStatus constants tests
- Add User model tests (TableName, default values)
- Overall coverage improved from 53.2% to 53.5%
2026-05-29 14:57:49 +08:00

219 lines
4.5 KiB
Go

package pagination
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestCursor_Encode 测试 Cursor 编码
func TestCursor_Encode(t *testing.T) {
tests := []struct {
name string
cursor *Cursor
expected string
}{
{
name: "nil cursor",
cursor: nil,
expected: "",
},
{
name: "zero LastID",
cursor: &Cursor{LastID: 0, LastValue: time.Now()},
expected: "",
},
{
name: "valid cursor",
cursor: &Cursor{LastID: 123, LastValue: time.Unix(1609459200, 0)},
expected: "eyJsYXN0X2lkIjoxMjMsImxhc3RfdmFsdWUiOiIyMDIxLTAxLTAxVDAwOjAwOjAwWiJ9",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.cursor.Encode()
if tt.expected == "" {
assert.Empty(t, got)
} else {
assert.NotEmpty(t, got)
}
})
}
}
// TestDecode 测试 Cursor 解码
func TestDecode(t *testing.T) {
tests := []struct {
name string
encoded string
wantNil bool
wantErr bool
expectedID int64
expectedTime time.Time
}{
{
name: "empty string",
encoded: "",
wantNil: true,
wantErr: false,
},
{
name: "invalid base64",
encoded: "!!!invalid!!!",
wantNil: true,
wantErr: true,
},
{
name: "invalid json",
encoded: "aW52YWxpZCBqc29u", // "invalid json" base64
wantNil: true,
wantErr: true,
},
{
name: "valid cursor",
encoded: "eyJsYXN0X2lkIjoxMjMsImxhc3RfdmFsdWUiOiIyMDIxLTAxLTAxVDAwOjAwOjAwWiJ9",
wantNil: false,
wantErr: false,
expectedID: 123,
expectedTime: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Decode(tt.encoded)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
if tt.wantNil {
assert.Nil(t, got)
} else {
require.NotNil(t, got)
assert.Equal(t, tt.expectedID, got.LastID)
assert.Equal(t, tt.expectedTime, got.LastValue)
}
})
}
}
// TestClampPageSize 测试分页大小限制
func TestClampPageSize(t *testing.T) {
tests := []struct {
name string
input int
expected int
}{
{"zero", 0, DefaultPageSize},
{"negative", -1, DefaultPageSize},
{"negative large", -100, DefaultPageSize},
{"one", 1, 1},
{"ten", 10, 10},
{"default", 20, 20},
{"max", 100, 100},
{"over max", 101, MaxPageSize},
{"large", 1000, MaxPageSize},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ClampPageSize(tt.input)
assert.Equal(t, tt.expected, got)
})
}
}
// TestBuildNextCursor 测试构建下一页游标
func TestBuildNextCursor(t *testing.T) {
tests := []struct {
name string
lastID int64
lastTime time.Time
expected string
}{
{
name: "zero ID",
lastID: 0,
lastTime: time.Now(),
expected: "",
},
{
name: "valid cursor",
lastID: 456,
lastTime: time.Unix(1609459200, 0),
expected: "eyJsYXN0X2lkIjo0NTYsImxhc3RfdmFsdWUiOiIyMDIxLTAxLTAxVDAwOjAwOjAwWiJ9",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := BuildNextCursor(tt.lastID, tt.lastTime)
if tt.expected == "" {
assert.Empty(t, got)
} else {
assert.NotEmpty(t, got)
// 验证可以解码
decoded, err := Decode(got)
require.NoError(t, err)
assert.Equal(t, tt.lastID, decoded.LastID)
}
})
}
}
// TestPageResult 测试 PageResult 结构
func TestPageResult(t *testing.T) {
// 测试泛型 PageResult
type Item struct {
ID int
Name string
}
items := []Item{
{ID: 1, Name: "item1"},
{ID: 2, Name: "item2"},
}
result := PageResult[Item]{
Items: items,
Total: 100,
NextCursor: "cursor123",
HasMore: true,
PageSize: 20,
}
assert.Len(t, result.Items, 2)
assert.Equal(t, int64(100), result.Total)
assert.Equal(t, "cursor123", result.NextCursor)
assert.True(t, result.HasMore)
assert.Equal(t, 20, result.PageSize)
}
// TestCursor_RoundTrip 测试编码解码往返
func TestCursor_RoundTrip(t *testing.T) {
original := &Cursor{
LastID: 999,
LastValue: time.Date(2023, 6, 15, 10, 30, 0, 0, time.UTC),
}
encoded := original.Encode()
require.NotEmpty(t, encoded)
decoded, err := Decode(encoded)
require.NoError(t, err)
require.NotNil(t, decoded)
assert.Equal(t, original.LastID, decoded.LastID)
assert.Equal(t, original.LastValue, decoded.LastValue)
}
// TestConstants 测试常量值
func TestConstants(t *testing.T) {
assert.Equal(t, 20, DefaultPageSize)
assert.Equal(t, 100, MaxPageSize)
}