refactor: tribe change - cursor pagination #25
|
@ -52,17 +52,22 @@ func (repo *TribeChangeBunRepository) Create(ctx context.Context, params ...doma
|
|||
func (repo *TribeChangeBunRepository) List(
|
||||
ctx context.Context,
|
||||
params domain.ListTribeChangesParams,
|
||||
) (domain.TribeChanges, error) {
|
||||
) (domain.ListTribeChangesResult, error) {
|
||||
var tribeChanges bunmodel.TribeChanges
|
||||
|
||||
if err := repo.db.NewSelect().
|
||||
Model(&tribeChanges).
|
||||
Apply(listTribeChangesParamsApplier{params: params}.apply).
|
||||
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, fmt.Errorf("couldn't select tribe changes from the db: %w", err)
|
||||
return domain.ListTribeChangesResult{}, fmt.Errorf("couldn't select tribe changes from the db: %w", err)
|
||||
}
|
||||
|
||||
return tribeChanges.ToDomain()
|
||||
converted, err := tribeChanges.ToDomain()
|
||||
if err != nil {
|
||||
return domain.ListTribeChangesResult{}, err
|
||||
}
|
||||
|
||||
return domain.NewListTribeChangesResult(separateListResultAndNext(converted, params.Limit()))
|
||||
}
|
||||
|
||||
type listTribeChangesParamsApplier struct {
|
||||
|
@ -94,5 +99,57 @@ func (a listTribeChangesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuer
|
|||
}
|
||||
}
|
||||
|
||||
return q.Limit(a.params.Limit()).Offset(a.params.Offset())
|
||||
return q.Limit(a.params.Limit() + 1).Apply(a.applyCursor)
|
||||
}
|
||||
|
||||
func (a listTribeChangesParamsApplier) 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 el cursorPaginationApplierDataElement
|
||||
|
||||
switch s {
|
||||
case domain.TribeChangeSortIDASC:
|
||||
el.value = cursor.ID()
|
||||
el.unique = true
|
||||
el.column = "tc.id"
|
||||
el.direction = sortDirectionASC
|
||||
case domain.TribeChangeSortIDDESC:
|
||||
el.value = cursor.ID()
|
||||
el.unique = true
|
||||
el.column = "tc.id"
|
||||
el.direction = sortDirectionDESC
|
||||
case domain.TribeChangeSortServerKeyASC:
|
||||
el.value = cursor.ServerKey()
|
||||
el.column = "tc.server_key"
|
||||
el.direction = sortDirectionASC
|
||||
case domain.TribeChangeSortServerKeyDESC:
|
||||
el.value = cursor.ServerKey()
|
||||
el.column = "tc.server_key"
|
||||
el.direction = sortDirectionDESC
|
||||
case domain.TribeChangeSortCreatedAtASC:
|
||||
el.value = cursor.CreatedAt()
|
||||
el.column = "tc.created_at"
|
||||
el.direction = sortDirectionASC
|
||||
case domain.TribeChangeSortCreatedAtDESC:
|
||||
el.value = cursor.CreatedAt()
|
||||
el.column = "tc.created_at"
|
||||
el.direction = sortDirectionDESC
|
||||
default:
|
||||
return q.Err(fmt.Errorf("%s: %w", s.String(), errInvalidSortValue))
|
||||
}
|
||||
|
||||
cursorApplier.data = append(cursorApplier.data, el)
|
||||
}
|
||||
|
||||
return q.Apply(cursorApplier.apply)
|
||||
}
|
||||
|
|
|
@ -431,12 +431,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
|
||||
require.NoError(t, params.SetSort([]domain.EnnoblementSort{domain.EnnoblementSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.Ennoblements()[1].ServerKey()}))
|
||||
require.NoError(
|
||||
t,
|
||||
params.SetCursor(domaintest.NewEnnoblementCursor(t, func(cfg *domaintest.EnnoblementCursorConfig) {
|
||||
cfg.ID = res.Ennoblements()[1].ID()
|
||||
})),
|
||||
)
|
||||
cursor, err := res.Ennoblements()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -475,13 +472,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Ennoblements()), 2)
|
||||
|
||||
require.NoError(
|
||||
t,
|
||||
params.SetCursor(domaintest.NewEnnoblementCursor(t, func(cfg *domaintest.EnnoblementCursorConfig) {
|
||||
cfg.ID = res.Ennoblements()[1].ID()
|
||||
cfg.ServerKey = res.Ennoblements()[1].ServerKey()
|
||||
})),
|
||||
)
|
||||
cursor, err := res.Ennoblements()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -520,13 +513,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Ennoblements()), 2)
|
||||
|
||||
require.NoError(
|
||||
t,
|
||||
params.SetCursor(domaintest.NewEnnoblementCursor(t, func(cfg *domaintest.EnnoblementCursorConfig) {
|
||||
cfg.ID = res.Ennoblements()[1].ID()
|
||||
cfg.ServerKey = res.Ennoblements()[1].ServerKey()
|
||||
})),
|
||||
)
|
||||
cursor, err := res.Ennoblements()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
|
|
@ -531,9 +531,9 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
|
||||
require.NoError(t, params.SetSort([]domain.PlayerSort{domain.PlayerSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.Players()[1].ServerKey()}))
|
||||
require.NoError(t, params.SetCursor(domaintest.NewPlayerCursor(t, func(cfg *domaintest.PlayerCursorConfig) {
|
||||
cfg.ID = res.Players()[1].ID()
|
||||
})))
|
||||
cursor, err := res.Players()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -572,10 +572,9 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Players()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewPlayerCursor(t, func(cfg *domaintest.PlayerCursorConfig) {
|
||||
cfg.ID = res.Players()[1].ID()
|
||||
cfg.ServerKey = res.Players()[1].ServerKey()
|
||||
})))
|
||||
cursor, err := res.Players()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -614,10 +613,9 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Players()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewPlayerCursor(t, func(cfg *domaintest.PlayerCursorConfig) {
|
||||
cfg.ID = res.Players()[1].ID()
|
||||
cfg.ServerKey = res.Players()[1].ServerKey()
|
||||
})))
|
||||
cursor, err := res.Players()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
|
|
@ -369,9 +369,9 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Servers()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewServerCursor(t, func(cfg *domaintest.ServerCursorConfig) {
|
||||
cfg.Key = res.Servers()[1].Key()
|
||||
})))
|
||||
cursor, err := res.Servers()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -403,10 +403,9 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Servers()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewServerCursor(t, func(cfg *domaintest.ServerCursorConfig) {
|
||||
cfg.Key = res.Servers()[1].Key()
|
||||
cfg.Open = res.Servers()[1].Open()
|
||||
})))
|
||||
cursor, err := res.Servers()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -446,10 +445,9 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Servers()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewServerCursor(t, func(cfg *domaintest.ServerCursorConfig) {
|
||||
cfg.Key = res.Servers()[1].Key()
|
||||
cfg.Open = res.Servers()[1].Open()
|
||||
})))
|
||||
cursor, err := res.Servers()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
|
|
@ -56,7 +56,7 @@ type ennoblementRepository interface {
|
|||
|
||||
type tribeChangeRepository interface {
|
||||
Create(ctx context.Context, params ...domain.CreateTribeChangeParams) error
|
||||
List(ctx context.Context, params domain.ListTribeChangesParams) (domain.TribeChanges, error)
|
||||
List(ctx context.Context, params domain.ListTribeChangesParams) (domain.ListTribeChangesResult, error)
|
||||
}
|
||||
|
||||
type tribeSnapshotRepository interface {
|
||||
|
|
|
@ -32,8 +32,9 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
listParams := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, listParams.SetServerKeys([]string{params[0].ServerKey()}))
|
||||
|
||||
tribeChanges, err := repos.tribeChange.List(ctx, listParams)
|
||||
res, err := repos.tribeChange.List(ctx, listParams)
|
||||
require.NoError(t, err)
|
||||
tribeChanges := res.TribeChanges()
|
||||
for i, p := range params {
|
||||
idx := slices.IndexFunc(tribeChanges, func(tc domain.TribeChange) bool {
|
||||
return tc.ServerKey() == p.ServerKey() &&
|
||||
|
@ -60,8 +61,9 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
listParams := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, listParams.SetServerKeys([]string{params[0].ServerKey()}))
|
||||
|
||||
tribeChanges, err := repos.tribeChange.List(ctx, listParams)
|
||||
res, err := repos.tribeChange.List(ctx, listParams)
|
||||
require.NoError(t, err)
|
||||
tribeChanges := res.TribeChanges()
|
||||
|
||||
m := make(map[string][]int)
|
||||
|
||||
|
@ -139,17 +141,11 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
|
||||
repos := newRepos(t)
|
||||
|
||||
tribeChanges, listTribeChangesErr := repos.tribeChange.List(ctx, domain.NewListTribeChangesParams())
|
||||
require.NoError(t, listTribeChangesErr)
|
||||
require.NotEmpty(t, tribeChanges)
|
||||
randTribeChange := tribeChanges[0]
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
params func(t *testing.T) domain.ListTribeChangesParams
|
||||
assertTribeChanges func(t *testing.T, params domain.ListTribeChangesParams, tribeChanges domain.TribeChanges)
|
||||
assertResult func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult)
|
||||
assertError func(t *testing.T, err error)
|
||||
assertTotal func(t *testing.T, params domain.ListTribeChangesParams, total int)
|
||||
}{
|
||||
{
|
||||
name: "OK: default params",
|
||||
|
@ -157,8 +153,9 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
t.Helper()
|
||||
return domain.NewListTribeChangesParams()
|
||||
},
|
||||
assertTribeChanges: func(t *testing.T, _ domain.ListTribeChangesParams, tribeChanges domain.TribeChanges) {
|
||||
assertResult: func(t *testing.T, _ domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
tribeChanges := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tribeChanges))
|
||||
assert.True(t, slices.IsSortedFunc(tribeChanges, func(a, b domain.TribeChange) int {
|
||||
return cmp.Or(
|
||||
|
@ -167,15 +164,13 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
assert.False(t, res.Self().IsZero())
|
||||
assert.True(t, res.Next().IsZero())
|
||||
},
|
||||
assertError: func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertTotal: func(t *testing.T, _ domain.ListTribeChangesParams, total int) {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, total)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[serverKey DESC, createdAt DESC]",
|
||||
|
@ -188,8 +183,9 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
}))
|
||||
return params
|
||||
},
|
||||
assertTribeChanges: func(t *testing.T, _ domain.ListTribeChangesParams, tribeChanges domain.TribeChanges) {
|
||||
assertResult: func(t *testing.T, _ domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
tribeChanges := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tribeChanges))
|
||||
assert.True(t, slices.IsSortedFunc(tribeChanges, func(a, b domain.TribeChange) int {
|
||||
return cmp.Or(
|
||||
|
@ -202,10 +198,6 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertTotal: func(t *testing.T, _ domain.ListTribeChangesParams, total int) {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, total)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[id ASC]",
|
||||
|
@ -217,8 +209,9 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
}))
|
||||
return params
|
||||
},
|
||||
assertTribeChanges: func(t *testing.T, _ domain.ListTribeChangesParams, tribeChanges domain.TribeChanges) {
|
||||
assertResult: func(t *testing.T, _ domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
tribeChanges := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tribeChanges))
|
||||
assert.True(t, slices.IsSortedFunc(tribeChanges, func(a, b domain.TribeChange) int {
|
||||
return cmp.Compare(a.ID(), b.ID())
|
||||
|
@ -228,10 +221,6 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertTotal: func(t *testing.T, _ domain.ListTribeChangesParams, total int) {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, total)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[id DESC]",
|
||||
|
@ -243,8 +232,9 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
}))
|
||||
return params
|
||||
},
|
||||
assertTribeChanges: func(t *testing.T, _ domain.ListTribeChangesParams, tribeChanges domain.TribeChanges) {
|
||||
assertResult: func(t *testing.T, _ domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
tribeChanges := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tribeChanges))
|
||||
assert.True(t, slices.IsSortedFunc(tribeChanges, func(a, b domain.TribeChange) int {
|
||||
return cmp.Compare(a.ID(), b.ID()) * -1
|
||||
|
@ -254,25 +244,31 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertTotal: func(t *testing.T, _ domain.ListTribeChangesParams, total int) {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, total)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: fmt.Sprintf("OK: serverKeys=[%s]", randTribeChange.ServerKey()),
|
||||
name: "OK: serverKeys",
|
||||
params: func(t *testing.T) domain.ListTribeChangesParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, params.SetServerKeys([]string{randTribeChange.ServerKey()}))
|
||||
|
||||
res, err := repos.tribeChange.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, res.TribeChanges())
|
||||
randTC := res.TribeChanges()[0]
|
||||
|
||||
require.NoError(t, params.SetServerKeys([]string{randTC.ServerKey()}))
|
||||
|
||||
return params
|
||||
},
|
||||
assertTribeChanges: func(t *testing.T, params domain.ListTribeChangesParams, tribeChanges domain.TribeChanges) {
|
||||
assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
|
||||
serverKeys := params.ServerKeys()
|
||||
|
||||
for _, tc := range tribeChanges {
|
||||
tcs := res.TribeChanges()
|
||||
assert.NotZero(t, tcs)
|
||||
for _, tc := range tcs {
|
||||
assert.True(t, slices.Contains(serverKeys, tc.ServerKey()))
|
||||
}
|
||||
},
|
||||
|
@ -280,31 +276,145 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertTotal: func(t *testing.T, _ domain.ListTribeChangesParams, total int) {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, total)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: offset=1 limit=2",
|
||||
name: "OK: cursor serverKeys sort=[id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribeChangesParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, params.SetOffset(1))
|
||||
require.NoError(t, params.SetLimit(2))
|
||||
|
||||
res, err := repos.tribeChange.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.TribeChanges()), 2)
|
||||
|
||||
require.NoError(t, params.SetSort([]domain.TribeChangeSort{domain.TribeChangeSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.TribeChanges()[1].ServerKey()}))
|
||||
cursor, err := res.TribeChanges()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertTribeChanges: func(t *testing.T, params domain.ListTribeChangesParams, tribeChanges domain.TribeChanges) {
|
||||
assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
assert.Len(t, tribeChanges, params.Limit())
|
||||
|
||||
serverKeys := params.ServerKeys()
|
||||
|
||||
tcs := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tcs))
|
||||
for _, tc := range tcs {
|
||||
assert.GreaterOrEqual(t, tc.ID(), params.Cursor().ID())
|
||||
assert.True(t, slices.Contains(serverKeys, tc.ServerKey()))
|
||||
}
|
||||
assert.True(t, slices.IsSortedFunc(tcs, func(a, b domain.TribeChange) int {
|
||||
return cmp.Compare(a.ID(), b.ID())
|
||||
}))
|
||||
},
|
||||
assertError: func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
assertTotal: func(t *testing.T, _ domain.ListTribeChangesParams, total int) {
|
||||
},
|
||||
{
|
||||
name: "OK: cursor sort=[serverKey ASC, id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribeChangesParams {
|
||||
t.Helper()
|
||||
assert.NotEmpty(t, total)
|
||||
|
||||
params := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, params.SetSort([]domain.TribeChangeSort{
|
||||
domain.TribeChangeSortServerKeyASC,
|
||||
domain.TribeChangeSortIDASC,
|
||||
}))
|
||||
|
||||
res, err := repos.tribeChange.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.TribeChanges()), 2)
|
||||
|
||||
cursor, err := res.TribeChanges()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
tcs := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tcs))
|
||||
assert.True(t, slices.IsSortedFunc(tcs, func(a, b domain.TribeChange) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
assert.GreaterOrEqual(t, tcs[0].ID(), params.Cursor().ID())
|
||||
for _, tc := range tcs {
|
||||
assert.GreaterOrEqual(t, tc.ServerKey(), params.Cursor().ServerKey())
|
||||
}
|
||||
},
|
||||
assertError: func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: cursor sort=[serverKey DESC, id DESC]",
|
||||
params: func(t *testing.T) domain.ListTribeChangesParams {
|
||||
t.Helper()
|
||||
|
||||
params := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, params.SetSort([]domain.TribeChangeSort{
|
||||
domain.TribeChangeSortServerKeyDESC,
|
||||
domain.TribeChangeSortIDDESC,
|
||||
}))
|
||||
|
||||
res, err := repos.tribeChange.List(ctx, params)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.TribeChanges()), 2)
|
||||
|
||||
cursor, err := res.TribeChanges()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
tcs := res.TribeChanges()
|
||||
assert.NotEmpty(t, len(tcs))
|
||||
assert.True(t, slices.IsSortedFunc(tcs, func(a, b domain.TribeChange) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
) * -1
|
||||
}))
|
||||
assert.LessOrEqual(t, tcs[0].ID(), params.Cursor().ID())
|
||||
for _, tc := range tcs {
|
||||
assert.LessOrEqual(t, tc.ServerKey(), params.Cursor().ServerKey())
|
||||
}
|
||||
},
|
||||
assertError: func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: limit=2",
|
||||
params: func(t *testing.T) domain.ListTribeChangesParams {
|
||||
t.Helper()
|
||||
params := domain.NewListTribeChangesParams()
|
||||
require.NoError(t, params.SetLimit(2))
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) {
|
||||
t.Helper()
|
||||
assert.Len(t, res.TribeChanges(), params.Limit())
|
||||
assert.False(t, res.Self().IsZero())
|
||||
assert.False(t, res.Next().IsZero())
|
||||
},
|
||||
assertError: func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -317,7 +427,7 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
|||
|
||||
res, err := repos.tribeChange.List(ctx, params)
|
||||
tt.assertError(t, err)
|
||||
tt.assertTribeChanges(t, params, res)
|
||||
tt.assertResult(t, params, res)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
@ -556,9 +556,9 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
|
||||
require.NoError(t, params.SetSort([]domain.TribeSort{domain.TribeSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.Tribes()[1].ServerKey()}))
|
||||
require.NoError(t, params.SetCursor(domaintest.NewTribeCursor(t, func(cfg *domaintest.TribeCursorConfig) {
|
||||
cfg.ID = res.Tribes()[1].ID()
|
||||
})))
|
||||
cursor, err := res.Tribes()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -597,10 +597,9 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Tribes()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewTribeCursor(t, func(cfg *domaintest.TribeCursorConfig) {
|
||||
cfg.ID = res.Tribes()[1].ID()
|
||||
cfg.ServerKey = res.Tribes()[1].ServerKey()
|
||||
})))
|
||||
cursor, err := res.Tribes()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -639,10 +638,9 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Tribes()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewTribeCursor(t, func(cfg *domaintest.TribeCursorConfig) {
|
||||
cfg.ID = res.Tribes()[1].ID()
|
||||
cfg.ServerKey = res.Tribes()[1].ServerKey()
|
||||
})))
|
||||
cursor, err := res.Tribes()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -682,11 +680,9 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Tribes()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewTribeCursor(t, func(cfg *domaintest.TribeCursorConfig) {
|
||||
cfg.ID = res.Tribes()[1].ID()
|
||||
cfg.ServerKey = res.Tribes()[1].ServerKey()
|
||||
cfg.Points = res.Tribes()[1].Points()
|
||||
})))
|
||||
cursor, err := res.Tribes()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -728,11 +724,9 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Tribes()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewTribeCursor(t, func(cfg *domaintest.TribeCursorConfig) {
|
||||
cfg.ID = res.Tribes()[1].ID()
|
||||
cfg.ServerKey = res.Tribes()[1].ServerKey()
|
||||
cfg.DeletedAt = res.Tribes()[1].DeletedAt()
|
||||
})))
|
||||
cursor, err := res.Tribes()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain/domaintest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -80,9 +79,9 @@ func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Versions()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) {
|
||||
cfg.Code = res.Versions()[1].Code()
|
||||
})))
|
||||
cursor, err := res.Versions()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -113,9 +112,9 @@ func testVersionRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Versions()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewVersionCursor(t, func(cfg *domaintest.VersionCursorConfig) {
|
||||
cfg.Code = res.Versions()[1].Code()
|
||||
})))
|
||||
cursor, err := res.Versions()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
|
|
@ -331,9 +331,9 @@ func testVillageRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
|||
|
||||
require.NoError(t, params.SetSort([]domain.VillageSort{domain.VillageSortIDASC}))
|
||||
require.NoError(t, params.SetServerKeys([]string{res.Villages()[1].ServerKey()}))
|
||||
require.NoError(t, params.SetCursor(domaintest.NewVillageCursor(t, func(cfg *domaintest.VillageCursorConfig) {
|
||||
cfg.ID = res.Villages()[1].ID()
|
||||
})))
|
||||
cursor, err := res.Villages()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -372,10 +372,9 @@ func testVillageRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Villages()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewVillageCursor(t, func(cfg *domaintest.VillageCursorConfig) {
|
||||
cfg.ID = res.Villages()[1].ID()
|
||||
cfg.ServerKey = res.Villages()[1].ServerKey()
|
||||
})))
|
||||
cursor, err := res.Villages()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
@ -414,10 +413,9 @@ func testVillageRepository(t *testing.T, newRepos func(t *testing.T) repositorie
|
|||
require.NoError(t, err)
|
||||
require.Greater(t, len(res.Villages()), 2)
|
||||
|
||||
require.NoError(t, params.SetCursor(domaintest.NewVillageCursor(t, func(cfg *domaintest.VillageCursorConfig) {
|
||||
cfg.ID = res.Villages()[1].ID()
|
||||
cfg.ServerKey = res.Villages()[1].ServerKey()
|
||||
})))
|
||||
cursor, err := res.Villages()[1].ToCursor()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, params.SetCursor(cursor))
|
||||
|
||||
return params
|
||||
},
|
||||
|
|
|
@ -4,9 +4,39 @@ import (
|
|||
"time"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||
"github.com/brianvoe/gofakeit/v7"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type TribeChangeCursorConfig struct {
|
||||
ID int
|
||||
ServerKey string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func NewTribeChangeCursor(tb TestingTB, opts ...func(cfg *TribeChangeCursorConfig)) domain.TribeChangeCursor {
|
||||
tb.Helper()
|
||||
|
||||
cfg := &TribeChangeCursorConfig{
|
||||
ID: RandID(),
|
||||
ServerKey: RandServerKey(),
|
||||
CreatedAt: gofakeit.Date(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
|
||||
tcc, err := domain.NewTribeChangeCursor(
|
||||
cfg.ID,
|
||||
cfg.ServerKey,
|
||||
cfg.CreatedAt,
|
||||
)
|
||||
require.NoError(tb, err)
|
||||
|
||||
return tcc
|
||||
}
|
||||
|
||||
type TribeChangeConfig struct {
|
||||
ID int
|
||||
ServerKey string
|
||||
|
|
|
@ -81,6 +81,14 @@ func (tc TribeChange) CreatedAt() time.Time {
|
|||
return tc.createdAt
|
||||
}
|
||||
|
||||
func (tc TribeChange) ToCursor() (TribeChangeCursor, error) {
|
||||
return NewTribeChangeCursor(tc.id, tc.serverKey, tc.createdAt)
|
||||
}
|
||||
|
||||
func (tc TribeChange) IsZero() bool {
|
||||
return tc == TribeChange{}
|
||||
}
|
||||
|
||||
type TribeChanges []TribeChange
|
||||
|
||||
type CreateTribeChangeParams struct {
|
||||
|
@ -241,11 +249,105 @@ func (s TribeChangeSort) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
type TribeChangeCursor struct {
|
||||
id int
|
||||
serverKey string
|
||||
createdAt time.Time
|
||||
}
|
||||
|
||||
const tribeChangeCursorModelName = "TribeChangeCursor"
|
||||
|
||||
func NewTribeChangeCursor(id int, serverKey string, createdAt time.Time) (TribeChangeCursor, error) {
|
||||
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
|
||||
return TribeChangeCursor{}, ValidationError{
|
||||
Model: tribeChangeCursorModelName,
|
||||
Field: "id",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateServerKey(serverKey); err != nil {
|
||||
return TribeChangeCursor{}, ValidationError{
|
||||
Model: tribeChangeCursorModelName,
|
||||
Field: "serverKey",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return TribeChangeCursor{
|
||||
id: id,
|
||||
serverKey: serverKey,
|
||||
createdAt: createdAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func decodeTribeChangeCursor(encoded string) (TribeChangeCursor, error) {
|
||||
m, err := decodeCursor(encoded)
|
||||
if err != nil {
|
||||
return TribeChangeCursor{}, err
|
||||
}
|
||||
|
||||
id, err := m.int("id")
|
||||
if err != nil {
|
||||
return TribeChangeCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
serverKey, err := m.string("serverKey")
|
||||
if err != nil {
|
||||
return TribeChangeCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
createdAt, err := m.time("createdAt")
|
||||
if err != nil {
|
||||
return TribeChangeCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
ec, err := NewTribeChangeCursor(
|
||||
id,
|
||||
serverKey,
|
||||
createdAt,
|
||||
)
|
||||
if err != nil {
|
||||
return TribeChangeCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
return ec, nil
|
||||
}
|
||||
|
||||
func (tcc TribeChangeCursor) ID() int {
|
||||
return tcc.id
|
||||
}
|
||||
|
||||
func (tcc TribeChangeCursor) ServerKey() string {
|
||||
return tcc.serverKey
|
||||
}
|
||||
|
||||
func (tcc TribeChangeCursor) CreatedAt() time.Time {
|
||||
return tcc.createdAt
|
||||
}
|
||||
|
||||
func (tcc TribeChangeCursor) IsZero() bool {
|
||||
return tcc == TribeChangeCursor{}
|
||||
}
|
||||
|
||||
func (tcc TribeChangeCursor) Encode() string {
|
||||
if tcc.IsZero() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return encodeCursor([]keyValuePair{
|
||||
{"id", tcc.id},
|
||||
{"serverKey", tcc.serverKey},
|
||||
{"createdAt", tcc.createdAt},
|
||||
})
|
||||
}
|
||||
|
||||
type ListTribeChangesParams struct {
|
||||
serverKeys []string
|
||||
sort []TribeChangeSort
|
||||
cursor TribeChangeCursor
|
||||
limit int
|
||||
offset int
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -308,6 +410,30 @@ func (params *ListTribeChangesParams) SetSort(sort []TribeChangeSort) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeChangesParams) Cursor() TribeChangeCursor {
|
||||
return params.cursor
|
||||
}
|
||||
|
||||
func (params *ListTribeChangesParams) SetCursor(cursor TribeChangeCursor) error {
|
||||
params.cursor = cursor
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeChangesParams) SetEncodedCursor(encoded string) error {
|
||||
decoded, err := decodeTribeChangeCursor(encoded)
|
||||
if err != nil {
|
||||
return ValidationError{
|
||||
Model: listTribeChangesParamsModelName,
|
||||
Field: "cursor",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
params.cursor = decoded
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeChangesParams) Limit() int {
|
||||
return params.limit
|
||||
}
|
||||
|
@ -326,20 +452,53 @@ func (params *ListTribeChangesParams) SetLimit(limit int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *ListTribeChangesParams) Offset() int {
|
||||
return params.offset
|
||||
type ListTribeChangesResult struct {
|
||||
tribeChanges TribeChanges
|
||||
self TribeChangeCursor
|
||||
next TribeChangeCursor
|
||||
}
|
||||
|
||||
func (params *ListTribeChangesParams) SetOffset(offset int) error {
|
||||
if err := validateIntInRange(offset, 0, math.MaxInt); err != nil {
|
||||
return ValidationError{
|
||||
Model: listTribeChangesParamsModelName,
|
||||
Field: "offset",
|
||||
const listTribeChangesResultModelName = "ListTribeChangesResult"
|
||||
|
||||
func NewListTribeChangesResult(ennoblements TribeChanges, next TribeChange) (ListTribeChangesResult, error) {
|
||||
var err error
|
||||
res := ListTribeChangesResult{
|
||||
tribeChanges: ennoblements,
|
||||
}
|
||||
|
||||
if len(ennoblements) > 0 {
|
||||
res.self, err = ennoblements[0].ToCursor()
|
||||
if err != nil {
|
||||
return ListTribeChangesResult{}, ValidationError{
|
||||
Model: listTribeChangesResultModelName,
|
||||
Field: "self",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
params.offset = offset
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if !next.IsZero() {
|
||||
res.next, err = next.ToCursor()
|
||||
if err != nil {
|
||||
return ListTribeChangesResult{}, ValidationError{
|
||||
Model: listTribeChangesResultModelName,
|
||||
Field: "next",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (res ListTribeChangesResult) TribeChanges() TribeChanges {
|
||||
return res.tribeChanges
|
||||
}
|
||||
|
||||
func (res ListTribeChangesResult) Self() TribeChangeCursor {
|
||||
return res.self
|
||||
}
|
||||
|
||||
func (res ListTribeChangesResult) Next() TribeChangeCursor {
|
||||
return res.next
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@ import (
|
|||
"fmt"
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
@ -279,6 +281,87 @@ func TestTribeChangeSort_IsInConflict(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewTribeChangeCursor(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validTribeChangeCursor := domaintest.NewTribeChangeCursor(t)
|
||||
|
||||
type args struct {
|
||||
id int
|
||||
serverKey string
|
||||
createdAt time.Time
|
||||
}
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
id: validTribeChangeCursor.ID(),
|
||||
serverKey: validTribeChangeCursor.ServerKey(),
|
||||
createdAt: validTribeChangeCursor.CreatedAt(),
|
||||
},
|
||||
expectedErr: nil,
|
||||
},
|
||||
{
|
||||
name: "ERR: id < 1",
|
||||
args: args{
|
||||
id: 0,
|
||||
serverKey: validTribeChangeCursor.ServerKey(),
|
||||
createdAt: validTribeChangeCursor.CreatedAt(),
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "TribeChangeCursor",
|
||||
Field: "id",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 1,
|
||||
Current: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, serverKeyTest := range newServerKeyValidationTests() {
|
||||
tests = append(tests, test{
|
||||
name: serverKeyTest.name,
|
||||
args: args{
|
||||
id: validTribeChangeCursor.ID(),
|
||||
serverKey: serverKeyTest.key,
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "TribeChangeCursor",
|
||||
Field: "serverKey",
|
||||
Err: serverKeyTest.expectedErr,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tcc, err := domain.NewTribeChangeCursor(
|
||||
tt.args.id,
|
||||
tt.args.serverKey,
|
||||
tt.args.createdAt,
|
||||
)
|
||||
require.ErrorIs(t, err, tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.id, tcc.ID())
|
||||
assert.Equal(t, tt.args.serverKey, tcc.ServerKey())
|
||||
assert.Equal(t, tt.args.createdAt, tcc.CreatedAt())
|
||||
assert.NotEmpty(t, tcc.Encode())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListTribeChangesParams_SetServerKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -422,6 +505,86 @@ func TestListTribeChangesParams_SetSort(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListTribeChangesParams_SetEncodedCursor(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
validCursor := domaintest.NewTribeChangeCursor(t)
|
||||
|
||||
type args struct {
|
||||
cursor string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedCursor domain.TribeChangeCursor
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
cursor: validCursor.Encode(),
|
||||
},
|
||||
expectedCursor: validCursor,
|
||||
},
|
||||
{
|
||||
name: "ERR: len(cursor) < 1",
|
||||
args: args{
|
||||
cursor: "",
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "ListTribeChangesParams",
|
||||
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: "ListTribeChangesParams",
|
||||
Field: "cursor",
|
||||
Err: domain.LenOutOfRangeError{
|
||||
Min: 1,
|
||||
Max: 1000,
|
||||
Current: 1001,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: malformed base64",
|
||||
args: args{
|
||||
cursor: "112345",
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "ListTribeChangesParams",
|
||||
Field: "cursor",
|
||||
Err: domain.ErrInvalidCursor,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewListTribeChangesParams()
|
||||
|
||||
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 TestListTribeChangesParams_SetLimit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -485,51 +648,49 @@ func TestListTribeChangesParams_SetLimit(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestListTribeChangesParams_SetOffset(t *testing.T) {
|
||||
func TestNewListTribeChangesResult(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
offset int
|
||||
tcs := domain.TribeChanges{
|
||||
domaintest.NewTribeChange(t),
|
||||
domaintest.NewTribeChange(t),
|
||||
domaintest.NewTribeChange(t),
|
||||
}
|
||||
next := domaintest.NewTribeChange(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: "ListTribeChangesParams",
|
||||
Field: "offset",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run("OK: with next", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewListTribeChangesParams()
|
||||
res, err := domain.NewListTribeChangesResult(tcs, next)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tcs, res.TribeChanges())
|
||||
assert.Equal(t, tcs[0].ID(), res.Self().ID())
|
||||
assert.Equal(t, tcs[0].ServerKey(), res.Self().ServerKey())
|
||||
assert.Equal(t, tcs[0].CreatedAt(), res.Self().CreatedAt())
|
||||
assert.Equal(t, next.ID(), res.Next().ID())
|
||||
assert.Equal(t, next.ServerKey(), res.Next().ServerKey())
|
||||
assert.Equal(t, next.CreatedAt(), res.Next().CreatedAt())
|
||||
})
|
||||
|
||||
require.ErrorIs(t, params.SetOffset(tt.args.offset), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.offset, params.Offset())
|
||||
t.Run("OK: without next", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
res, err := domain.NewListTribeChangesResult(tcs, domain.TribeChange{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tcs, res.TribeChanges())
|
||||
assert.Equal(t, tcs[0].ID(), res.Self().ID())
|
||||
assert.Equal(t, tcs[0].ServerKey(), res.Self().ServerKey())
|
||||
assert.Equal(t, tcs[0].CreatedAt(), res.Self().CreatedAt())
|
||||
assert.True(t, res.Next().IsZero())
|
||||
})
|
||||
|
||||
t.Run("OK: 0 tribe changes", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
res, err := domain.NewListTribeChangesResult(nil, domain.TribeChange{})
|
||||
require.NoError(t, err)
|
||||
assert.Zero(t, res.TribeChanges())
|
||||
assert.True(t, res.Self().IsZero())
|
||||
assert.True(t, res.Next().IsZero())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -467,16 +467,16 @@ func TestDataSync(t *testing.T) {
|
|||
allTribeChanges := make(domain.TribeChanges, 0, len(expectedTribeChanges))
|
||||
|
||||
for {
|
||||
tcs, err := tribeChangeRepo.List(ctx, listParams)
|
||||
res, err := tribeChangeRepo.List(ctx, listParams)
|
||||
require.NoError(collect, err)
|
||||
|
||||
if len(tcs) == 0 {
|
||||
allTribeChanges = append(allTribeChanges, res.TribeChanges()...)
|
||||
|
||||
if res.Next().IsZero() {
|
||||
break
|
||||
}
|
||||
|
||||
allTribeChanges = append(allTribeChanges, tcs...)
|
||||
|
||||
require.NoError(collect, listParams.SetOffset(listParams.Offset()+domain.TribeChangeListMaxLimit))
|
||||
require.NoError(collect, listParams.SetCursor(res.Next()))
|
||||
}
|
||||
|
||||
if !assert.Len(collect, allTribeChanges, len(expectedTribeChanges)) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user