refactor: new PrependSortString logic (#35)
ci/woodpecker/push/govulncheck Pipeline was successful Details
ci/woodpecker/push/test Pipeline was successful Details

Reviewed-on: twhelp/corev3#35
This commit is contained in:
Dawid Wysokiński 2024-03-25 07:29:37 +00:00
parent 4819ec39cd
commit 99b187d930
31 changed files with 872 additions and 763 deletions

View File

@ -1737,7 +1737,7 @@ components:
enum: enum:
- createdAt:ASC - createdAt:ASC
- createdAt:DESC - createdAt:DESC
maxItems: 2 maxItems: 1
TribeChangeSortQueryParam: TribeChangeSortQueryParam:
name: sort name: sort
in: query in: query
@ -1751,7 +1751,7 @@ components:
enum: enum:
- createdAt:ASC - createdAt:ASC
- createdAt:DESC - createdAt:DESC
maxItems: 2 maxItems: 1
TribeSnapshotSortQueryParam: TribeSnapshotSortQueryParam:
name: sort name: sort
in: query in: query
@ -1765,7 +1765,7 @@ components:
enum: enum:
- date:ASC - date:ASC
- date:DESC - date:DESC
maxItems: 2 maxItems: 1
PlayerSnapshotSortQueryParam: PlayerSnapshotSortQueryParam:
name: sort name: sort
in: query in: query
@ -1779,7 +1779,7 @@ components:
enum: enum:
- date:ASC - date:ASC
- date:DESC - date:DESC
maxItems: 2 maxItems: 1
SinceQueryParam: SinceQueryParam:
name: since name: since
in: query in: query

View File

@ -485,7 +485,7 @@ func (params *ListEnnoblementsParams) Sort() []EnnoblementSort {
} }
const ( const (
ennoblementSortMinLength = 1 ennoblementSortMinLength = 0
ennoblementSortMaxLength = 3 ennoblementSortMaxLength = 3
) )
@ -503,12 +503,12 @@ func (params *ListEnnoblementsParams) SetSort(sort []EnnoblementSort) error {
return nil return nil
} }
func (params *ListEnnoblementsParams) PrependSortString(sort []string) error { func (params *ListEnnoblementsParams) PrependSortString(sort []string, allowed []EnnoblementSort, maxLength int) error {
if err := validateSliceLen( if len(sort) == 0 {
sort, return nil
ennoblementSortMinLength, }
max(ennoblementSortMaxLength-len(params.sort), 0),
); err != nil { if err := validateSliceLen(sort, 0, max(min(ennoblementSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
return ValidationError{ return ValidationError{
Model: listEnnoblementsParamsModelName, Model: listEnnoblementsParamsModelName,
Field: "sort", Field: "sort",
@ -519,11 +519,7 @@ func (params *ListEnnoblementsParams) PrependSortString(sort []string) error {
toPrepend := make([]EnnoblementSort, 0, len(sort)) toPrepend := make([]EnnoblementSort, 0, len(sort))
for i, s := range sort { for i, s := range sort {
converted, err := newSortFromString( converted, err := newSortFromString(s, allowed...)
s,
EnnoblementSortCreatedAtASC,
EnnoblementSortCreatedAtDESC,
)
if err != nil { if err != nil {
return SliceElementValidationError{ return SliceElementValidationError{
Model: listEnnoblementsParamsModelName, Model: listEnnoblementsParamsModelName,

View File

@ -442,19 +442,10 @@ func TestListEnnoblementsParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListEnnoblementsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 3", name: "ERR: len(sort) > 3",
@ -470,7 +461,7 @@ func TestListEnnoblementsParams_SetSort(t *testing.T) {
Model: "ListEnnoblementsParams", Model: "ListEnnoblementsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 3,
Current: 4, Current: 4,
}, },
@ -516,9 +507,20 @@ func TestListEnnoblementsParams_PrependSortString(t *testing.T) {
t.Helper() t.Helper()
return domain.ListEnnoblementsParams{} return domain.ListEnnoblementsParams{}
} }
defaultAllowed := []domain.EnnoblementSort{
domain.EnnoblementSortCreatedAtASC,
domain.EnnoblementSortCreatedAtDESC,
domain.EnnoblementSortIDASC,
domain.EnnoblementSortIDDESC,
domain.EnnoblementSortServerKeyASC,
domain.EnnoblementSortServerKeyDESC,
}
defaultMaxLength := 3
type args struct { type args struct {
sort []string sort []string
allowed []domain.EnnoblementSort
maxLength int
} }
tests := []struct { tests := []struct {
@ -529,44 +531,73 @@ func TestListEnnoblementsParams_PrependSortString(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "OK: [createdAt:ASC]", name: "OK: [serverKey:ASC, createdAt:ASC, id:ASC]",
args: args{
sort: []string{
"serverKey:ASC",
"createdAt:ASC",
"id:ASC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.EnnoblementSort{
domain.EnnoblementSortServerKeyASC,
domain.EnnoblementSortCreatedAtASC,
domain.EnnoblementSortIDASC,
},
},
{
name: "OK: [serverKey:DESC, createdAt:DESC, id:DESC]",
args: args{
sort: []string{
"serverKey:DESC",
"createdAt:DESC",
"id:DESC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.EnnoblementSort{
domain.EnnoblementSortServerKeyDESC,
domain.EnnoblementSortCreatedAtDESC,
domain.EnnoblementSortIDDESC,
},
},
{
name: "OK: custom params",
newParams: func(t *testing.T) domain.ListEnnoblementsParams {
t.Helper()
params := domain.NewListEnnoblementsParams()
require.NoError(t, params.SetSort([]domain.EnnoblementSort{
domain.EnnoblementSortIDASC,
domain.EnnoblementSortServerKeyASC,
}))
return params
},
args: args{ args: args{
sort: []string{ sort: []string{
"createdAt:ASC", "createdAt:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.EnnoblementSort{ expectedSort: []domain.EnnoblementSort{
domain.EnnoblementSortCreatedAtASC, domain.EnnoblementSortCreatedAtASC,
domain.EnnoblementSortIDASC,
domain.EnnoblementSortServerKeyASC,
}, },
}, },
{ {
name: "OK: [createdAt:DESC]", name: "OK: empty slice",
args: args{ args: args{
sort: []string{ sort: nil,
"createdAt:DESC", allowed: defaultAllowed,
}, maxLength: defaultMaxLength,
},
expectedSort: []domain.EnnoblementSort{
domain.EnnoblementSortCreatedAtDESC,
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "ERR: custom params + len(sort) > sortMaxLength - len(sort)",
args: args{
sort: nil,
},
expectedErr: domain.ValidationError{
Model: "ListEnnoblementsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
},
{
name: "ERR: custom params + len(sort) > 1",
newParams: func(t *testing.T) domain.ListEnnoblementsParams { newParams: func(t *testing.T) domain.ListEnnoblementsParams {
t.Helper() t.Helper()
params := domain.NewListEnnoblementsParams() params := domain.NewListEnnoblementsParams()
@ -581,12 +612,35 @@ func TestListEnnoblementsParams_PrependSortString(t *testing.T) {
"createdAt:ASC", "createdAt:ASC",
"createdAt:DESC", "createdAt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListEnnoblementsParams", Model: "ListEnnoblementsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 1,
Current: 2,
},
},
},
{
name: "ERR: len(sort) > maxLength",
newParams: defaultNewParams,
args: args{
sort: []string{
"serverKey:ASC",
"createdAt:ASC",
},
allowed: defaultAllowed,
maxLength: 1,
},
expectedErr: domain.ValidationError{
Model: "ListEnnoblementsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 0,
Max: 1, Max: 1,
Current: 2, Current: 2,
}, },
@ -599,6 +653,8 @@ func TestListEnnoblementsParams_PrependSortString(t *testing.T) {
sort: []string{ sort: []string{
"createdAt:", "createdAt:",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.SliceElementValidationError{ expectedErr: domain.SliceElementValidationError{
Model: "ListEnnoblementsParams", Model: "ListEnnoblementsParams",
@ -616,6 +672,8 @@ func TestListEnnoblementsParams_PrependSortString(t *testing.T) {
"createdAt:ASC", "createdAt:ASC",
"createdAt:DESC", "createdAt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListEnnoblementsParams", Model: "ListEnnoblementsParams",
@ -637,7 +695,7 @@ func TestListEnnoblementsParams_PrependSortString(t *testing.T) {
} }
params := newParams(t) params := newParams(t)
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) require.ErrorIs(t, params.PrependSortString(tt.args.sort, tt.args.allowed, tt.args.maxLength), tt.expectedErr)
if tt.expectedErr != nil { if tt.expectedErr != nil {
return return
} }

View File

@ -940,8 +940,8 @@ func (params *ListPlayersParams) Sort() []PlayerSort {
} }
const ( const (
playerSortMinLength = 1 playerSortMinLength = 0
playerSortMaxLength = 3 playerSortMaxLength = 4
) )
func (params *ListPlayersParams) SetSort(sort []PlayerSort) error { func (params *ListPlayersParams) SetSort(sort []PlayerSort) error {
@ -958,8 +958,12 @@ func (params *ListPlayersParams) SetSort(sort []PlayerSort) error {
return nil return nil
} }
func (params *ListPlayersParams) PrependSortString(sort []string) error { func (params *ListPlayersParams) PrependSortString(sort []string, allowed []PlayerSort, maxLength int) error {
if err := validateSliceLen(sort, playerSortMinLength, max(playerSortMaxLength-len(params.sort), 0)); err != nil { if len(sort) == 0 {
return nil
}
if err := validateSliceLen(sort, 0, max(min(playerSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
return ValidationError{ return ValidationError{
Model: listPlayersParamsModelName, Model: listPlayersParamsModelName,
Field: "sort", Field: "sort",
@ -970,21 +974,7 @@ func (params *ListPlayersParams) PrependSortString(sort []string) error {
toPrepend := make([]PlayerSort, 0, len(sort)) toPrepend := make([]PlayerSort, 0, len(sort))
for i, s := range sort { for i, s := range sort {
converted, err := newSortFromString( converted, err := newSortFromString(s, allowed...)
s,
PlayerSortODScoreAttASC,
PlayerSortODScoreAttDESC,
PlayerSortODScoreDefASC,
PlayerSortODScoreDefDESC,
PlayerSortODScoreSupASC,
PlayerSortODScoreSupDESC,
PlayerSortODScoreTotalASC,
PlayerSortODScoreTotalDESC,
PlayerSortPointsASC,
PlayerSortPointsDESC,
PlayerSortDeletedAtASC,
PlayerSortDeletedAtDESC,
)
if err != nil { if err != nil {
return SliceElementValidationError{ return SliceElementValidationError{
Model: listPlayersParamsModelName, Model: listPlayersParamsModelName,

View File

@ -431,7 +431,7 @@ func (params *ListPlayerSnapshotsParams) Sort() []PlayerSnapshotSort {
} }
const ( const (
playerSnapshotSortMinLength = 1 playerSnapshotSortMinLength = 0
playerSnapshotSortMaxLength = 3 playerSnapshotSortMaxLength = 3
) )
@ -449,12 +449,16 @@ func (params *ListPlayerSnapshotsParams) SetSort(sort []PlayerSnapshotSort) erro
return nil return nil
} }
func (params *ListPlayerSnapshotsParams) PrependSortString(sort []string) error { func (params *ListPlayerSnapshotsParams) PrependSortString(
if err := validateSliceLen( sort []string,
sort, allowed []PlayerSnapshotSort,
playerSnapshotSortMinLength, maxLength int,
max(playerSnapshotSortMaxLength-len(params.sort), 0), ) error {
); err != nil { if len(sort) == 0 {
return nil
}
if err := validateSliceLen(sort, 0, max(min(playerSnapshotSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
return ValidationError{ return ValidationError{
Model: listPlayerSnapshotsParamsModelName, Model: listPlayerSnapshotsParamsModelName,
Field: "sort", Field: "sort",
@ -465,11 +469,7 @@ func (params *ListPlayerSnapshotsParams) PrependSortString(sort []string) error
toPrepend := make([]PlayerSnapshotSort, 0, len(sort)) toPrepend := make([]PlayerSnapshotSort, 0, len(sort))
for i, s := range sort { for i, s := range sort {
converted, err := newSortFromString( converted, err := newSortFromString(s, allowed...)
s,
PlayerSnapshotSortDateASC,
PlayerSnapshotSortDateDESC,
)
if err != nil { if err != nil {
return SliceElementValidationError{ return SliceElementValidationError{
Model: listPlayerSnapshotsParamsModelName, Model: listPlayerSnapshotsParamsModelName,

View File

@ -327,19 +327,10 @@ func TestListPlayerSnapshotsParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListPlayerSnapshotsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 3", name: "ERR: len(sort) > 3",
@ -355,7 +346,7 @@ func TestListPlayerSnapshotsParams_SetSort(t *testing.T) {
Model: "ListPlayerSnapshotsParams", Model: "ListPlayerSnapshotsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 3,
Current: 4, Current: 4,
}, },
@ -401,9 +392,20 @@ func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) {
t.Helper() t.Helper()
return domain.ListPlayerSnapshotsParams{} return domain.ListPlayerSnapshotsParams{}
} }
defaultAllowed := []domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortDateASC,
domain.PlayerSnapshotSortDateDESC,
domain.PlayerSnapshotSortIDASC,
domain.PlayerSnapshotSortIDDESC,
domain.PlayerSnapshotSortServerKeyASC,
domain.PlayerSnapshotSortServerKeyDESC,
}
defaultMaxLength := 3
type args struct { type args struct {
sort []string sort []string
allowed []domain.PlayerSnapshotSort
maxLength int
} }
tests := []struct { tests := []struct {
@ -414,44 +416,71 @@ func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "OK: [date:ASC]", name: "OK: [id:ASC, date:ASC, serverKey:ASC]",
args: args{
sort: []string{
"id:ASC",
"date:ASC",
"serverKey:ASC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortIDASC,
domain.PlayerSnapshotSortDateASC,
domain.PlayerSnapshotSortServerKeyASC,
},
},
{
name: "OK: [id:DESC, date:DESC, serverKey:DESC]",
args: args{
sort: []string{
"id:DESC",
"date:DESC",
"serverKey:DESC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortIDDESC,
domain.PlayerSnapshotSortDateDESC,
domain.PlayerSnapshotSortServerKeyDESC,
},
},
{
name: "OK: custom params",
newParams: func(t *testing.T) domain.ListPlayerSnapshotsParams {
t.Helper()
params := domain.NewListPlayerSnapshotsParams()
require.NoError(t, params.SetSort([]domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortIDASC,
domain.PlayerSnapshotSortServerKeyASC,
}))
return params
},
args: args{ args: args{
sort: []string{ sort: []string{
"date:ASC", "date:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.PlayerSnapshotSort{ expectedSort: []domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortDateASC, domain.PlayerSnapshotSortDateASC,
domain.PlayerSnapshotSortIDASC,
domain.PlayerSnapshotSortServerKeyASC,
}, },
}, },
{ {
name: "OK: [date:DESC]", name: "OK: empty slice",
args: args{
sort: []string{
"date:DESC",
},
},
expectedSort: []domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortDateDESC,
},
},
{
name: "ERR: len(sort) < 1",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListPlayerSnapshotsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: custom params + len(sort) > 1", name: "ERR: custom params + len(sort) > sortMaxLength - len(sort)",
newParams: func(t *testing.T) domain.ListPlayerSnapshotsParams { newParams: func(t *testing.T) domain.ListPlayerSnapshotsParams {
t.Helper() t.Helper()
params := domain.NewListPlayerSnapshotsParams() params := domain.NewListPlayerSnapshotsParams()
@ -466,12 +495,35 @@ func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) {
"date:ASC", "date:ASC",
"date:DESC", "date:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListPlayerSnapshotsParams", Model: "ListPlayerSnapshotsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 1,
Current: 2,
},
},
},
{
name: "ERR: len(sort) > maxLength",
newParams: defaultNewParams,
args: args{
sort: []string{
"serverKey:ASC",
"date:ASC",
},
allowed: defaultAllowed,
maxLength: 1,
},
expectedErr: domain.ValidationError{
Model: "ListPlayerSnapshotsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 0,
Max: 1, Max: 1,
Current: 2, Current: 2,
}, },
@ -484,6 +536,8 @@ func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) {
sort: []string{ sort: []string{
"date:", "date:",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.SliceElementValidationError{ expectedErr: domain.SliceElementValidationError{
Model: "ListPlayerSnapshotsParams", Model: "ListPlayerSnapshotsParams",
@ -501,6 +555,8 @@ func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) {
"date:ASC", "date:ASC",
"date:DESC", "date:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListPlayerSnapshotsParams", Model: "ListPlayerSnapshotsParams",
@ -522,7 +578,7 @@ func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) {
} }
params := newParams(t) params := newParams(t)
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) require.ErrorIs(t, params.PrependSortString(tt.args.sort, tt.args.allowed, tt.args.maxLength), tt.expectedErr)
if tt.expectedErr != nil { if tt.expectedErr != nil {
return return
} }

View File

@ -837,37 +837,29 @@ func TestListPlayersParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListPlayersParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 3", name: "ERR: len(sort) > 4",
args: args{ args: args{
sort: []domain.PlayerSort{ sort: []domain.PlayerSort{
domain.PlayerSortDeletedAtDESC, domain.PlayerSortDeletedAtDESC,
domain.PlayerSortPointsASC, domain.PlayerSortPointsASC,
domain.PlayerSortIDASC, domain.PlayerSortIDASC,
domain.PlayerSortServerKeyASC, domain.PlayerSortServerKeyASC,
domain.PlayerSortServerKeyASC,
}, },
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListPlayersParams", Model: "ListPlayersParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 4,
Current: 4, Current: 5,
}, },
}, },
}, },
@ -911,9 +903,30 @@ func TestListPlayersParams_PrependSortString(t *testing.T) {
t.Helper() t.Helper()
return domain.ListPlayersParams{} return domain.ListPlayersParams{}
} }
defaultAllowed := []domain.PlayerSort{
domain.PlayerSortIDASC,
domain.PlayerSortIDDESC,
domain.PlayerSortServerKeyASC,
domain.PlayerSortServerKeyDESC,
domain.PlayerSortODScoreAttASC,
domain.PlayerSortODScoreAttDESC,
domain.PlayerSortODScoreDefASC,
domain.PlayerSortODScoreDefDESC,
domain.PlayerSortODScoreSupASC,
domain.PlayerSortODScoreSupDESC,
domain.PlayerSortODScoreTotalASC,
domain.PlayerSortODScoreTotalDESC,
domain.PlayerSortPointsASC,
domain.PlayerSortPointsDESC,
domain.PlayerSortDeletedAtASC,
domain.PlayerSortDeletedAtDESC,
}
defaultMaxLength := 4
type args struct { type args struct {
sort []string sort []string
allowed []domain.PlayerSort
maxLength int
} }
tests := []struct { tests := []struct {
@ -924,106 +937,145 @@ func TestListPlayersParams_PrependSortString(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "OK: [odScoreAtt:ASC, odScoreDef:ASC, odScoreTotal:ASC]", name: "OK: [id:ASC, odScoreAtt:ASC, odScoreDef:ASC, odScoreTotal:ASC]",
args: args{ args: args{
sort: []string{ sort: []string{
"id:ASC",
"odScoreAtt:ASC", "odScoreAtt:ASC",
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:ASC", "odScoreTotal:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.PlayerSort{ expectedSort: []domain.PlayerSort{
domain.PlayerSortIDASC,
domain.PlayerSortODScoreAttASC, domain.PlayerSortODScoreAttASC,
domain.PlayerSortODScoreDefASC, domain.PlayerSortODScoreDefASC,
domain.PlayerSortODScoreTotalASC, domain.PlayerSortODScoreTotalASC,
}, },
}, },
{ {
name: "OK: [odScoreAtt:DESC, odScoreDef:DESC, odScoreTotal:DESC]", name: "OK: [id:DESC, odScoreAtt:DESC, odScoreDef:DESC, odScoreTotal:DESC]",
args: args{ args: args{
sort: []string{ sort: []string{
"id:DESC",
"odScoreAtt:DESC", "odScoreAtt:DESC",
"odScoreDef:DESC", "odScoreDef:DESC",
"odScoreTotal:DESC", "odScoreTotal:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.PlayerSort{ expectedSort: []domain.PlayerSort{
domain.PlayerSortIDDESC,
domain.PlayerSortODScoreAttDESC, domain.PlayerSortODScoreAttDESC,
domain.PlayerSortODScoreDefDESC, domain.PlayerSortODScoreDefDESC,
domain.PlayerSortODScoreTotalDESC, domain.PlayerSortODScoreTotalDESC,
}, },
}, },
{ {
name: "OK: [odScoreSup:ASC, points:ASC, deletedAt:ASC]", name: "OK: [serverKey:ASC, odScoreSup:ASC, points:ASC, deletedAt:ASC]",
args: args{ args: args{
sort: []string{ sort: []string{
"serverKey:ASC",
"odScoreSup:ASC", "odScoreSup:ASC",
"points:ASC", "points:ASC",
"deletedAt:ASC", "deletedAt:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.PlayerSort{ expectedSort: []domain.PlayerSort{
domain.PlayerSortServerKeyASC,
domain.PlayerSortODScoreSupASC, domain.PlayerSortODScoreSupASC,
domain.PlayerSortPointsASC, domain.PlayerSortPointsASC,
domain.PlayerSortDeletedAtASC, domain.PlayerSortDeletedAtASC,
}, },
}, },
{ {
name: "OK: [odScoreSup:DESC, points:DESC, deletedAt:DESC]", name: "OK: [serverKey: DESC, odScoreSup:DESC, points:DESC, deletedAt:DESC]",
args: args{ args: args{
sort: []string{ sort: []string{
"serverKey:DESC",
"odScoreSup:DESC", "odScoreSup:DESC",
"points:DESC", "points:DESC",
"deletedAt:DESC", "deletedAt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.PlayerSort{ expectedSort: []domain.PlayerSort{
domain.PlayerSortServerKeyDESC,
domain.PlayerSortODScoreSupDESC, domain.PlayerSortODScoreSupDESC,
domain.PlayerSortPointsDESC, domain.PlayerSortPointsDESC,
domain.PlayerSortDeletedAtDESC, domain.PlayerSortDeletedAtDESC,
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: custom params",
args: args{ newParams: func(t *testing.T) domain.ListPlayersParams {
sort: nil, t.Helper()
params := domain.NewListPlayersParams()
require.NoError(t, params.SetSort([]domain.PlayerSort{
domain.PlayerSortIDASC,
domain.PlayerSortServerKeyASC,
}))
return params
}, },
expectedErr: domain.ValidationError{ args: args{
Model: "ListPlayersParams", sort: []string{
Field: "sort", "points:DESC",
Err: domain.LenOutOfRangeError{ "deletedAt:DESC",
Min: 1,
Max: 3,
Current: 0,
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.PlayerSort{
domain.PlayerSortPointsDESC,
domain.PlayerSortDeletedAtDESC,
domain.PlayerSortIDASC,
domain.PlayerSortServerKeyASC,
}, },
}, },
{ {
name: "ERR: len(sort) > 3", name: "OK: empty slice",
args: args{
sort: nil,
},
},
{
name: "ERR: len(sort) > 4",
args: args{ args: args{
sort: []string{ sort: []string{
"odScoreAtt:ASC", "odScoreAtt:ASC",
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:ASC", "odScoreTotal:ASC",
"points:ASC", "points:ASC",
"points:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListPlayersParams", Model: "ListPlayersParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 4,
Current: 4, Current: 5,
}, },
}, },
}, },
{ {
name: "ERR: custom params + len(sort) > 2", name: "ERR: custom params + len(sort) > sortMaxLength - len(sort)",
newParams: func(t *testing.T) domain.ListPlayersParams { newParams: func(t *testing.T) domain.ListPlayersParams {
t.Helper() t.Helper()
params := domain.NewListPlayersParams() params := domain.NewListPlayersParams()
require.NoError(t, params.SetSort([]domain.PlayerSort{domain.PlayerSortIDASC})) require.NoError(t, params.SetSort([]domain.PlayerSort{
domain.PlayerSortIDASC,
domain.PlayerSortServerKeyASC,
}))
return params return params
}, },
args: args{ args: args{
@ -1032,17 +1084,40 @@ func TestListPlayersParams_PrependSortString(t *testing.T) {
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:ASC", "odScoreTotal:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListPlayersParams", Model: "ListPlayersParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: 3, Current: 3,
}, },
}, },
}, },
{
name: "ERR: len(sort) > maxLength",
newParams: defaultNewParams,
args: args{
sort: []string{
"serverKey:ASC",
"odScoreAtt:ASC",
},
allowed: defaultAllowed,
maxLength: 1,
},
expectedErr: domain.ValidationError{
Model: "ListPlayersParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 0,
Max: 1,
Current: 2,
},
},
},
{ {
name: "ERR: unsupported sort string", name: "ERR: unsupported sort string",
newParams: defaultNewParams, newParams: defaultNewParams,
@ -1052,6 +1127,8 @@ func TestListPlayersParams_PrependSortString(t *testing.T) {
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:", "odScoreTotal:",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.SliceElementValidationError{ expectedErr: domain.SliceElementValidationError{
Model: "ListPlayersParams", Model: "ListPlayersParams",
@ -1069,6 +1146,8 @@ func TestListPlayersParams_PrependSortString(t *testing.T) {
"odScoreAtt:ASC", "odScoreAtt:ASC",
"odScoreAtt:DESC", "odScoreAtt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListPlayersParams", Model: "ListPlayersParams",
@ -1090,7 +1169,7 @@ func TestListPlayersParams_PrependSortString(t *testing.T) {
} }
params := newParams(t) params := newParams(t)
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) require.ErrorIs(t, params.PrependSortString(tt.args.sort, tt.args.allowed, tt.args.maxLength), tt.expectedErr)
if tt.expectedErr != nil { if tt.expectedErr != nil {
return return
} }

View File

@ -766,7 +766,7 @@ func (params *ListServersParams) Sort() []ServerSort {
} }
const ( const (
serverSortMinLength = 1 serverSortMinLength = 0
serverSortMaxLength = 2 serverSortMaxLength = 2
) )

View File

@ -682,19 +682,10 @@ func TestListServersParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListServersParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 2,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 2",
@ -709,7 +700,7 @@ func TestListServersParams_SetSort(t *testing.T) {
Model: "ListServersParams", Model: "ListServersParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: 3, Current: 3,
}, },

View File

@ -827,8 +827,8 @@ func (params *ListTribesParams) Sort() []TribeSort {
} }
const ( const (
tribeSortMinLength = 1 tribeSortMinLength = 0
tribeSortMaxLength = 3 tribeSortMaxLength = 4
) )
func (params *ListTribesParams) SetSort(sort []TribeSort) error { func (params *ListTribesParams) SetSort(sort []TribeSort) error {
@ -845,8 +845,12 @@ func (params *ListTribesParams) SetSort(sort []TribeSort) error {
return nil return nil
} }
func (params *ListTribesParams) PrependSortString(sort []string) error { func (params *ListTribesParams) PrependSortString(sort []string, allowed []TribeSort, maxLength int) error {
if err := validateSliceLen(sort, tribeSortMinLength, max(tribeSortMaxLength-len(params.sort), 0)); err != nil { if len(sort) == 0 {
return nil
}
if err := validateSliceLen(sort, 0, max(min(tribeSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
return ValidationError{ return ValidationError{
Model: listTribesParamsModelName, Model: listTribesParamsModelName,
Field: "sort", Field: "sort",
@ -857,21 +861,7 @@ func (params *ListTribesParams) PrependSortString(sort []string) error {
toPrepend := make([]TribeSort, 0, len(sort)) toPrepend := make([]TribeSort, 0, len(sort))
for i, s := range sort { for i, s := range sort {
converted, err := newSortFromString( converted, err := newSortFromString(s, allowed...)
s,
TribeSortODScoreAttASC,
TribeSortODScoreAttDESC,
TribeSortODScoreDefASC,
TribeSortODScoreDefDESC,
TribeSortODScoreTotalASC,
TribeSortODScoreTotalDESC,
TribeSortPointsASC,
TribeSortPointsDESC,
TribeSortDominanceASC,
TribeSortDominanceDESC,
TribeSortDeletedAtASC,
TribeSortDeletedAtDESC,
)
if err != nil { if err != nil {
return SliceElementValidationError{ return SliceElementValidationError{
Model: listTribesParamsModelName, Model: listTribesParamsModelName,

View File

@ -495,7 +495,7 @@ func (params *ListTribeChangesParams) Sort() []TribeChangeSort {
} }
const ( const (
tribeChangeSortMinLength = 1 tribeChangeSortMinLength = 0
tribeChangeSortMaxLength = 3 tribeChangeSortMaxLength = 3
) )
@ -555,12 +555,16 @@ func (params *ListTribeChangesParams) SetLimit(limit int) error {
return nil return nil
} }
func (params *ListTribeChangesParams) PrependSortString(sort []string) error { func (params *ListTribeChangesParams) PrependSortString(
if err := validateSliceLen( sort []string,
sort, allowed []TribeChangeSort,
tribeChangeSortMinLength, maxLength int,
max(tribeChangeSortMaxLength-len(params.sort), 0), ) error {
); err != nil { if len(sort) == 0 {
return nil
}
if err := validateSliceLen(sort, 0, max(min(tribeChangeSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
return ValidationError{ return ValidationError{
Model: listTribeChangesParamsModelName, Model: listTribeChangesParamsModelName,
Field: "sort", Field: "sort",
@ -571,11 +575,7 @@ func (params *ListTribeChangesParams) PrependSortString(sort []string) error {
toPrepend := make([]TribeChangeSort, 0, len(sort)) toPrepend := make([]TribeChangeSort, 0, len(sort))
for i, s := range sort { for i, s := range sort {
converted, err := newSortFromString( converted, err := newSortFromString(s, allowed...)
s,
TribeChangeSortCreatedAtASC,
TribeChangeSortCreatedAtDESC,
)
if err != nil { if err != nil {
return SliceElementValidationError{ return SliceElementValidationError{
Model: listTribeChangesParamsModelName, Model: listTribeChangesParamsModelName,

View File

@ -558,19 +558,10 @@ func TestListTribeChangesParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListTribeChangesParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 3", name: "ERR: len(sort) > 3",
@ -586,7 +577,7 @@ func TestListTribeChangesParams_SetSort(t *testing.T) {
Model: "ListTribeChangesParams", Model: "ListTribeChangesParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 3,
Current: 4, Current: 4,
}, },
@ -632,9 +623,20 @@ func TestListTribeChangesParams_PrependSortString(t *testing.T) {
t.Helper() t.Helper()
return domain.ListTribeChangesParams{} return domain.ListTribeChangesParams{}
} }
defaultAllowed := []domain.TribeChangeSort{
domain.TribeChangeSortCreatedAtASC,
domain.TribeChangeSortCreatedAtDESC,
domain.TribeChangeSortIDASC,
domain.TribeChangeSortIDDESC,
domain.TribeChangeSortServerKeyASC,
domain.TribeChangeSortServerKeyDESC,
}
defaultMaxLength := 3
type args struct { type args struct {
sort []string sort []string
allowed []domain.TribeChangeSort
maxLength int
} }
tests := []struct { tests := []struct {
@ -645,44 +647,71 @@ func TestListTribeChangesParams_PrependSortString(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "OK: [createdAt:ASC]", name: "OK: [id:ASC, createdAt:ASC, serverKey:ASC]",
args: args{
sort: []string{
"id:ASC",
"createdAt:ASC",
"serverKey:ASC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.TribeChangeSort{
domain.TribeChangeSortIDASC,
domain.TribeChangeSortCreatedAtASC,
domain.TribeChangeSortServerKeyASC,
},
},
{
name: "OK: [id:DESC, createdAt:DESC, serverKey:DESC]",
args: args{
sort: []string{
"id:DESC",
"createdAt:DESC",
"serverKey:DESC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.TribeChangeSort{
domain.TribeChangeSortIDDESC,
domain.TribeChangeSortCreatedAtDESC,
domain.TribeChangeSortServerKeyDESC,
},
},
{
name: "OK: custom params",
newParams: func(t *testing.T) domain.ListTribeChangesParams {
t.Helper()
params := domain.NewListTribeChangesParams()
require.NoError(t, params.SetSort([]domain.TribeChangeSort{
domain.TribeChangeSortIDASC,
domain.TribeChangeSortServerKeyASC,
}))
return params
},
args: args{ args: args{
sort: []string{ sort: []string{
"createdAt:ASC", "createdAt:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.TribeChangeSort{ expectedSort: []domain.TribeChangeSort{
domain.TribeChangeSortCreatedAtASC, domain.TribeChangeSortCreatedAtASC,
domain.TribeChangeSortIDASC,
domain.TribeChangeSortServerKeyASC,
}, },
}, },
{ {
name: "OK: [createdAt:DESC]", name: "OK: empty slice",
args: args{
sort: []string{
"createdAt:DESC",
},
},
expectedSort: []domain.TribeChangeSort{
domain.TribeChangeSortCreatedAtDESC,
},
},
{
name: "ERR: len(sort) < 1",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListTribeChangesParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: custom params + len(sort) > 1", name: "ERR: custom params + len(sort) > sortMaxLength - len(sort)",
newParams: func(t *testing.T) domain.ListTribeChangesParams { newParams: func(t *testing.T) domain.ListTribeChangesParams {
t.Helper() t.Helper()
params := domain.NewListTribeChangesParams() params := domain.NewListTribeChangesParams()
@ -697,12 +726,35 @@ func TestListTribeChangesParams_PrependSortString(t *testing.T) {
"createdAt:ASC", "createdAt:ASC",
"createdAt:DESC", "createdAt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribeChangesParams", Model: "ListTribeChangesParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 1,
Current: 2,
},
},
},
{
name: "ERR: len(sort) > maxLength",
newParams: defaultNewParams,
args: args{
sort: []string{
"serverKey:ASC",
"createdAt:ASC",
},
allowed: defaultAllowed,
maxLength: 1,
},
expectedErr: domain.ValidationError{
Model: "ListTribeChangesParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 0,
Max: 1, Max: 1,
Current: 2, Current: 2,
}, },
@ -715,6 +767,8 @@ func TestListTribeChangesParams_PrependSortString(t *testing.T) {
sort: []string{ sort: []string{
"createdAt:", "createdAt:",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.SliceElementValidationError{ expectedErr: domain.SliceElementValidationError{
Model: "ListTribeChangesParams", Model: "ListTribeChangesParams",
@ -732,6 +786,8 @@ func TestListTribeChangesParams_PrependSortString(t *testing.T) {
"createdAt:ASC", "createdAt:ASC",
"createdAt:DESC", "createdAt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribeChangesParams", Model: "ListTribeChangesParams",
@ -753,7 +809,7 @@ func TestListTribeChangesParams_PrependSortString(t *testing.T) {
} }
params := newParams(t) params := newParams(t)
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) require.ErrorIs(t, params.PrependSortString(tt.args.sort, tt.args.allowed, tt.args.maxLength), tt.expectedErr)
if tt.expectedErr != nil { if tt.expectedErr != nil {
return return
} }

View File

@ -451,7 +451,7 @@ func (params *ListTribeSnapshotsParams) Sort() []TribeSnapshotSort {
} }
const ( const (
tribeSnapshotSortMinLength = 1 tribeSnapshotSortMinLength = 0
tribeSnapshotSortMaxLength = 3 tribeSnapshotSortMaxLength = 3
) )
@ -469,12 +469,16 @@ func (params *ListTribeSnapshotsParams) SetSort(sort []TribeSnapshotSort) error
return nil return nil
} }
func (params *ListTribeSnapshotsParams) PrependSortString(sort []string) error { func (params *ListTribeSnapshotsParams) PrependSortString(
if err := validateSliceLen( sort []string,
sort, allowed []TribeSnapshotSort,
tribeSnapshotSortMinLength, maxLength int,
max(tribeSnapshotSortMaxLength-len(params.sort), 0), ) error {
); err != nil { if len(sort) == 0 {
return nil
}
if err := validateSliceLen(sort, 0, max(min(tribeSnapshotSortMaxLength-len(params.sort), maxLength), 0)); err != nil {
return ValidationError{ return ValidationError{
Model: listTribeSnapshotsParamsModelName, Model: listTribeSnapshotsParamsModelName,
Field: "sort", Field: "sort",
@ -485,11 +489,7 @@ func (params *ListTribeSnapshotsParams) PrependSortString(sort []string) error {
toPrepend := make([]TribeSnapshotSort, 0, len(sort)) toPrepend := make([]TribeSnapshotSort, 0, len(sort))
for i, s := range sort { for i, s := range sort {
converted, err := newSortFromString( converted, err := newSortFromString(s, allowed...)
s,
TribeSnapshotSortDateASC,
TribeSnapshotSortDateDESC,
)
if err != nil { if err != nil {
return SliceElementValidationError{ return SliceElementValidationError{
Model: listTribeSnapshotsParamsModelName, Model: listTribeSnapshotsParamsModelName,

View File

@ -329,19 +329,10 @@ func TestListTribeSnapshotsParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListTribeSnapshotsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 3", name: "ERR: len(sort) > 3",
@ -357,7 +348,7 @@ func TestListTribeSnapshotsParams_SetSort(t *testing.T) {
Model: "ListTribeSnapshotsParams", Model: "ListTribeSnapshotsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 3,
Current: 4, Current: 4,
}, },
@ -403,9 +394,20 @@ func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) {
t.Helper() t.Helper()
return domain.ListTribeSnapshotsParams{} return domain.ListTribeSnapshotsParams{}
} }
defaultAllowed := []domain.TribeSnapshotSort{
domain.TribeSnapshotSortDateASC,
domain.TribeSnapshotSortDateDESC,
domain.TribeSnapshotSortIDASC,
domain.TribeSnapshotSortIDDESC,
domain.TribeSnapshotSortServerKeyASC,
domain.TribeSnapshotSortServerKeyDESC,
}
defaultMaxLength := 3
type args struct { type args struct {
sort []string sort []string
allowed []domain.TribeSnapshotSort
maxLength int
} }
tests := []struct { tests := []struct {
@ -416,44 +418,71 @@ func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "OK: [date:ASC]", name: "OK: [id:ASC, date:ASC, serverKey:ASC]",
args: args{
sort: []string{
"id:ASC",
"date:ASC",
"serverKey:ASC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.TribeSnapshotSort{
domain.TribeSnapshotSortIDASC,
domain.TribeSnapshotSortDateASC,
domain.TribeSnapshotSortServerKeyASC,
},
},
{
name: "OK: [id:DESC, date:DESC, serverKey:DESC]",
args: args{
sort: []string{
"id:DESC",
"date:DESC",
"serverKey:DESC",
},
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.TribeSnapshotSort{
domain.TribeSnapshotSortIDDESC,
domain.TribeSnapshotSortDateDESC,
domain.TribeSnapshotSortServerKeyDESC,
},
},
{
name: "OK: custom params",
newParams: func(t *testing.T) domain.ListTribeSnapshotsParams {
t.Helper()
params := domain.NewListTribeSnapshotsParams()
require.NoError(t, params.SetSort([]domain.TribeSnapshotSort{
domain.TribeSnapshotSortIDASC,
domain.TribeSnapshotSortServerKeyASC,
}))
return params
},
args: args{ args: args{
sort: []string{ sort: []string{
"date:ASC", "date:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.TribeSnapshotSort{ expectedSort: []domain.TribeSnapshotSort{
domain.TribeSnapshotSortDateASC, domain.TribeSnapshotSortDateASC,
domain.TribeSnapshotSortIDASC,
domain.TribeSnapshotSortServerKeyASC,
}, },
}, },
{ {
name: "OK: [date:DESC]", name: "OK: empty slice",
args: args{
sort: []string{
"date:DESC",
},
},
expectedSort: []domain.TribeSnapshotSort{
domain.TribeSnapshotSortDateDESC,
},
},
{
name: "ERR: len(sort) < 1",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListTribeSnapshotsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: custom params + len(sort) > 1", name: "ERR: custom params + len(sort) > sortMaxLength - len(sort)",
newParams: func(t *testing.T) domain.ListTribeSnapshotsParams { newParams: func(t *testing.T) domain.ListTribeSnapshotsParams {
t.Helper() t.Helper()
params := domain.NewListTribeSnapshotsParams() params := domain.NewListTribeSnapshotsParams()
@ -468,12 +497,35 @@ func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) {
"date:ASC", "date:ASC",
"date:DESC", "date:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribeSnapshotsParams", Model: "ListTribeSnapshotsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 1,
Current: 2,
},
},
},
{
name: "ERR: len(sort) > maxLength",
newParams: defaultNewParams,
args: args{
sort: []string{
"serverKey:ASC",
"date:ASC",
},
allowed: defaultAllowed,
maxLength: 1,
},
expectedErr: domain.ValidationError{
Model: "ListTribeSnapshotsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 0,
Max: 1, Max: 1,
Current: 2, Current: 2,
}, },
@ -486,6 +538,8 @@ func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) {
sort: []string{ sort: []string{
"date:", "date:",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.SliceElementValidationError{ expectedErr: domain.SliceElementValidationError{
Model: "ListTribeSnapshotsParams", Model: "ListTribeSnapshotsParams",
@ -503,6 +557,8 @@ func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) {
"date:ASC", "date:ASC",
"date:DESC", "date:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribeSnapshotsParams", Model: "ListTribeSnapshotsParams",
@ -524,7 +580,7 @@ func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) {
} }
params := newParams(t) params := newParams(t)
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) require.ErrorIs(t, params.PrependSortString(tt.args.sort, tt.args.allowed, tt.args.maxLength), tt.expectedErr)
if tt.expectedErr != nil { if tt.expectedErr != nil {
return return
} }

View File

@ -675,37 +675,29 @@ func TestListTribesParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListTribesParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 3,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 3", name: "ERR: len(sort) > 4",
args: args{ args: args{
sort: []domain.TribeSort{ sort: []domain.TribeSort{
domain.TribeSortDominanceASC, domain.TribeSortDominanceASC,
domain.TribeSortPointsASC, domain.TribeSortPointsASC,
domain.TribeSortIDASC, domain.TribeSortIDASC,
domain.TribeSortServerKeyASC, domain.TribeSortServerKeyASC,
domain.TribeSortServerKeyASC,
}, },
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribesParams", Model: "ListTribesParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 4,
Current: 4, Current: 5,
}, },
}, },
}, },
@ -749,9 +741,30 @@ func TestListTribesParams_PrependSortString(t *testing.T) {
t.Helper() t.Helper()
return domain.ListTribesParams{} return domain.ListTribesParams{}
} }
defaultAllowed := []domain.TribeSort{
domain.TribeSortIDASC,
domain.TribeSortIDDESC,
domain.TribeSortServerKeyASC,
domain.TribeSortServerKeyDESC,
domain.TribeSortODScoreAttASC,
domain.TribeSortODScoreAttDESC,
domain.TribeSortODScoreDefASC,
domain.TribeSortODScoreDefDESC,
domain.TribeSortODScoreTotalASC,
domain.TribeSortODScoreTotalDESC,
domain.TribeSortPointsASC,
domain.TribeSortPointsDESC,
domain.TribeSortDominanceASC,
domain.TribeSortDominanceDESC,
domain.TribeSortDeletedAtASC,
domain.TribeSortDeletedAtDESC,
}
defaultMaxLength := 4
type args struct { type args struct {
sort []string sort []string
allowed []domain.TribeSort
maxLength int
} }
tests := []struct { tests := []struct {
@ -762,106 +775,147 @@ func TestListTribesParams_PrependSortString(t *testing.T) {
expectedErr error expectedErr error
}{ }{
{ {
name: "OK: [odScoreAtt:ASC, odScoreDef:ASC, odScoreTotal:ASC]", name: "OK: [id:ASC, odScoreAtt:ASC, odScoreDef:ASC, odScoreTotal:ASC]",
args: args{ args: args{
sort: []string{ sort: []string{
"id:ASC",
"odScoreAtt:ASC", "odScoreAtt:ASC",
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:ASC", "odScoreTotal:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.TribeSort{ expectedSort: []domain.TribeSort{
domain.TribeSortIDASC,
domain.TribeSortODScoreAttASC, domain.TribeSortODScoreAttASC,
domain.TribeSortODScoreDefASC, domain.TribeSortODScoreDefASC,
domain.TribeSortODScoreTotalASC, domain.TribeSortODScoreTotalASC,
}, },
}, },
{ {
name: "OK: [odScoreAtt:DESC, odScoreDef:DESC, odScoreTotal:DESC]", name: "OK: [id:DESC, odScoreAtt:DESC, odScoreDef:DESC, odScoreTotal:DESC]",
args: args{ args: args{
sort: []string{ sort: []string{
"id:DESC",
"odScoreAtt:DESC", "odScoreAtt:DESC",
"odScoreDef:DESC", "odScoreDef:DESC",
"odScoreTotal:DESC", "odScoreTotal:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.TribeSort{ expectedSort: []domain.TribeSort{
domain.TribeSortIDDESC,
domain.TribeSortODScoreAttDESC, domain.TribeSortODScoreAttDESC,
domain.TribeSortODScoreDefDESC, domain.TribeSortODScoreDefDESC,
domain.TribeSortODScoreTotalDESC, domain.TribeSortODScoreTotalDESC,
}, },
}, },
{ {
name: "OK: [points:ASC, dominance:ASC, deletedAt:ASC]", name: "OK: [serverKey:ASC, points:ASC, dominance:ASC, deletedAt:ASC]",
args: args{ args: args{
sort: []string{ sort: []string{
"serverKey:ASC",
"points:ASC", "points:ASC",
"dominance:ASC", "dominance:ASC",
"deletedAt:ASC", "deletedAt:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.TribeSort{ expectedSort: []domain.TribeSort{
domain.TribeSortServerKeyASC,
domain.TribeSortPointsASC, domain.TribeSortPointsASC,
domain.TribeSortDominanceASC, domain.TribeSortDominanceASC,
domain.TribeSortDeletedAtASC, domain.TribeSortDeletedAtASC,
}, },
}, },
{ {
name: "OK: [points:DESC, dominance:DESC, deletedAt:DESC]", name: "OK: [serverKey:DESC, points:DESC, dominance:DESC, deletedAt:DESC]",
args: args{ args: args{
sort: []string{ sort: []string{
"serverKey:DESC",
"points:DESC", "points:DESC",
"dominance:DESC", "dominance:DESC",
"deletedAt:DESC", "deletedAt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedSort: []domain.TribeSort{ expectedSort: []domain.TribeSort{
domain.TribeSortServerKeyDESC,
domain.TribeSortPointsDESC, domain.TribeSortPointsDESC,
domain.TribeSortDominanceDESC, domain.TribeSortDominanceDESC,
domain.TribeSortDeletedAtDESC, domain.TribeSortDeletedAtDESC,
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: custom params",
args: args{ newParams: func(t *testing.T) domain.ListTribesParams {
sort: nil, t.Helper()
params := domain.NewListTribesParams()
require.NoError(t, params.SetSort([]domain.TribeSort{
domain.TribeSortIDASC,
domain.TribeSortServerKeyASC,
}))
return params
}, },
expectedErr: domain.ValidationError{ args: args{
Model: "ListTribesParams", sort: []string{
Field: "sort", "points:DESC",
Err: domain.LenOutOfRangeError{ "deletedAt:DESC",
Min: 1,
Max: 3,
Current: 0,
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
expectedSort: []domain.TribeSort{
domain.TribeSortPointsDESC,
domain.TribeSortDeletedAtDESC,
domain.TribeSortIDASC,
domain.TribeSortServerKeyASC,
}, },
}, },
{ {
name: "ERR: len(sort) > 3", name: "OK: empty slice",
args: args{
sort: nil,
allowed: defaultAllowed,
maxLength: defaultMaxLength,
},
},
{
name: "ERR: len(sort) > 4",
args: args{ args: args{
sort: []string{ sort: []string{
"odScoreAtt:ASC", "odScoreAtt:ASC",
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:ASC", "odScoreTotal:ASC",
"points:ASC", "points:ASC",
"points:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribesParams", Model: "ListTribesParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 3, Max: 4,
Current: 4, Current: 5,
}, },
}, },
}, },
{ {
name: "ERR: custom params + len(sort) > 2", name: "ERR: custom params + len(sort) > sortMaxLength - len(sort)",
newParams: func(t *testing.T) domain.ListTribesParams { newParams: func(t *testing.T) domain.ListTribesParams {
t.Helper() t.Helper()
params := domain.NewListTribesParams() params := domain.NewListTribesParams()
require.NoError(t, params.SetSort([]domain.TribeSort{domain.TribeSortIDASC})) require.NoError(t, params.SetSort([]domain.TribeSort{
domain.TribeSortIDASC,
domain.TribeSortServerKeyASC,
}))
return params return params
}, },
args: args{ args: args{
@ -870,17 +924,40 @@ func TestListTribesParams_PrependSortString(t *testing.T) {
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:ASC", "odScoreTotal:ASC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribesParams", Model: "ListTribesParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: 3, Current: 3,
}, },
}, },
}, },
{
name: "ERR: len(sort) > maxLength",
newParams: defaultNewParams,
args: args{
sort: []string{
"odScoreAtt:ASC",
"odScoreDef:ASC",
},
allowed: defaultAllowed,
maxLength: 1,
},
expectedErr: domain.ValidationError{
Model: "ListTribesParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 0,
Max: 1,
Current: 2,
},
},
},
{ {
name: "ERR: unsupported sort string", name: "ERR: unsupported sort string",
newParams: defaultNewParams, newParams: defaultNewParams,
@ -890,6 +967,8 @@ func TestListTribesParams_PrependSortString(t *testing.T) {
"odScoreDef:ASC", "odScoreDef:ASC",
"odScoreTotal:", "odScoreTotal:",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.SliceElementValidationError{ expectedErr: domain.SliceElementValidationError{
Model: "ListTribesParams", Model: "ListTribesParams",
@ -907,6 +986,8 @@ func TestListTribesParams_PrependSortString(t *testing.T) {
"odScoreAtt:ASC", "odScoreAtt:ASC",
"odScoreAtt:DESC", "odScoreAtt:DESC",
}, },
allowed: defaultAllowed,
maxLength: defaultMaxLength,
}, },
expectedErr: domain.ValidationError{ expectedErr: domain.ValidationError{
Model: "ListTribesParams", Model: "ListTribesParams",
@ -928,7 +1009,7 @@ func TestListTribesParams_PrependSortString(t *testing.T) {
} }
params := newParams(t) params := newParams(t)
require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) require.ErrorIs(t, params.PrependSortString(tt.args.sort, tt.args.allowed, tt.args.maxLength), tt.expectedErr)
if tt.expectedErr != nil { if tt.expectedErr != nil {
return return
} }

View File

@ -218,7 +218,7 @@ func (params *ListVersionsParams) SetCodes(codes []string) error {
} }
const ( const (
versionSortMinLength = 1 versionSortMinLength = 0
versionSortMaxLength = 1 versionSortMaxLength = 1
) )

View File

@ -177,19 +177,10 @@ func TestListVersionsParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListVersionsParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 1,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 1", name: "ERR: len(sort) > 1",
@ -203,7 +194,7 @@ func TestListVersionsParams_SetSort(t *testing.T) {
Model: "ListVersionsParams", Model: "ListVersionsParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 1, Max: 1,
Current: 2, Current: 2,
}, },

View File

@ -664,7 +664,7 @@ func (params *ListVillagesParams) Sort() []VillageSort {
} }
const ( const (
villageSortMinLength = 1 villageSortMinLength = 0
villageSortMaxLength = 2 villageSortMaxLength = 2
) )

View File

@ -650,19 +650,10 @@ func TestListVillagesParams_SetSort(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) < 1", name: "OK: empty slice",
args: args{ args: args{
sort: nil, sort: nil,
}, },
expectedErr: domain.ValidationError{
Model: "ListVillagesParams",
Field: "sort",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 2,
Current: 0,
},
},
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 2",
@ -677,7 +668,7 @@ func TestListVillagesParams_SetSort(t *testing.T) {
Model: "ListVillagesParams", Model: "ListVillagesParams",
Field: "sort", Field: "sort",
Err: domain.LenOutOfRangeError{ Err: domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: 3, Current: 3,
}, },

View File

@ -8,6 +8,13 @@ import (
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel" "gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
) )
const apiEnnoblementSortMaxLength = 1
var apiEnnoblementSortAllowedValues = []domain.EnnoblementSort{
domain.EnnoblementSortCreatedAtASC,
domain.EnnoblementSortCreatedAtDESC,
}
//nolint:gocyclo //nolint:gocyclo
func (h *apiHTTPHandler) ListEnnoblements( func (h *apiHTTPHandler) ListEnnoblements(
w http.ResponseWriter, w http.ResponseWriter,
@ -23,16 +30,18 @@ func (h *apiHTTPHandler) ListEnnoblements(
return return
} }
sort := []string{domain.EnnoblementSortCreatedAtASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.EnnoblementSortCreatedAtASC.String()}); err != nil { apiEnnoblementSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) apiEnnoblementSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {
@ -104,16 +113,18 @@ func (h *apiHTTPHandler) ListPlayerEnnoblements(
return return
} }
sort := []string{domain.EnnoblementSortCreatedAtASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.EnnoblementSortCreatedAtASC.String()}); err != nil { apiEnnoblementSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) apiEnnoblementSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {
@ -185,16 +196,18 @@ func (h *apiHTTPHandler) ListTribeEnnoblements(
return return
} }
sort := []string{domain.EnnoblementSortCreatedAtASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.EnnoblementSortCreatedAtASC.String()}); err != nil { apiEnnoblementSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) apiEnnoblementSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {
@ -266,16 +279,18 @@ func (h *apiHTTPHandler) ListVillageEnnoblements(
return return
} }
sort := []string{domain.EnnoblementSortCreatedAtASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.EnnoblementSortCreatedAtASC.String()}); err != nil { apiEnnoblementSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err) apiEnnoblementSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListEnnoblementsErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {

View File

@ -414,13 +414,12 @@ func TestListEnnoblements(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "createdAt:DESC") q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC") q.Add("sort", "createdAt:ASC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -431,8 +430,8 @@ func TestListEnnoblements(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -483,44 +482,6 @@ func TestListEnnoblements(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: invalid since", name: "ERR: invalid since",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
@ -1061,13 +1022,12 @@ func TestListPlayerEnnoblements(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "createdAt:DESC") q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC") q.Add("sort", "createdAt:ASC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -1078,8 +1038,8 @@ func TestListPlayerEnnoblements(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -1130,44 +1090,6 @@ func TestListPlayerEnnoblements(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: invalid since", name: "ERR: invalid since",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
@ -1766,13 +1688,12 @@ func TestListTribeEnnoblements(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "createdAt:DESC") q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC") q.Add("sort", "createdAt:ASC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -1783,8 +1704,8 @@ func TestListTribeEnnoblements(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -1835,44 +1756,6 @@ func TestListTribeEnnoblements(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: invalid since", name: "ERR: invalid since",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
@ -2458,13 +2341,12 @@ func TestListVillageEnnoblements(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "createdAt:DESC") q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC") q.Add("sort", "createdAt:ASC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -2475,8 +2357,8 @@ func TestListVillageEnnoblements(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -2527,44 +2409,6 @@ func TestListVillageEnnoblements(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: invalid since", name: "ERR: invalid since",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {

View File

@ -11,6 +11,23 @@ import (
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
) )
const apiPlayerSortMaxLength = 2
var apiPlayerSortAllowedValues = []domain.PlayerSort{
domain.PlayerSortODScoreAttASC,
domain.PlayerSortODScoreAttDESC,
domain.PlayerSortODScoreDefASC,
domain.PlayerSortODScoreDefDESC,
domain.PlayerSortODScoreSupASC,
domain.PlayerSortODScoreSupDESC,
domain.PlayerSortODScoreTotalASC,
domain.PlayerSortODScoreTotalDESC,
domain.PlayerSortPointsASC,
domain.PlayerSortPointsDESC,
domain.PlayerSortDeletedAtASC,
domain.PlayerSortDeletedAtDESC,
}
//nolint:gocyclo //nolint:gocyclo
func (h *apiHTTPHandler) ListPlayers( func (h *apiHTTPHandler) ListPlayers(
w http.ResponseWriter, w http.ResponseWriter,
@ -27,7 +44,11 @@ func (h *apiHTTPHandler) ListPlayers(
} }
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { if err := domainParams.PrependSortString(
*params.Sort,
apiPlayerSortAllowedValues,
apiPlayerSortMaxLength,
); err != nil {
h.errorRenderer.withErrorPathFormatter(formatListPlayersErrorPath).render(w, r, err) h.errorRenderer.withErrorPathFormatter(formatListPlayersErrorPath).render(w, r, err)
return return
} }
@ -95,7 +116,11 @@ func (h *apiHTTPHandler) ListTribeMembers(
} }
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { if err := domainParams.PrependSortString(
*params.Sort,
apiPlayerSortAllowedValues,
apiPlayerSortMaxLength,
); err != nil {
h.errorRenderer.withErrorPathFormatter(formatListPlayersErrorPath).render(w, r, err) h.errorRenderer.withErrorPathFormatter(formatListPlayersErrorPath).render(w, r, err)
return return
} }

View File

@ -8,6 +8,13 @@ import (
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel" "gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
) )
const apiPlayerSnapshotSortMaxLength = 1
var apiPlayerSnapshotSortAllowedValues = []domain.PlayerSnapshotSort{
domain.PlayerSnapshotSortDateASC,
domain.PlayerSnapshotSortDateDESC,
}
//nolint:gocyclo //nolint:gocyclo
func (h *apiHTTPHandler) ListPlayerPlayerSnapshots( func (h *apiHTTPHandler) ListPlayerPlayerSnapshots(
w http.ResponseWriter, w http.ResponseWriter,
@ -29,16 +36,18 @@ func (h *apiHTTPHandler) ListPlayerPlayerSnapshots(
return return
} }
sort := []string{domain.PlayerSnapshotSortDateASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListPlayerSnapshotsErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.PlayerSnapshotSortDateASC.String()}); err != nil { apiPlayerSnapshotSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListPlayerSnapshotsErrorPath).render(w, r, err) apiPlayerSnapshotSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListPlayerSnapshotsErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {

View File

@ -348,13 +348,12 @@ func TestListPlayerPlayerSnapshots(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "date:DESC") q.Add("sort", "date:DESC")
q.Add("sort", "date:ASC") q.Add("sort", "date:ASC")
q.Add("sort", "date:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -365,8 +364,8 @@ func TestListPlayerPlayerSnapshots(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -417,44 +416,6 @@ func TestListPlayerPlayerSnapshots(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "date:DESC")
q.Add("sort", "date:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: version not found", name: "ERR: version not found",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {

View File

@ -474,7 +474,7 @@ func TestListPlayers(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
@ -1133,7 +1133,7 @@ func TestListTribeMembers(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }

View File

@ -11,6 +11,23 @@ import (
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
) )
const apiTribeSortMaxLength = 2
var apiTribeSortAllowedValues = []domain.TribeSort{
domain.TribeSortODScoreAttASC,
domain.TribeSortODScoreAttDESC,
domain.TribeSortODScoreDefASC,
domain.TribeSortODScoreDefDESC,
domain.TribeSortODScoreTotalASC,
domain.TribeSortODScoreTotalDESC,
domain.TribeSortPointsASC,
domain.TribeSortPointsDESC,
domain.TribeSortDominanceASC,
domain.TribeSortDominanceDESC,
domain.TribeSortDeletedAtASC,
domain.TribeSortDeletedAtDESC,
}
//nolint:gocyclo //nolint:gocyclo
func (h *apiHTTPHandler) ListTribes( func (h *apiHTTPHandler) ListTribes(
w http.ResponseWriter, w http.ResponseWriter,
@ -27,7 +44,7 @@ func (h *apiHTTPHandler) ListTribes(
} }
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { if err := domainParams.PrependSortString(*params.Sort, apiTribeSortAllowedValues, apiTribeSortMaxLength); err != nil {
h.errorRenderer.withErrorPathFormatter(formatListTribesErrorPath).render(w, r, err) h.errorRenderer.withErrorPathFormatter(formatListTribesErrorPath).render(w, r, err)
return return
} }

View File

@ -8,6 +8,13 @@ import (
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel" "gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
) )
const apiTribeChangeSortMaxLength = 1
var apiTribeChangeSortAllowedValues = []domain.TribeChangeSort{
domain.TribeChangeSortCreatedAtASC,
domain.TribeChangeSortCreatedAtDESC,
}
//nolint:gocyclo //nolint:gocyclo
func (h *apiHTTPHandler) ListPlayerTribeChanges( func (h *apiHTTPHandler) ListPlayerTribeChanges(
w http.ResponseWriter, w http.ResponseWriter,
@ -29,16 +36,18 @@ func (h *apiHTTPHandler) ListPlayerTribeChanges(
return return
} }
sort := []string{domain.TribeChangeSortCreatedAtASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.TribeChangeSortCreatedAtASC.String()}); err != nil { apiTribeChangeSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err) apiTribeChangeSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {
@ -110,16 +119,18 @@ func (h *apiHTTPHandler) ListTribeMemberChanges(
return return
} }
sort := []string{domain.TribeChangeSortCreatedAtASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.TribeChangeSortCreatedAtASC.String()}); err != nil { apiTribeChangeSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err) apiTribeChangeSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListTribeChangesErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {

View File

@ -429,13 +429,12 @@ func TestListPlayerTribeChanges(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "createdAt:DESC") q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC") q.Add("sort", "createdAt:ASC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -446,8 +445,8 @@ func TestListPlayerTribeChanges(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -498,44 +497,6 @@ func TestListPlayerTribeChanges(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: invalid since", name: "ERR: invalid since",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
@ -1160,13 +1121,12 @@ func TestListTribeMemberChanges(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "createdAt:DESC") q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC") q.Add("sort", "createdAt:ASC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -1177,8 +1137,8 @@ func TestListTribeMemberChanges(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -1229,44 +1189,6 @@ func TestListTribeMemberChanges(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "createdAt:DESC")
q.Add("sort", "createdAt:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: invalid since", name: "ERR: invalid since",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {

View File

@ -8,6 +8,13 @@ import (
"gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel" "gitea.dwysokinski.me/twhelp/corev3/internal/port/internal/apimodel"
) )
const apiTribeSnapshotSortMaxLength = 1
var apiTribeSnapshotSortAllowedValues = []domain.TribeSnapshotSort{
domain.TribeSnapshotSortDateASC,
domain.TribeSnapshotSortDateDESC,
}
//nolint:gocyclo //nolint:gocyclo
func (h *apiHTTPHandler) ListTribeTribeSnapshots( func (h *apiHTTPHandler) ListTribeTribeSnapshots(
w http.ResponseWriter, w http.ResponseWriter,
@ -29,16 +36,18 @@ func (h *apiHTTPHandler) ListTribeTribeSnapshots(
return return
} }
sort := []string{domain.TribeSnapshotSortDateASC.String()}
if params.Sort != nil { if params.Sort != nil {
if err := domainParams.PrependSortString(*params.Sort); err != nil { sort = *params.Sort
h.errorRenderer.withErrorPathFormatter(formatListTribeSnapshotsErrorPath).render(w, r, err) }
return
} if err := domainParams.PrependSortString(
} else { sort,
if err := domainParams.PrependSortString([]string{domain.TribeSnapshotSortDateASC.String()}); err != nil { apiTribeSnapshotSortAllowedValues,
h.errorRenderer.withErrorPathFormatter(formatListTribeSnapshotsErrorPath).render(w, r, err) apiTribeSnapshotSortMaxLength,
return ); err != nil {
} h.errorRenderer.withErrorPathFormatter(formatListTribeSnapshotsErrorPath).render(w, r, err)
return
} }
if err := domainParams.SetServerKeys([]string{serverKey}); err != nil { if err := domainParams.SetServerKeys([]string{serverKey}); err != nil {

View File

@ -348,13 +348,12 @@ func TestListTribeTribeSnapshots(t *testing.T) {
}, },
}, },
{ {
name: "ERR: len(sort) > 2", name: "ERR: len(sort) > 1",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {
t.Helper() t.Helper()
q := req.URL.Query() q := req.URL.Query()
q.Add("sort", "date:DESC") q.Add("sort", "date:DESC")
q.Add("sort", "date:ASC") q.Add("sort", "date:ASC")
q.Add("sort", "date:ASC")
req.URL.RawQuery = q.Encode() req.URL.RawQuery = q.Encode()
}, },
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) { assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
@ -365,8 +364,8 @@ func TestListTribeTribeSnapshots(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 1,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }
assert.Equal(t, apimodel.ErrorResponse{ assert.Equal(t, apimodel.ErrorResponse{
@ -417,44 +416,6 @@ func TestListTribeTribeSnapshots(t *testing.T) {
}, body) }, body)
}, },
}, },
{
name: "ERR: sort conflict",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
q := req.URL.Query()
q.Add("sort", "date:DESC")
q.Add("sort", "date:ASC")
req.URL.RawQuery = q.Encode()
},
assertResp: func(t *testing.T, req *http.Request, resp *http.Response) {
t.Helper()
assert.Equal(t, http.StatusBadRequest, resp.StatusCode)
// body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
q := req.URL.Query()
domainErr := domain.SortConflictError{
Sort: [2]string{q["sort"][0], q["sort"][1]},
}
paramSort := make([]any, len(domainErr.Sort))
for i, s := range domainErr.Sort {
paramSort[i] = s
}
assert.Equal(t, apimodel.ErrorResponse{
Errors: []apimodel.Error{
{
Code: apimodel.ErrorCode(domainErr.Code()),
Message: domainErr.Error(),
Params: map[string]any{
"sort": paramSort,
},
Path: []string{"$query", "sort"},
},
},
}, body)
},
},
{ {
name: "ERR: version not found", name: "ERR: version not found",
reqModifier: func(t *testing.T, req *http.Request) { reqModifier: func(t *testing.T, req *http.Request) {

View File

@ -474,7 +474,7 @@ func TestListTribes(t *testing.T) {
// body // body
body := decodeJSON[apimodel.ErrorResponse](t, resp.Body) body := decodeJSON[apimodel.ErrorResponse](t, resp.Body)
domainErr := domain.LenOutOfRangeError{ domainErr := domain.LenOutOfRangeError{
Min: 1, Min: 0,
Max: 2, Max: 2,
Current: len(req.URL.Query()["sort"]), Current: len(req.URL.Query()["sort"]),
} }