refactor: tribe snapshot - cursor pagination
This commit is contained in:
parent
41cb1d042e
commit
5fa98ce0b6
|
@ -58,17 +58,22 @@ func (repo *TribeSnapshotBunRepository) Create(ctx context.Context, params ...do
|
|||
func (repo *TribeSnapshotBunRepository) List(
|
||||
ctx context.Context,
|
||||
params domain.ListTribeSnapshotsParams,
|
||||
) (domain.TribeSnapshots, error) {
|
||||
) (domain.ListTribeSnapshotsResult, error) {
|
||||
var tribeSnapshots bunmodel.TribeSnapshots
|
||||
|
||||
if err := repo.db.NewSelect().
|
||||
Model(&tribeSnapshots).
|
||||
Apply(listTribeSnapshotsParamsApplier{params: params}.apply).
|
||||
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, fmt.Errorf("couldn't select tribe snapshots from the db: %w", err)
|
||||
return domain.ListTribeSnapshotsResult{}, fmt.Errorf("couldn't select tribe snapshots from the db: %w", err)
|
||||
}
|
||||
|
||||
return tribeSnapshots.ToDomain()
|
||||
converted, err := tribeSnapshots.ToDomain()
|
||||
if err != nil {
|
||||
return domain.ListTribeSnapshotsResult{}, err
|
||||
}
|
||||
|
||||
return domain.NewListTribeSnapshotsResult(separateListResultAndNext(converted, params.Limit()))
|
||||
}
|
||||
|
||||
type listTribeSnapshotsParamsApplier struct {
|
||||
|
@ -80,6 +85,10 @@ func (a listTribeSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQu
|
|||
q = q.Where("ts.server_key IN (?)", bun.In(serverKeys))
|
||||
}
|
||||
|
||||
if tribeIDs := a.params.TribeIDs(); len(tribeIDs) > 0 {
|
||||
q = q.Where("ts.tribe_id IN (?)", bun.In(tribeIDs))
|
||||
}
|
||||
|
||||
for _, s := range a.params.Sort() {
|
||||
column, dir, err := a.sortToColumnAndDirection(s)
|
||||
if err != nil {
|
||||
|
@ -89,7 +98,49 @@ func (a listTribeSnapshotsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQu
|
|||
q.OrderExpr("? ?", column, dir.Bun())
|
||||
}
|
||||
|
||||
return q.Limit(a.params.Limit()).Offset(a.params.Offset())
|
||||
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
|
||||
}
|
||||
|
||||
func (a listTribeSnapshotsParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQuery {
|
||||
cursor := a.params.Cursor()
|
||||
|
||||
if cursor.IsZero() {
|
||||
return q
|
||||
}
|
||||
|
||||
sort := a.params.Sort()
|
||||
cursorApplier := cursorPaginationApplier{
|
||||
data: make([]cursorPaginationApplierDataElement, 0, len(sort)),
|
||||
}
|
||||
|
||||
for _, s := range sort {
|
||||
var err error
|
||||
var el cursorPaginationApplierDataElement
|
||||
|
||||
el.column, el.direction, err = a.sortToColumnAndDirection(s)
|
||||
if err != nil {
|
||||
return q.Err(err)
|
||||
}
|
||||
|
||||
switch s {
|
||||
case domain.TribeSnapshotSortIDASC,
|
||||
domain.TribeSnapshotSortIDDESC:
|
||||
el.value = cursor.ID()
|
||||
el.unique = true
|
||||
case domain.TribeSnapshotSortServerKeyASC,
|
||||
domain.TribeSnapshotSortServerKeyDESC:
|
||||
el.value = cursor.ServerKey()
|
||||
case domain.TribeSnapshotSortDateASC,
|
||||
domain.TribeSnapshotSortDateDESC:
|
||||
el.value = cursor.Date()
|
||||
default:
|
||||
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
|
||||
}
|
||||
|
||||
cursorApplier.data = append(cursorApplier.data, el)
|
||||
}
|
||||
|
||||
return q.Apply(cursorApplier.apply)
|
||||
}
|
||||
|
||||
func (a listTribeSnapshotsParamsApplier) sortToColumnAndDirection(
|
||||
|
|
|
@ -296,6 +296,115 @@ func testPlayerSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repo
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor serverKeys sort=[id ASC]",
|
||||
params: func(t *testing.T) domain.ListPlayerSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListPlayerSnapshotsParams()
|
||||
|
||||
res, err := repos.playerSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.PlayerSnapshots()), 2)
|
||||
|
||||
require.NoError(t, params.SetSort([]domain.PlayerSnapshotSort{domain.PlayerSnapshotSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.PlayerSnapshots()[1].ServerKey()}))
|
||||
cursor, err := res.PlayerSnapshots()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListPlayerSnapshotsParams, res domain.ListPlayerSnapshotsResult) {
|
||||
t.Helper()
|
||||
|
||||
serverKeys := params.ServerKeys()
|
||||
|
||||
playerSnapshots := res.PlayerSnapshots()
|
||||
assert.NotEmpty(t, len(playerSnapshots))
|
||||
for _, ps := range playerSnapshots {
|
||||
assert.GreaterOrEqual(t, ps.ID(), params.Cursor().ID())
|
||||
assert.True(t, slices.Contains(serverKeys, ps.ServerKey()))
|
||||
}
|
||||
assert.True(t, slices.IsSortedFunc(playerSnapshots, func(a, b domain.PlayerSnapshot) int {
|
||||
return cmp.Compare(a.ID(), b.ID())
|
||||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor sort=[serverKey ASC, id ASC]",
|
||||
params: func(t *testing.T) domain.ListPlayerSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListPlayerSnapshotsParams()
|
||||
require.NoError(t, params.SetSort([]domain.PlayerSnapshotSort{
|
||||
domain.PlayerSnapshotSortServerKeyASC,
|
||||
domain.PlayerSnapshotSortIDASC,
|
||||
}))
|
||||
|
||||
res, err := repos.playerSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.PlayerSnapshots()), 2)
|
||||
|
||||
cursor, err := res.PlayerSnapshots()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListPlayerSnapshotsParams, res domain.ListPlayerSnapshotsResult) {
|
||||
t.Helper()
|
||||
playerSnapshots := res.PlayerSnapshots()
|
||||
assert.NotEmpty(t, len(playerSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(playerSnapshots, func(a, b domain.PlayerSnapshot) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
assert.GreaterOrEqual(t, playerSnapshots[0].ID(), params.Cursor().ID())
|
||||
for _, ps := range playerSnapshots {
|
||||
assert.GreaterOrEqual(t, ps.ServerKey(), params.Cursor().ServerKey())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor sort=[serverKey DESC, id DESC]",
|
||||
params: func(t *testing.T) domain.ListPlayerSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListPlayerSnapshotsParams()
|
||||
require.NoError(t, params.SetSort([]domain.PlayerSnapshotSort{
|
||||
domain.PlayerSnapshotSortServerKeyDESC,
|
||||
domain.PlayerSnapshotSortIDDESC,
|
||||
}))
|
||||
|
||||
res, err := repos.playerSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.PlayerSnapshots()), 2)
|
||||
|
||||
cursor, err := res.PlayerSnapshots()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListPlayerSnapshotsParams, res domain.ListPlayerSnapshotsResult) {
|
||||
t.Helper()
|
||||
playerSnapshots := res.PlayerSnapshots()
|
||||
assert.NotEmpty(t, len(playerSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(playerSnapshots, func(a, b domain.PlayerSnapshot) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
) * -1
|
||||
}))
|
||||
assert.LessOrEqual(t, playerSnapshots[0].ID(), params.Cursor().ID())
|
||||
for _, ps := range playerSnapshots {
|
||||
assert.LessOrEqual(t, ps.ServerKey(), params.Cursor().ServerKey())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: limit=2",
|
||||
params: func(t *testing.T) domain.ListPlayerSnapshotsParams {
|
||||
|
|
|
@ -65,7 +65,7 @@ type tribeChangeRepository interface {
|
|||
|
||||
type tribeSnapshotRepository interface {
|
||||
Create(ctx context.Context, params ...domain.CreateTribeSnapshotParams) error
|
||||
List(ctx context.Context, params domain.ListTribeSnapshotsParams) (domain.TribeSnapshots, error)
|
||||
List(ctx context.Context, params domain.ListTribeSnapshotsParams) (domain.ListTribeSnapshotsResult, error)
|
||||
}
|
||||
|
||||
type playerSnapshotRepository interface {
|
||||
|
|
|
@ -30,7 +30,8 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
|
||||
require.NotEmpty(t, params)
|
||||
|
||||
tribeSnapshots, err := repos.tribeSnapshot.List(ctx, domain.NewListTribeSnapshotsParams())
|
||||
res, err := repos.tribeSnapshot.List(ctx, domain.NewListTribeSnapshotsParams())
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
require.NoError(t, err)
|
||||
for i, p := range params {
|
||||
date := p.Date().Format(dateFormat)
|
||||
|
@ -62,8 +63,9 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
|
||||
require.NotEmpty(t, params)
|
||||
|
||||
tribeSnapshots, err := repos.tribeSnapshot.List(ctx, domain.NewListTribeSnapshotsParams())
|
||||
res, err := repos.tribeSnapshot.List(ctx, domain.NewListTribeSnapshotsParams())
|
||||
require.NoError(t, err)
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
|
||||
m := make(map[string][]int)
|
||||
|
||||
|
@ -120,16 +122,11 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
|
||||
repos := newRepos(t)
|
||||
|
||||
tribeSnapshots, listTribeSnapshotsErr := repos.tribeSnapshot.List(ctx, domain.NewListTribeSnapshotsParams())
|
||||
require.NoError(t, listTribeSnapshotsErr)
|
||||
require.NotEmpty(t, tribeSnapshots)
|
||||
randTribeSnapshot := tribeSnapshots[0]
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
params func(t *testing.T) domain.ListTribeSnapshotsParams
|
||||
assertTribeSnapshots func(t *testing.T, params domain.ListTribeSnapshotsParams, tribeSnapshots domain.TribeSnapshots)
|
||||
assertError func(t *testing.T, err error)
|
||||
name string
|
||||
params func(t *testing.T) domain.ListTribeSnapshotsParams
|
||||
assertResult func(t *testing.T, params domain.ListTribeSnapshotsParams, res domain.ListTribeSnapshotsResult)
|
||||
assertError func(t *testing.T, err error)
|
||||
}{
|
||||
{
|
||||
name: "OK: default params",
|
||||
|
@ -137,12 +134,13 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
t.Helper()
|
||||
return domain.NewListTribeSnapshotsParams()
|
||||
},
|
||||
assertTribeSnapshots: func(
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
_ domain.ListTribeSnapshotsParams,
|
||||
tribeSnapshots domain.TribeSnapshots,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Or(
|
||||
|
@ -151,6 +149,8 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
assert.False(t, res.Self().IsZero())
|
||||
assert.True(t, res.Next().IsZero())
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -164,12 +164,13 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
}))
|
||||
return params
|
||||
},
|
||||
assertTribeSnapshots: func(
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
_ domain.ListTribeSnapshotsParams,
|
||||
tribeSnapshots domain.TribeSnapshots,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Or(
|
||||
|
@ -189,12 +190,13 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
}))
|
||||
return params
|
||||
},
|
||||
assertTribeSnapshots: func(
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
_ domain.ListTribeSnapshotsParams,
|
||||
tribeSnapshots domain.TribeSnapshots,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Compare(a.ID(), b.ID())
|
||||
|
@ -211,12 +213,13 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
}))
|
||||
return params
|
||||
},
|
||||
assertTribeSnapshots: func(
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
_ domain.ListTribeSnapshotsParams,
|
||||
tribeSnapshots domain.TribeSnapshots,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Compare(a.ID(), b.ID()) * -1
|
||||
|
@ -224,43 +227,198 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
},
|
||||
},
|
||||
{
|
||||
name: fmt.Sprintf("OK: serverKeys=[%s]", randTribeSnapshot.ServerKey()),
|
||||
name: "OK: serverKeys",
|
||||
params: func(t *testing.T) domain.ListTribeSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
|
||||
res, err := repos.tribeSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, res.TribeSnapshots())
|
||||
randTribeSnapshot := res.TribeSnapshots()[0]
|
||||
|
||||
require.NoError(t, params.SetServerKeys([]string{randTribeSnapshot.ServerKey()}))
|
||||
|
||||
return params
|
||||
},
|
||||
assertTribeSnapshots: func(
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
params domain.ListTribeSnapshotsParams,
|
||||
tribeSnapshots domain.TribeSnapshots,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
serverKeys := params.ServerKeys()
|
||||
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotZero(t, tribeSnapshots)
|
||||
for _, ts := range tribeSnapshots {
|
||||
assert.True(t, slices.Contains(serverKeys, ts.ServerKey()))
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: offset=1 limit=2",
|
||||
name: "OK: tribeIDs serverKeys",
|
||||
params: func(t *testing.T) domain.ListTribeSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
|
||||
res, err := repos.tribeSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, res.TribeSnapshots())
|
||||
randTribeSnapshot := res.TribeSnapshots()[0]
|
||||
|
||||
require.NoError(t, params.SetServerKeys([]string{randTribeSnapshot.ServerKey()}))
|
||||
require.NoError(t, params.SetTribeIDs([]int{randTribeSnapshot.TribeID()}))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
params domain.ListTribeSnapshotsParams,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
serverKeys := params.ServerKeys()
|
||||
tribeIDs := params.TribeIDs()
|
||||
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotZero(t, tribeSnapshots)
|
||||
for _, ts := range tribeSnapshots {
|
||||
assert.True(t, slices.Contains(serverKeys, ts.ServerKey()))
|
||||
assert.True(t, slices.Contains(tribeIDs, ts.TribeID()))
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor serverKeys sort=[id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribeSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
|
||||
res, err := repos.tribeSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.TribeSnapshots()), 2)
|
||||
|
||||
require.NoError(t, params.SetSort([]domain.TribeSnapshotSort{domain.TribeSnapshotSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.TribeSnapshots()[1].ServerKey()}))
|
||||
cursor, err := res.TribeSnapshots()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListTribeSnapshotsParams, res domain.ListTribeSnapshotsResult) {
|
||||
t.Helper()
|
||||
|
||||
serverKeys := params.ServerKeys()
|
||||
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
for _, ts := range tribeSnapshots {
|
||||
assert.GreaterOrEqual(t, ts.ID(), params.Cursor().ID())
|
||||
assert.True(t, slices.Contains(serverKeys, ts.ServerKey()))
|
||||
}
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Compare(a.ID(), b.ID())
|
||||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor sort=[serverKey ASC, id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribeSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
require.NoError(t, params.SetSort([]domain.TribeSnapshotSort{
|
||||
domain.TribeSnapshotSortServerKeyASC,
|
||||
domain.TribeSnapshotSortIDASC,
|
||||
}))
|
||||
|
||||
res, err := repos.tribeSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.TribeSnapshots()), 2)
|
||||
|
||||
cursor, err := res.TribeSnapshots()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListTribeSnapshotsParams, res domain.ListTribeSnapshotsResult) {
|
||||
t.Helper()
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
assert.GreaterOrEqual(t, tribeSnapshots[0].ID(), params.Cursor().ID())
|
||||
for _, ts := range tribeSnapshots {
|
||||
assert.GreaterOrEqual(t, ts.ServerKey(), params.Cursor().ServerKey())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor sort=[serverKey DESC, id DESC]",
|
||||
params: func(t *testing.T) domain.ListTribeSnapshotsParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
require.NoError(t, params.SetSort([]domain.TribeSnapshotSort{
|
||||
domain.TribeSnapshotSortServerKeyDESC,
|
||||
domain.TribeSnapshotSortIDDESC,
|
||||
}))
|
||||
|
||||
res, err := repos.tribeSnapshot.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.TribeSnapshots()), 2)
|
||||
|
||||
cursor, err := res.TribeSnapshots()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListTribeSnapshotsParams, res domain.ListTribeSnapshotsResult) {
|
||||
t.Helper()
|
||||
tribeSnapshots := res.TribeSnapshots()
|
||||
assert.NotEmpty(t, len(tribeSnapshots))
|
||||
assert.True(t, slices.IsSortedFunc(tribeSnapshots, func(a, b domain.TribeSnapshot) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
) * -1
|
||||
}))
|
||||
assert.LessOrEqual(t, tribeSnapshots[0].ID(), params.Cursor().ID())
|
||||
for _, ts := range tribeSnapshots {
|
||||
assert.LessOrEqual(t, ts.ServerKey(), params.Cursor().ServerKey())
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: limit=2",
|
||||
params: func(t *testing.T) domain.ListTribeSnapshotsParams {
|
||||
t.Helper()
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
require.NoError(t, params.SetOffset(1))
|
||||
require.NoError(t, params.SetLimit(2))
|
||||
return params
|
||||
},
|
||||
assertTribeSnapshots: func(
|
||||
assertResult: func(
|
||||
t *testing.T,
|
||||
params domain.ListTribeSnapshotsParams,
|
||||
tribeSnapshots domain.TribeSnapshots,
|
||||
res domain.ListTribeSnapshotsResult,
|
||||
) {
|
||||
t.Helper()
|
||||
assert.Len(t, tribeSnapshots, params.Limit())
|
||||
assert.Len(t, res.TribeSnapshots(), params.Limit())
|
||||
assert.False(t, res.Self().IsZero())
|
||||
assert.False(t, res.Next().IsZero())
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -281,7 +439,7 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
|
|||
|
||||
res, err := repos.tribeSnapshot.List(ctx, params)
|
||||
assertError(t, err)
|
||||
tt.assertTribeSnapshots(t, params, res)
|
||||
tt.assertResult(t, params, res)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package domaintest
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
"github.com/brianvoe/gofakeit/v7"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type TribeSnapshotCursorConfig struct {
|
||||
ID int
|
||||
ServerKey string
|
||||
Date time.Time
|
||||
}
|
||||
|
||||
func NewTribeSnapshotCursor(tb TestingTB, opts ...func(cfg *TribeSnapshotCursorConfig)) domain.TribeSnapshotCursor {
|
||||
tb.Helper()
|
||||
|
||||
cfg := &TribeSnapshotCursorConfig{
|
||||
ID: RandID(),
|
||||
ServerKey: RandServerKey(),
|
||||
Date: gofakeit.Date(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
|
||||
psc, err := domain.NewTribeSnapshotCursor(
|
||||
cfg.ID,
|
||||
cfg.ServerKey,
|
||||
cfg.Date,
|
||||
)
|
||||
require.NoError(tb, err)
|
||||
|
||||
return psc
|
||||
}
|
||||
|
||||
type TribeSnapshotConfig struct {
|
||||
ID int
|
||||
TribeID int
|
||||
ServerKey string
|
||||
NumMembers int
|
||||
NumVillages int
|
||||
Points int
|
||||
AllPoints int
|
||||
Rank int
|
||||
OD domain.OpponentsDefeated
|
||||
Dominance float64
|
||||
Date time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func NewTribeSnapshot(tb TestingTB, opts ...func(cfg *TribeSnapshotConfig)) domain.TribeSnapshot {
|
||||
tb.Helper()
|
||||
|
||||
now := time.Now()
|
||||
|
||||
cfg := &TribeSnapshotConfig{
|
||||
ID: RandID(),
|
||||
TribeID: RandID(),
|
||||
ServerKey: RandServerKey(),
|
||||
NumMembers: gofakeit.IntRange(1, 10000),
|
||||
NumVillages: gofakeit.IntRange(1, 10000),
|
||||
Points: gofakeit.IntRange(1, 10000),
|
||||
AllPoints: gofakeit.IntRange(1, 10000),
|
||||
Rank: gofakeit.IntRange(1, 10000),
|
||||
OD: NewOpponentsDefeated(tb),
|
||||
Dominance: gofakeit.Float64Range(0.1, 100),
|
||||
Date: now,
|
||||
CreatedAt: now,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
|
||||
ts, err := domain.UnmarshalTribeSnapshotFromDatabase(
|
||||
cfg.ID,
|
||||
cfg.TribeID,
|
||||
cfg.ServerKey,
|
||||
cfg.NumMembers,
|
||||
cfg.NumVillages,
|
||||
cfg.Points,
|
||||
cfg.AllPoints,
|
||||
cfg.Rank,
|
||||
cfg.OD,
|
||||
cfg.Dominance,
|
||||
cfg.Date,
|
||||
cfg.CreatedAt,
|
||||
)
|
||||
require.NoError(tb, err)
|
||||
|
||||
return ts
|
||||
}
|
|
@ -245,6 +245,66 @@ func TestListPlayerSnapshotsParams_SetServerKeys(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListPlayerSnapshotsParams_SetPlayerIDs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
playerIDs []int
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
playerIDs: []int{
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: value < 1",
|
||||
args: args{
|
||||
playerIDs: []int{
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
0,
|
||||
domaintest.RandID(),
|
||||
},
|
||||
},
|
||||
expectedErr: domain.SliceElementValidationError{
|
||||
Model: "ListPlayerSnapshotsParams",
|
||||
Field: "playerIDs",
|
||||
Index: 3,
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 1,
|
||||
Current: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewListPlayerSnapshotsParams()
|
||||
|
||||
require.ErrorIs(t, params.SetPlayerIDs(tt.args.playerIDs), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.playerIDs, params.PlayerIDs())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListPlayerSnapshotsParams_SetSort(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -129,6 +129,14 @@ func (ts TribeSnapshot) CreatedAt() time.Time {
|
|||
return ts.createdAt
|
||||
}
|
||||
|
||||
func (ts TribeSnapshot) ToCursor() (TribeSnapshotCursor, error) {
|
||||
return NewTribeSnapshotCursor(ts.id, ts.serverKey, ts.date)
|
||||
}
|
||||
|
||||
func (ts TribeSnapshot) IsZero() bool {
|
||||
return ts == TribeSnapshot{}
|
||||
}
|
||||
|
||||
type TribeSnapshots []TribeSnapshot
|
||||
|
||||
type CreateTribeSnapshotParams struct {
|
||||
|
@ -250,11 +258,106 @@ func (s TribeSnapshotSort) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
type TribeSnapshotCursor struct {
|
||||
id int
|
||||
serverKey string
|
||||
date time.Time
|
||||
}
|
||||
|
||||
const tribeSnapshotCursorModelName = "TribeSnapshotCursor"
|
||||
|
||||
func NewTribeSnapshotCursor(id int, serverKey string, date time.Time) (TribeSnapshotCursor, error) {
|
||||
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
|
||||
return TribeSnapshotCursor{}, ValidationError{
|
||||
Model: tribeSnapshotCursorModelName,
|
||||
Field: "id",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateServerKey(serverKey); err != nil {
|
||||
return TribeSnapshotCursor{}, ValidationError{
|
||||
Model: tribeSnapshotCursorModelName,
|
||||
Field: "serverKey",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return TribeSnapshotCursor{
|
||||
id: id,
|
||||
serverKey: serverKey,
|
||||
date: date,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func decodeTribeSnapshotCursor(encoded string) (TribeSnapshotCursor, error) {
|
||||
m, err := decodeCursor(encoded)
|
||||
if err != nil {
|
||||
return TribeSnapshotCursor{}, err
|
||||
}
|
||||
|
||||
id, err := m.int("id")
|
||||
if err != nil {
|
||||
return TribeSnapshotCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
serverKey, err := m.string("serverKey")
|
||||
if err != nil {
|
||||
return TribeSnapshotCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
date, err := m.time("date")
|
||||
if err != nil {
|
||||
return TribeSnapshotCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
tsc, err := NewTribeSnapshotCursor(
|
||||
id,
|
||||
serverKey,
|
||||
date,
|
||||
)
|
||||
if err != nil {
|
||||
return TribeSnapshotCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
return tsc, nil
|
||||
}
|
||||
|
||||
func (tsc TribeSnapshotCursor) ID() int {
|
||||
return tsc.id
|
||||
}
|
||||
|
||||
func (tsc TribeSnapshotCursor) ServerKey() string {
|
||||
return tsc.serverKey
|
||||
}
|
||||
|
||||
func (tsc TribeSnapshotCursor) Date() time.Time {
|
||||
return tsc.date
|
||||
}
|
||||
|
||||
func (tsc TribeSnapshotCursor) IsZero() bool {
|
||||
return tsc == TribeSnapshotCursor{}
|
||||
}
|
||||
|
||||
func (tsc TribeSnapshotCursor) Encode() string {
|
||||
if tsc.IsZero() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return encodeCursor([]keyValuePair{
|
||||
{"id", tsc.id},
|
||||
{"serverKey", tsc.serverKey},
|
||||
{"date", tsc.date},
|
||||
})
|
||||
}
|
||||
|
||||
type ListTribeSnapshotsParams struct {
|
||||
serverKeys []string
|
||||
tribeIDs []int
|
||||
sort []TribeSnapshotSort
|
||||
cursor TribeSnapshotCursor
|
||||
limit int
|
||||
offset int
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -294,6 +397,27 @@ func (params *ListTribeSnapshotsParams) SetServerKeys(serverKeys []string) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) TribeIDs() []int {
|
||||
return params.tribeIDs
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) SetTribeIDs(tribeIDs []int) error {
|
||||
for i, id := range tribeIDs {
|
||||
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
|
||||
return SliceElementValidationError{
|
||||
Model: listTribeSnapshotsParamsModelName,
|
||||
Field: "tribeIDs",
|
||||
Index: i,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.tribeIDs = tribeIDs
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) Sort() []TribeSnapshotSort {
|
||||
return params.sort
|
||||
}
|
||||
|
@ -317,6 +441,30 @@ func (params *ListTribeSnapshotsParams) SetSort(sort []TribeSnapshotSort) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) Cursor() TribeSnapshotCursor {
|
||||
return params.cursor
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) SetCursor(cursor TribeSnapshotCursor) error {
|
||||
params.cursor = cursor
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) SetEncodedCursor(encoded string) error {
|
||||
decoded, err := decodeTribeSnapshotCursor(encoded)
|
||||
if err != nil {
|
||||
return ValidationError{
|
||||
Model: listTribeSnapshotsParamsModelName,
|
||||
Field: "cursor",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
params.cursor = decoded
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) Limit() int {
|
||||
return params.limit
|
||||
}
|
||||
|
@ -335,20 +483,56 @@ func (params *ListTribeSnapshotsParams) SetLimit(limit int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) Offset() int {
|
||||
return params.offset
|
||||
type ListTribeSnapshotsResult struct {
|
||||
snapshots TribeSnapshots
|
||||
self TribeSnapshotCursor
|
||||
next TribeSnapshotCursor
|
||||
}
|
||||
|
||||
func (params *ListTribeSnapshotsParams) SetOffset(offset int) error {
|
||||
if err := validateIntInRange(offset, 0, math.MaxInt); err != nil {
|
||||
return ValidationError{
|
||||
Model: listTribeSnapshotsParamsModelName,
|
||||
Field: "offset",
|
||||
Err: err,
|
||||
const listTribeSnapshotsResultModelName = "ListTribeSnapshotsResult"
|
||||
|
||||
func NewListTribeSnapshotsResult(
|
||||
snapshots TribeSnapshots,
|
||||
next TribeSnapshot,
|
||||
) (ListTribeSnapshotsResult, error) {
|
||||
var err error
|
||||
res := ListTribeSnapshotsResult{
|
||||
snapshots: snapshots,
|
||||
}
|
||||
|
||||
if len(snapshots) > 0 {
|
||||
res.self, err = snapshots[0].ToCursor()
|
||||
if err != nil {
|
||||
return ListTribeSnapshotsResult{}, ValidationError{
|
||||
Model: listTribeSnapshotsResultModelName,
|
||||
Field: "self",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.offset = offset
|
||||
if !next.IsZero() {
|
||||
res.next, err = next.ToCursor()
|
||||
if err != nil {
|
||||
return ListTribeSnapshotsResult{}, ValidationError{
|
||||
Model: listTribeSnapshotsResultModelName,
|
||||
Field: "next",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (res ListTribeSnapshotsResult) TribeSnapshots() TribeSnapshots {
|
||||
return res.snapshots
|
||||
}
|
||||
|
||||
func (res ListTribeSnapshotsResult) Self() TribeSnapshotCursor {
|
||||
return res.self
|
||||
}
|
||||
|
||||
func (res ListTribeSnapshotsResult) Next() TribeSnapshotCursor {
|
||||
return res.next
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain/domaintest"
|
||||
"github.com/brianvoe/gofakeit/v7"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -111,6 +112,87 @@ func TestTribeSnapshotSort_IsInConflict(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewTribeSnapshotCursor(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validTribeSnapshotCursor := domaintest.NewTribeSnapshotCursor(t)
|
||||
|
||||
type args struct {
|
||||
id int
|
||||
serverKey string
|
||||
date time.Time
|
||||
}
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
id: validTribeSnapshotCursor.ID(),
|
||||
serverKey: validTribeSnapshotCursor.ServerKey(),
|
||||
date: validTribeSnapshotCursor.Date(),
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
name: "ERR: id < 1",
|
||||
args: args{
|
||||
id: 0,
|
||||
serverKey: validTribeSnapshotCursor.ServerKey(),
|
||||
date: validTribeSnapshotCursor.Date(),
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "TribeSnapshotCursor",
|
||||
Field: "id",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 1,
|
||||
Current: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, serverKeyTest := range newServerKeyValidationTests() {
|
||||
tests = append(tests, test{
|
||||
name: serverKeyTest.name,
|
||||
args: args{
|
||||
id: validTribeSnapshotCursor.ID(),
|
||||
serverKey: serverKeyTest.key,
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "TribeSnapshotCursor",
|
||||
Field: "serverKey",
|
||||
Err: serverKeyTest.expectedErr,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
psc, err := domain.NewTribeSnapshotCursor(
|
||||
tt.args.id,
|
||||
tt.args.serverKey,
|
||||
tt.args.date,
|
||||
)
|
||||
require.ErrorIs(t, err, tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.id, psc.ID())
|
||||
assert.Equal(t, tt.args.serverKey, psc.ServerKey())
|
||||
assert.Equal(t, tt.args.date, psc.Date())
|
||||
assert.NotEmpty(t, psc.Encode())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListTribeSnapshotsParams_SetServerKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -165,6 +247,66 @@ func TestListTribeSnapshotsParams_SetServerKeys(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListTribeSnapshotsParams_SetTribeIDs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
tribeIDs []int
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
tribeIDs: []int{
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: value < 1",
|
||||
args: args{
|
||||
tribeIDs: []int{
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
domaintest.RandID(),
|
||||
0,
|
||||
domaintest.RandID(),
|
||||
},
|
||||
},
|
||||
expectedErr: domain.SliceElementValidationError{
|
||||
Model: "ListTribeSnapshotsParams",
|
||||
Field: "tribeIDs",
|
||||
Index: 3,
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 1,
|
||||
Current: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
|
||||
require.ErrorIs(t, params.SetTribeIDs(tt.args.tribeIDs), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.tribeIDs, params.TribeIDs())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListTribeSnapshotsParams_SetSort(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -254,6 +396,86 @@ func TestListTribeSnapshotsParams_SetSort(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListTribeSnapshotsParams_SetEncodedCursor(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validCursor := domaintest.NewTribeSnapshotCursor(t)
|
||||
|
||||
type args struct {
|
||||
cursor string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedCursor domain.TribeSnapshotCursor
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
cursor: validCursor.Encode(),
|
||||
},
|
||||
expectedCursor: validCursor,
|
||||
},
|
||||
{
|
||||
name: "ERR: len(cursor) < 1",
|
||||
args: args{
|
||||
cursor: "",
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "ListTribeSnapshotsParams",
|
||||
Field: "cursor",
|
||||
Err: domain.LenOutOfRangeError{
|
||||
Min: 1,
|
||||
Max: 1000,
|
||||
Current: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: len(cursor) > 1000",
|
||||
args: args{
|
||||
cursor: gofakeit.LetterN(1001),
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "ListTribeSnapshotsParams",
|
||||
Field: "cursor",
|
||||
Err: domain.LenOutOfRangeError{
|
||||
Min: 1,
|
||||
Max: 1000,
|
||||
Current: 1001,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: malformed base64",
|
||||
args: args{
|
||||
cursor: "112345",
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "ListTribeSnapshotsParams",
|
||||
Field: "cursor",
|
||||
Err: domain.ErrInvalidCursor,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
|
||||
require.ErrorIs(t, params.SetEncodedCursor(tt.args.cursor), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.cursor, params.Cursor().Encode())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListTribeSnapshotsParams_SetLimit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -317,51 +539,49 @@ func TestListTribeSnapshotsParams_SetLimit(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListTribeSnapshotsParams_SetOffset(t *testing.T) {
|
||||
func TestNewListTribeSnapshotsResult(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
offset int
|
||||
snapshots := domain.TribeSnapshots{
|
||||
domaintest.NewTribeSnapshot(t),
|
||||
domaintest.NewTribeSnapshot(t),
|
||||
domaintest.NewTribeSnapshot(t),
|
||||
}
|
||||
next := domaintest.NewTribeSnapshot(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
offset: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: offset < 0",
|
||||
args: args{
|
||||
offset: -1,
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "ListTribeSnapshotsParams",
|
||||
Field: "offset",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
t.Run("OK: with next", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
res, err := domain.NewListTribeSnapshotsResult(snapshots, next)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, snapshots, res.TribeSnapshots())
|
||||
assert.Equal(t, snapshots[0].ID(), res.Self().ID())
|
||||
assert.Equal(t, snapshots[0].ServerKey(), res.Self().ServerKey())
|
||||
assert.Equal(t, snapshots[0].Date(), res.Self().Date())
|
||||
assert.Equal(t, next.ID(), res.Next().ID())
|
||||
assert.Equal(t, next.ServerKey(), res.Next().ServerKey())
|
||||
assert.Equal(t, next.Date(), res.Next().Date())
|
||||
})
|
||||
|
||||
params := domain.NewListTribeSnapshotsParams()
|
||||
t.Run("OK: without next", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.ErrorIs(t, params.SetOffset(tt.args.offset), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.offset, params.Offset())
|
||||
})
|
||||
}
|
||||
res, err := domain.NewListTribeSnapshotsResult(snapshots, domain.TribeSnapshot{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, snapshots, res.TribeSnapshots())
|
||||
assert.Equal(t, snapshots[0].ID(), res.Self().ID())
|
||||
assert.Equal(t, snapshots[0].ServerKey(), res.Self().ServerKey())
|
||||
assert.Equal(t, snapshots[0].Date(), res.Self().Date())
|
||||
assert.True(t, res.Next().IsZero())
|
||||
})
|
||||
|
||||
t.Run("OK: 0 snapshots", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
res, err := domain.NewListTribeSnapshotsResult(nil, domain.TribeSnapshot{})
|
||||
require.NoError(t, err)
|
||||
assert.Zero(t, res.TribeSnapshots())
|
||||
assert.True(t, res.Self().IsZero())
|
||||
assert.True(t, res.Next().IsZero())
|
||||
})
|
||||
}
|
||||
|
|
|
@ -225,14 +225,10 @@ func TestSnapshotCreation(t *testing.T) {
|
|||
cnt := 0
|
||||
|
||||
for {
|
||||
snapshots, err := tribeSnapshotRepo.List(ctx, listSnapshotsParams)
|
||||
res, err := tribeSnapshotRepo.List(ctx, listSnapshotsParams)
|
||||
require.NoError(collect, err)
|
||||
|
||||
if len(snapshots) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
for _, ts := range snapshots {
|
||||
for _, ts := range res.TribeSnapshots() {
|
||||
cnt++
|
||||
msg := fmt.Sprintf("TribeID=%d,ServerKey=%s", ts.TribeID(), ts.ServerKey())
|
||||
|
||||
|
@ -264,7 +260,11 @@ func TestSnapshotCreation(t *testing.T) {
|
|||
assert.WithinDuration(collect, time.Now(), ts.Date(), 24*time.Hour, msg)
|
||||
}
|
||||
|
||||
require.NoError(collect, listSnapshotsParams.SetOffset(listSnapshotsParams.Offset()+listSnapshotsParams.Limit()))
|
||||
if res.Next().IsZero() {
|
||||
break
|
||||
}
|
||||
|
||||
require.NoError(collect, listSnapshotsParams.SetCursor(res.Next()))
|
||||
}
|
||||
|
||||
//nolint:testifylint
|
||||
|
|
Loading…
Reference in New Issue