refactor: ennoblement - cursor pagination
This commit is contained in:
parent
eb1890d90b
commit
b0f7be66ac
|
@ -54,17 +54,22 @@ func (repo *EnnoblementBunRepository) Create(ctx context.Context, params ...doma
|
||||||
func (repo *EnnoblementBunRepository) List(
|
func (repo *EnnoblementBunRepository) List(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
params domain.ListEnnoblementsParams,
|
params domain.ListEnnoblementsParams,
|
||||||
) (domain.Ennoblements, error) {
|
) (domain.ListEnnoblementsResult, error) {
|
||||||
var ennoblements bunmodel.Ennoblements
|
var ennoblements bunmodel.Ennoblements
|
||||||
|
|
||||||
if err := repo.db.NewSelect().
|
if err := repo.db.NewSelect().
|
||||||
Model(&ennoblements).
|
Model(&ennoblements).
|
||||||
Apply(listEnnoblementsParamsApplier{params: params}.apply).
|
Apply(listEnnoblementsParamsApplier{params: params}.apply).
|
||||||
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||||
return nil, fmt.Errorf("couldn't select ennoblements from the db: %w", err)
|
return domain.ListEnnoblementsResult{}, fmt.Errorf("couldn't select ennoblements from the db: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ennoblements.ToDomain()
|
converted, err := ennoblements.ToDomain()
|
||||||
|
if err != nil {
|
||||||
|
return domain.ListEnnoblementsResult{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain.NewListEnnoblementsResult(separateListResultAndNext(converted, params.Limit()))
|
||||||
}
|
}
|
||||||
|
|
||||||
type listEnnoblementsParamsApplier struct {
|
type listEnnoblementsParamsApplier struct {
|
||||||
|
@ -96,5 +101,57 @@ func (a listEnnoblementsParamsApplier) 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 listEnnoblementsParamsApplier) 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.EnnoblementSortIDASC:
|
||||||
|
el.value = cursor.ID()
|
||||||
|
el.unique = true
|
||||||
|
el.column = "ennoblement.id"
|
||||||
|
el.direction = sortDirectionASC
|
||||||
|
case domain.EnnoblementSortIDDESC:
|
||||||
|
el.value = cursor.ID()
|
||||||
|
el.unique = true
|
||||||
|
el.column = "ennoblement.id"
|
||||||
|
el.direction = sortDirectionDESC
|
||||||
|
case domain.EnnoblementSortServerKeyASC:
|
||||||
|
el.value = cursor.ServerKey()
|
||||||
|
el.column = "ennoblement.server_key"
|
||||||
|
el.direction = sortDirectionASC
|
||||||
|
case domain.EnnoblementSortServerKeyDESC:
|
||||||
|
el.value = cursor.ServerKey()
|
||||||
|
el.column = "ennoblement.server_key"
|
||||||
|
el.direction = sortDirectionDESC
|
||||||
|
case domain.EnnoblementSortCreatedAtASC:
|
||||||
|
el.value = cursor.CreatedAt()
|
||||||
|
el.column = "ennoblement.created_at"
|
||||||
|
el.direction = sortDirectionASC
|
||||||
|
case domain.EnnoblementSortCreatedAtDESC:
|
||||||
|
el.value = cursor.CreatedAt()
|
||||||
|
el.column = "ennoblement.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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,8 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
listParams := domain.NewListEnnoblementsParams()
|
listParams := domain.NewListEnnoblementsParams()
|
||||||
require.NoError(t, listParams.SetServerKeys([]string{params[0].ServerKey()}))
|
require.NoError(t, listParams.SetServerKeys([]string{params[0].ServerKey()}))
|
||||||
|
|
||||||
ennoblements, err := repos.ennoblement.List(ctx, listParams)
|
res, err := repos.ennoblement.List(ctx, listParams)
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
for i, p := range params {
|
for i, p := range params {
|
||||||
idx := slices.IndexFunc(ennoblements, func(ennoblement domain.Ennoblement) bool {
|
idx := slices.IndexFunc(ennoblements, func(ennoblement domain.Ennoblement) bool {
|
||||||
|
@ -61,8 +62,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
listParams := domain.NewListEnnoblementsParams()
|
listParams := domain.NewListEnnoblementsParams()
|
||||||
require.NoError(t, listParams.SetServerKeys([]string{params[0].ServerKey()}))
|
require.NoError(t, listParams.SetServerKeys([]string{params[0].ServerKey()}))
|
||||||
|
|
||||||
ennoblements, err := repos.ennoblement.List(ctx, listParams)
|
res, err := repos.ennoblement.List(ctx, listParams)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
|
|
||||||
m := make(map[string][]int)
|
m := make(map[string][]int)
|
||||||
|
|
||||||
|
@ -121,15 +123,10 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
|
|
||||||
repos := newRepos(t)
|
repos := newRepos(t)
|
||||||
|
|
||||||
ennoblements, listEnnoblementsErr := repos.ennoblement.List(ctx, domain.NewListEnnoblementsParams())
|
|
||||||
require.NoError(t, listEnnoblementsErr)
|
|
||||||
require.NotEmpty(t, ennoblements)
|
|
||||||
randEnnoblement := ennoblements[0]
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
params func(t *testing.T) domain.ListEnnoblementsParams
|
params func(t *testing.T) domain.ListEnnoblementsParams
|
||||||
assertEnnoblements func(t *testing.T, params domain.ListEnnoblementsParams, ennoblements domain.Ennoblements)
|
assertResult func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult)
|
||||||
assertError func(t *testing.T, err error)
|
assertError func(t *testing.T, err error)
|
||||||
assertTotal func(t *testing.T, params domain.ListEnnoblementsParams, total int)
|
assertTotal func(t *testing.T, params domain.ListEnnoblementsParams, total int)
|
||||||
}{
|
}{
|
||||||
|
@ -139,8 +136,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
t.Helper()
|
t.Helper()
|
||||||
return domain.NewListEnnoblementsParams()
|
return domain.NewListEnnoblementsParams()
|
||||||
},
|
},
|
||||||
assertEnnoblements: func(t *testing.T, _ domain.ListEnnoblementsParams, ennoblements domain.Ennoblements) {
|
assertResult: func(t *testing.T, _ domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
assert.NotEmpty(t, len(ennoblements))
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
return cmp.Or(
|
return cmp.Or(
|
||||||
|
@ -149,6 +147,8 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
cmp.Compare(a.ID(), b.ID()),
|
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) {
|
assertError: func(t *testing.T, err error) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
@ -160,24 +160,27 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OK: sort=[serverKey DESC, createdAt DESC]",
|
name: "OK: sort=[serverKey DESC, createdAt DESC, id ASC]",
|
||||||
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
params := domain.NewListEnnoblementsParams()
|
params := domain.NewListEnnoblementsParams()
|
||||||
require.NoError(t, params.SetSort([]domain.EnnoblementSort{
|
require.NoError(t, params.SetSort([]domain.EnnoblementSort{
|
||||||
domain.EnnoblementSortServerKeyDESC,
|
domain.EnnoblementSortServerKeyDESC,
|
||||||
domain.EnnoblementSortCreatedAtDESC,
|
domain.EnnoblementSortCreatedAtDESC,
|
||||||
|
domain.EnnoblementSortIDASC,
|
||||||
}))
|
}))
|
||||||
return params
|
return params
|
||||||
},
|
},
|
||||||
assertEnnoblements: func(t *testing.T, _ domain.ListEnnoblementsParams, ennoblements domain.Ennoblements) {
|
assertResult: func(t *testing.T, _ domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
assert.NotEmpty(t, len(ennoblements))
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
return cmp.Or(
|
return cmp.Or(
|
||||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
cmp.Compare(a.ServerKey(), b.ServerKey())*-1,
|
||||||
a.CreatedAt().Compare(b.CreatedAt()),
|
a.CreatedAt().Compare(b.CreatedAt())*-1,
|
||||||
) * -1
|
cmp.Compare(a.ID(), b.ID()),
|
||||||
|
)
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
assertError: func(t *testing.T, err error) {
|
assertError: func(t *testing.T, err error) {
|
||||||
|
@ -199,8 +202,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
}))
|
}))
|
||||||
return params
|
return params
|
||||||
},
|
},
|
||||||
assertEnnoblements: func(t *testing.T, _ domain.ListEnnoblementsParams, ennoblements domain.Ennoblements) {
|
assertResult: func(t *testing.T, _ domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
assert.NotEmpty(t, len(ennoblements))
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
return cmp.Compare(a.ID(), b.ID())
|
return cmp.Compare(a.ID(), b.ID())
|
||||||
|
@ -225,8 +229,9 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
}))
|
}))
|
||||||
return params
|
return params
|
||||||
},
|
},
|
||||||
assertEnnoblements: func(t *testing.T, _ domain.ListEnnoblementsParams, ennoblements domain.Ennoblements) {
|
assertResult: func(t *testing.T, _ domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
assert.NotEmpty(t, len(ennoblements))
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
return cmp.Compare(a.ID(), b.ID()) * -1
|
return cmp.Compare(a.ID(), b.ID()) * -1
|
||||||
|
@ -242,18 +247,28 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: fmt.Sprintf("OK: serverKeys=[%s]", randEnnoblement.ServerKey()),
|
name: "OK: serverKeys",
|
||||||
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
params := domain.NewListEnnoblementsParams()
|
params := domain.NewListEnnoblementsParams()
|
||||||
|
|
||||||
|
res, err := repos.ennoblement.List(ctx, params)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, res.Ennoblements())
|
||||||
|
randEnnoblement := res.Ennoblements()[0]
|
||||||
|
|
||||||
require.NoError(t, params.SetServerKeys([]string{randEnnoblement.ServerKey()}))
|
require.NoError(t, params.SetServerKeys([]string{randEnnoblement.ServerKey()}))
|
||||||
|
|
||||||
return params
|
return params
|
||||||
},
|
},
|
||||||
assertEnnoblements: func(t *testing.T, params domain.ListEnnoblementsParams, ennoblements domain.Ennoblements) {
|
assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
serverKeys := params.ServerKeys()
|
serverKeys := params.ServerKeys()
|
||||||
|
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
|
assert.NotZero(t, ennoblements)
|
||||||
for _, e := range ennoblements {
|
for _, e := range ennoblements {
|
||||||
assert.True(t, slices.Contains(serverKeys, e.ServerKey()))
|
assert.True(t, slices.Contains(serverKeys, e.ServerKey()))
|
||||||
}
|
}
|
||||||
|
@ -268,17 +283,150 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OK: offset=1 limit=2",
|
name: "OK: cursor serverKeys sort=[id ASC]",
|
||||||
|
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
params := domain.NewListEnnoblementsParams()
|
||||||
|
|
||||||
|
res, err := repos.ennoblement.List(ctx, params)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Greater(t, len(res.Ennoblements()), 2)
|
||||||
|
|
||||||
|
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()
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
serverKeys := params.ServerKeys()
|
||||||
|
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
|
for _, e := range ennoblements {
|
||||||
|
assert.GreaterOrEqual(t, e.ID(), params.Cursor().ID())
|
||||||
|
assert.True(t, slices.Contains(serverKeys, e.ServerKey()))
|
||||||
|
}
|
||||||
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
|
return cmp.Compare(a.ID(), b.ID())
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
assertError: func(t *testing.T, err error) {
|
||||||
|
t.Helper()
|
||||||
|
require.NoError(t, err)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OK: cursor sort=[serverKey ASC, id ASC]",
|
||||||
|
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
params := domain.NewListEnnoblementsParams()
|
||||||
|
require.NoError(t, params.SetSort([]domain.EnnoblementSort{
|
||||||
|
domain.EnnoblementSortServerKeyASC,
|
||||||
|
domain.EnnoblementSortIDASC,
|
||||||
|
}))
|
||||||
|
|
||||||
|
res, err := repos.ennoblement.List(ctx, params)
|
||||||
|
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()
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
|
t.Helper()
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
|
return cmp.Or(
|
||||||
|
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||||
|
cmp.Compare(a.ID(), b.ID()),
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
assert.GreaterOrEqual(t, ennoblements[0].ID(), params.Cursor().ID())
|
||||||
|
for _, e := range ennoblements {
|
||||||
|
assert.GreaterOrEqual(t, e.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.ListEnnoblementsParams {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
params := domain.NewListEnnoblementsParams()
|
||||||
|
require.NoError(t, params.SetSort([]domain.EnnoblementSort{
|
||||||
|
domain.EnnoblementSortServerKeyDESC,
|
||||||
|
domain.EnnoblementSortIDDESC,
|
||||||
|
}))
|
||||||
|
|
||||||
|
res, err := repos.ennoblement.List(ctx, params)
|
||||||
|
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()
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
|
t.Helper()
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
|
assert.NotEmpty(t, len(ennoblements))
|
||||||
|
assert.True(t, slices.IsSortedFunc(ennoblements, func(a, b domain.Ennoblement) int {
|
||||||
|
return cmp.Or(
|
||||||
|
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||||
|
cmp.Compare(a.ID(), b.ID()),
|
||||||
|
) * -1
|
||||||
|
}))
|
||||||
|
assert.LessOrEqual(t, ennoblements[0].ID(), params.Cursor().ID())
|
||||||
|
for _, e := range ennoblements {
|
||||||
|
assert.LessOrEqual(t, e.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.ListEnnoblementsParams {
|
params: func(t *testing.T) domain.ListEnnoblementsParams {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
params := domain.NewListEnnoblementsParams()
|
params := domain.NewListEnnoblementsParams()
|
||||||
require.NoError(t, params.SetOffset(1))
|
|
||||||
require.NoError(t, params.SetLimit(2))
|
require.NoError(t, params.SetLimit(2))
|
||||||
return params
|
return params
|
||||||
},
|
},
|
||||||
assertEnnoblements: func(t *testing.T, params domain.ListEnnoblementsParams, ennoblements domain.Ennoblements) {
|
assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
assert.Len(t, ennoblements, params.Limit())
|
assert.Len(t, res.Ennoblements(), params.Limit())
|
||||||
|
assert.False(t, res.Self().IsZero())
|
||||||
|
assert.False(t, res.Next().IsZero())
|
||||||
},
|
},
|
||||||
assertError: func(t *testing.T, err error) {
|
assertError: func(t *testing.T, err error) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
@ -299,7 +447,7 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit
|
||||||
|
|
||||||
res, err := repos.ennoblement.List(ctx, params)
|
res, err := repos.ennoblement.List(ctx, params)
|
||||||
tt.assertError(t, err)
|
tt.assertError(t, err)
|
||||||
tt.assertEnnoblements(t, params, res)
|
tt.assertResult(t, params, res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -47,7 +47,7 @@ type villageRepository interface {
|
||||||
|
|
||||||
type ennoblementRepository interface {
|
type ennoblementRepository interface {
|
||||||
Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
|
Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
|
||||||
List(ctx context.Context, params domain.ListEnnoblementsParams) (domain.Ennoblements, error)
|
List(ctx context.Context, params domain.ListEnnoblementsParams) (domain.ListEnnoblementsResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type tribeChangeRepository interface {
|
type tribeChangeRepository interface {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
type EnnoblementRepository interface {
|
type EnnoblementRepository interface {
|
||||||
Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
|
Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
|
||||||
List(ctx context.Context, params domain.ListEnnoblementsParams) (domain.Ennoblements, error)
|
List(ctx context.Context, params domain.ListEnnoblementsParams) (domain.ListEnnoblementsResult, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type EnnoblementService struct {
|
type EnnoblementService struct {
|
||||||
|
@ -80,10 +80,12 @@ func (svc *EnnoblementService) getLatest(ctx context.Context, serverKey string)
|
||||||
return domain.Ennoblement{}, err
|
return domain.Ennoblement{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ennoblements, err := svc.repo.List(ctx, params)
|
res, err := svc.repo.List(ctx, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Ennoblement{}, err
|
return domain.Ennoblement{}, err
|
||||||
}
|
}
|
||||||
|
ennoblements := res.Ennoblements()
|
||||||
|
|
||||||
if len(ennoblements) == 0 {
|
if len(ennoblements) == 0 {
|
||||||
return domain.Ennoblement{}, errEnnoblementNotFound
|
return domain.Ennoblement{}, errEnnoblementNotFound
|
||||||
}
|
}
|
||||||
|
@ -116,3 +118,10 @@ func (svc *EnnoblementService) create(
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *EnnoblementService) List(
|
||||||
|
ctx context.Context,
|
||||||
|
params domain.ListEnnoblementsParams,
|
||||||
|
) (domain.ListEnnoblementsResult, error) {
|
||||||
|
return svc.repo.List(ctx, params)
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,35 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type EnnoblementCursorConfig struct {
|
||||||
|
ID int
|
||||||
|
ServerKey string
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEnnoblementCursor(tb TestingTB, opts ...func(cfg *EnnoblementCursorConfig)) domain.EnnoblementCursor {
|
||||||
|
tb.Helper()
|
||||||
|
|
||||||
|
cfg := &EnnoblementCursorConfig{
|
||||||
|
ID: RandID(),
|
||||||
|
ServerKey: RandServerKey(),
|
||||||
|
CreatedAt: gofakeit.Date(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
ec, err := domain.NewEnnoblementCursor(
|
||||||
|
cfg.ID,
|
||||||
|
cfg.ServerKey,
|
||||||
|
cfg.CreatedAt,
|
||||||
|
)
|
||||||
|
require.NoError(tb, err)
|
||||||
|
|
||||||
|
return ec
|
||||||
|
}
|
||||||
|
|
||||||
type EnnoblementConfig struct {
|
type EnnoblementConfig struct {
|
||||||
ID int
|
ID int
|
||||||
ServerKey string
|
ServerKey string
|
||||||
|
|
|
@ -25,13 +25,13 @@ func NewVillageCursor(tb TestingTB, opts ...func(cfg *VillageCursorConfig)) doma
|
||||||
opt(cfg)
|
opt(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
pc, err := domain.NewVillageCursor(
|
vc, err := domain.NewVillageCursor(
|
||||||
cfg.ID,
|
cfg.ID,
|
||||||
cfg.ServerKey,
|
cfg.ServerKey,
|
||||||
)
|
)
|
||||||
require.NoError(tb, err)
|
require.NoError(tb, err)
|
||||||
|
|
||||||
return pc
|
return vc
|
||||||
}
|
}
|
||||||
|
|
||||||
type VillageConfig struct {
|
type VillageConfig struct {
|
||||||
|
|
|
@ -101,6 +101,10 @@ func (e Ennoblement) CreatedAt() time.Time {
|
||||||
return e.createdAt
|
return e.createdAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e Ennoblement) ToCursor() (EnnoblementCursor, error) {
|
||||||
|
return NewEnnoblementCursor(e.id, e.serverKey, e.createdAt)
|
||||||
|
}
|
||||||
|
|
||||||
func (e Ennoblement) Base() BaseEnnoblement {
|
func (e Ennoblement) Base() BaseEnnoblement {
|
||||||
return BaseEnnoblement{
|
return BaseEnnoblement{
|
||||||
villageID: e.villageID,
|
villageID: e.villageID,
|
||||||
|
@ -113,6 +117,10 @@ func (e Ennoblement) Base() BaseEnnoblement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e Ennoblement) IsZero() bool {
|
||||||
|
return e == Ennoblement{}
|
||||||
|
}
|
||||||
|
|
||||||
type Ennoblements []Ennoblement
|
type Ennoblements []Ennoblement
|
||||||
|
|
||||||
type CreateEnnoblementParams struct {
|
type CreateEnnoblementParams struct {
|
||||||
|
@ -194,11 +202,105 @@ func (s EnnoblementSort) String() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EnnoblementCursor struct {
|
||||||
|
id int
|
||||||
|
serverKey string
|
||||||
|
createdAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
const ennoblementCursorModelName = "EnnoblementCursor"
|
||||||
|
|
||||||
|
func NewEnnoblementCursor(id int, serverKey string, createdAt time.Time) (EnnoblementCursor, error) {
|
||||||
|
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
|
||||||
|
return EnnoblementCursor{}, ValidationError{
|
||||||
|
Model: ennoblementCursorModelName,
|
||||||
|
Field: "id",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateServerKey(serverKey); err != nil {
|
||||||
|
return EnnoblementCursor{}, ValidationError{
|
||||||
|
Model: ennoblementCursorModelName,
|
||||||
|
Field: "serverKey",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EnnoblementCursor{
|
||||||
|
id: id,
|
||||||
|
serverKey: serverKey,
|
||||||
|
createdAt: createdAt,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:gocyclo
|
||||||
|
func decodeEnnoblementCursor(encoded string) (EnnoblementCursor, error) {
|
||||||
|
m, err := decodeCursor(encoded)
|
||||||
|
if err != nil {
|
||||||
|
return EnnoblementCursor{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := m.int("id")
|
||||||
|
if err != nil {
|
||||||
|
return EnnoblementCursor{}, ErrInvalidCursor
|
||||||
|
}
|
||||||
|
|
||||||
|
serverKey, err := m.string("serverKey")
|
||||||
|
if err != nil {
|
||||||
|
return EnnoblementCursor{}, ErrInvalidCursor
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt, err := m.time("createdAt")
|
||||||
|
if err != nil {
|
||||||
|
return EnnoblementCursor{}, ErrInvalidCursor
|
||||||
|
}
|
||||||
|
|
||||||
|
ec, err := NewEnnoblementCursor(
|
||||||
|
id,
|
||||||
|
serverKey,
|
||||||
|
createdAt,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return EnnoblementCursor{}, ErrInvalidCursor
|
||||||
|
}
|
||||||
|
|
||||||
|
return ec, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec EnnoblementCursor) ID() int {
|
||||||
|
return ec.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec EnnoblementCursor) ServerKey() string {
|
||||||
|
return ec.serverKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec EnnoblementCursor) CreatedAt() time.Time {
|
||||||
|
return ec.createdAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec EnnoblementCursor) IsZero() bool {
|
||||||
|
return ec == EnnoblementCursor{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec EnnoblementCursor) Encode() string {
|
||||||
|
if ec.IsZero() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return encodeCursor([]keyValuePair{
|
||||||
|
{"id", ec.id},
|
||||||
|
{"serverKey", ec.serverKey},
|
||||||
|
{"createdAt", ec.createdAt},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type ListEnnoblementsParams struct {
|
type ListEnnoblementsParams struct {
|
||||||
serverKeys []string
|
serverKeys []string
|
||||||
sort []EnnoblementSort
|
sort []EnnoblementSort
|
||||||
|
cursor EnnoblementCursor
|
||||||
limit int
|
limit int
|
||||||
offset int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -261,6 +363,30 @@ func (params *ListEnnoblementsParams) SetSort(sort []EnnoblementSort) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (params *ListEnnoblementsParams) Cursor() EnnoblementCursor {
|
||||||
|
return params.cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (params *ListEnnoblementsParams) SetCursor(cursor EnnoblementCursor) error {
|
||||||
|
params.cursor = cursor
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (params *ListEnnoblementsParams) SetEncodedCursor(encoded string) error {
|
||||||
|
decoded, err := decodeEnnoblementCursor(encoded)
|
||||||
|
if err != nil {
|
||||||
|
return ValidationError{
|
||||||
|
Model: listEnnoblementsParamsModelName,
|
||||||
|
Field: "cursor",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params.cursor = decoded
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (params *ListEnnoblementsParams) Limit() int {
|
func (params *ListEnnoblementsParams) Limit() int {
|
||||||
return params.limit
|
return params.limit
|
||||||
}
|
}
|
||||||
|
@ -279,20 +405,53 @@ func (params *ListEnnoblementsParams) SetLimit(limit int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (params *ListEnnoblementsParams) Offset() int {
|
type ListEnnoblementsResult struct {
|
||||||
return params.offset
|
ennoblements Ennoblements
|
||||||
|
self EnnoblementCursor
|
||||||
|
next EnnoblementCursor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (params *ListEnnoblementsParams) SetOffset(offset int) error {
|
const listEnnoblementsResultModelName = "ListEnnoblementsResult"
|
||||||
if err := validateIntInRange(offset, 0, math.MaxInt); err != nil {
|
|
||||||
return ValidationError{
|
func NewListEnnoblementsResult(ennoblements Ennoblements, next Ennoblement) (ListEnnoblementsResult, error) {
|
||||||
Model: listEnnoblementsParamsModelName,
|
var err error
|
||||||
Field: "offset",
|
res := ListEnnoblementsResult{
|
||||||
|
ennoblements: ennoblements,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ennoblements) > 0 {
|
||||||
|
res.self, err = ennoblements[0].ToCursor()
|
||||||
|
if err != nil {
|
||||||
|
return ListEnnoblementsResult{}, ValidationError{
|
||||||
|
Model: listEnnoblementsResultModelName,
|
||||||
|
Field: "self",
|
||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
params.offset = offset
|
if !next.IsZero() {
|
||||||
|
res.next, err = next.ToCursor()
|
||||||
|
if err != nil {
|
||||||
|
return ListEnnoblementsResult{}, ValidationError{
|
||||||
|
Model: listEnnoblementsResultModelName,
|
||||||
|
Field: "next",
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (res ListEnnoblementsResult) Ennoblements() Ennoblements {
|
||||||
|
return res.ennoblements
|
||||||
|
}
|
||||||
|
|
||||||
|
func (res ListEnnoblementsResult) Self() EnnoblementCursor {
|
||||||
|
return res.self
|
||||||
|
}
|
||||||
|
|
||||||
|
func (res ListEnnoblementsResult) Next() EnnoblementCursor {
|
||||||
|
return res.next
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
||||||
"gitea.dwysokinski.me/twhelp/corev3/internal/domain/domaintest"
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain/domaintest"
|
||||||
|
"github.com/brianvoe/gofakeit/v7"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -102,6 +104,87 @@ func TestEnnoblementSort_IsInConflict(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewEnnoblementCursor(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
validEnnoblementCursor := domaintest.NewEnnoblementCursor(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: validEnnoblementCursor.ID(),
|
||||||
|
serverKey: validEnnoblementCursor.ServerKey(),
|
||||||
|
createdAt: validEnnoblementCursor.CreatedAt(),
|
||||||
|
},
|
||||||
|
expectedErr: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: id < 1",
|
||||||
|
args: args{
|
||||||
|
id: 0,
|
||||||
|
serverKey: validEnnoblementCursor.ServerKey(),
|
||||||
|
createdAt: validEnnoblementCursor.CreatedAt(),
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "EnnoblementCursor",
|
||||||
|
Field: "id",
|
||||||
|
Err: domain.MinGreaterEqualError{
|
||||||
|
Min: 1,
|
||||||
|
Current: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, serverKeyTest := range newServerKeyValidationTests() {
|
||||||
|
tests = append(tests, test{
|
||||||
|
name: serverKeyTest.name,
|
||||||
|
args: args{
|
||||||
|
id: validEnnoblementCursor.ID(),
|
||||||
|
serverKey: serverKeyTest.key,
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "EnnoblementCursor",
|
||||||
|
Field: "serverKey",
|
||||||
|
Err: serverKeyTest.expectedErr,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ec, err := domain.NewEnnoblementCursor(
|
||||||
|
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, ec.ID())
|
||||||
|
assert.Equal(t, tt.args.serverKey, ec.ServerKey())
|
||||||
|
assert.Equal(t, tt.args.createdAt, ec.CreatedAt())
|
||||||
|
assert.NotEmpty(t, ec.Encode())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestListEnnoblementsParams_SetServerKeys(t *testing.T) {
|
func TestListEnnoblementsParams_SetServerKeys(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -246,6 +329,86 @@ func TestListEnnoblementsParams_SetSort(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListEnnoblementsParams_SetEncodedCursor(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
validCursor := domaintest.NewEnnoblementCursor(t)
|
||||||
|
|
||||||
|
type args struct {
|
||||||
|
cursor string
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
expectedCursor domain.EnnoblementCursor
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "OK",
|
||||||
|
args: args{
|
||||||
|
cursor: validCursor.Encode(),
|
||||||
|
},
|
||||||
|
expectedCursor: validCursor,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: len(cursor) < 1",
|
||||||
|
args: args{
|
||||||
|
cursor: "",
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "ListEnnoblementsParams",
|
||||||
|
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: "ListEnnoblementsParams",
|
||||||
|
Field: "cursor",
|
||||||
|
Err: domain.LenOutOfRangeError{
|
||||||
|
Min: 1,
|
||||||
|
Max: 1000,
|
||||||
|
Current: 1001,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ERR: malformed base64",
|
||||||
|
args: args{
|
||||||
|
cursor: "112345",
|
||||||
|
},
|
||||||
|
expectedErr: domain.ValidationError{
|
||||||
|
Model: "ListEnnoblementsParams",
|
||||||
|
Field: "cursor",
|
||||||
|
Err: domain.ErrInvalidCursor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
params := domain.NewListEnnoblementsParams()
|
||||||
|
|
||||||
|
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 TestListEnnoblementsParams_SetLimit(t *testing.T) {
|
func TestListEnnoblementsParams_SetLimit(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
@ -309,51 +472,46 @@ func TestListEnnoblementsParams_SetLimit(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListEnnoblementsParams_SetOffset(t *testing.T) {
|
func TestNewListEnnoblementsResult(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
type args struct {
|
ennoblements := domain.Ennoblements{
|
||||||
offset int
|
domaintest.NewEnnoblement(t),
|
||||||
|
domaintest.NewEnnoblement(t),
|
||||||
|
domaintest.NewEnnoblement(t),
|
||||||
}
|
}
|
||||||
|
next := domaintest.NewEnnoblement(t)
|
||||||
|
|
||||||
tests := []struct {
|
t.Run("OK: with next", func(t *testing.T) {
|
||||||
name string
|
|
||||||
args args
|
|
||||||
expectedErr error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "OK",
|
|
||||||
args: args{
|
|
||||||
offset: 100,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "ERR: offset < 0",
|
|
||||||
args: args{
|
|
||||||
offset: -1,
|
|
||||||
},
|
|
||||||
expectedErr: domain.ValidationError{
|
|
||||||
Model: "ListEnnoblementsParams",
|
|
||||||
Field: "offset",
|
|
||||||
Err: domain.MinGreaterEqualError{
|
|
||||||
Min: 0,
|
|
||||||
Current: -1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
params := domain.NewListEnnoblementsParams()
|
res, err := domain.NewListEnnoblementsResult(ennoblements, next)
|
||||||
|
require.NoError(t, err)
|
||||||
require.ErrorIs(t, params.SetOffset(tt.args.offset), tt.expectedErr)
|
assert.Equal(t, ennoblements, res.Ennoblements())
|
||||||
if tt.expectedErr != nil {
|
assert.Equal(t, ennoblements[0].ID(), res.Self().ID())
|
||||||
return
|
assert.Equal(t, ennoblements[0].ServerKey(), res.Self().ServerKey())
|
||||||
}
|
assert.Equal(t, next.ID(), res.Next().ID())
|
||||||
assert.Equal(t, tt.args.offset, params.Offset())
|
assert.Equal(t, next.ServerKey(), res.Next().ServerKey())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("OK: without next", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
res, err := domain.NewListEnnoblementsResult(ennoblements, domain.Ennoblement{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, ennoblements, res.Ennoblements())
|
||||||
|
assert.Equal(t, ennoblements[0].ID(), res.Self().ID())
|
||||||
|
assert.Equal(t, ennoblements[0].ServerKey(), res.Self().ServerKey())
|
||||||
|
assert.True(t, res.Next().IsZero())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("OK: 0 ennoblements", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
res, err := domain.NewListEnnoblementsResult(nil, domain.Ennoblement{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Zero(t, res.Ennoblements())
|
||||||
|
assert.True(t, res.Self().IsZero())
|
||||||
|
assert.True(t, res.Next().IsZero())
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,16 +204,16 @@ func TestEnnoblementSync(t *testing.T) {
|
||||||
allEnnoblements := make(domain.Ennoblements, 0, len(expectedEnnoblements))
|
allEnnoblements := make(domain.Ennoblements, 0, len(expectedEnnoblements))
|
||||||
|
|
||||||
for {
|
for {
|
||||||
ennoblements, err := ennoblementRepo.List(ctx, listParams)
|
res, err := ennoblementRepo.List(ctx, listParams)
|
||||||
require.NoError(collect, err)
|
require.NoError(collect, err)
|
||||||
|
|
||||||
if len(ennoblements) == 0 {
|
allEnnoblements = append(allEnnoblements, res.Ennoblements()...)
|
||||||
|
|
||||||
|
if res.Next().IsZero() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
allEnnoblements = append(allEnnoblements, ennoblements...)
|
require.NoError(collect, listParams.SetCursor(res.Next()))
|
||||||
|
|
||||||
require.NoError(collect, listParams.SetOffset(listParams.Offset()+domain.EnnoblementListMaxLimit))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assert.Len(collect, allEnnoblements, len(expectedEnnoblements)) {
|
if !assert.Len(collect, allEnnoblements, len(expectedEnnoblements)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user