diff --git a/internal/domain/player_snapshot.go b/internal/domain/player_snapshot.go index b1cb633..a47932b 100644 --- a/internal/domain/player_snapshot.go +++ b/internal/domain/player_snapshot.go @@ -415,6 +415,41 @@ func (params *ListPlayerSnapshotsParams) SetSort(sort []PlayerSnapshotSort) erro return nil } +func (params *ListPlayerSnapshotsParams) PrependSortString(sort []string) error { + if err := validateSliceLen( + sort, + playerSnapshotSortMinLength, + max(playerSnapshotSortMaxLength-len(params.sort), 0), + ); err != nil { + return ValidationError{ + Model: listPlayerSnapshotsParamsModelName, + Field: "sort", + Err: err, + } + } + + toPrepend := make([]PlayerSnapshotSort, 0, len(sort)) + + for i, s := range sort { + converted, err := newSortFromString( + s, + PlayerSnapshotSortDateASC, + PlayerSnapshotSortDateDESC, + ) + if err != nil { + return SliceElementValidationError{ + Model: listPlayerSnapshotsParamsModelName, + Field: "sort", + Index: i, + Err: err, + } + } + toPrepend = append(toPrepend, converted) + } + + return params.SetSort(append(toPrepend, params.sort...)) +} + func (params *ListPlayerSnapshotsParams) Cursor() PlayerSnapshotCursor { return params.cursor } diff --git a/internal/domain/player_snapshot_test.go b/internal/domain/player_snapshot_test.go index 966e78f..dd93552 100644 --- a/internal/domain/player_snapshot_test.go +++ b/internal/domain/player_snapshot_test.go @@ -394,6 +394,143 @@ func TestListPlayerSnapshotsParams_SetSort(t *testing.T) { } } +func TestListPlayerSnapshotsParams_PrependSortString(t *testing.T) { + t.Parallel() + + defaultNewParams := func(t *testing.T) domain.ListPlayerSnapshotsParams { + t.Helper() + return domain.ListPlayerSnapshotsParams{} + } + + type args struct { + sort []string + } + + tests := []struct { + name string + newParams func(t *testing.T) domain.ListPlayerSnapshotsParams + args args + expectedSort []domain.PlayerSnapshotSort + expectedErr error + }{ + { + name: "OK: [date:ASC]", + args: args{ + sort: []string{ + "date:ASC", + }, + }, + expectedSort: []domain.PlayerSnapshotSort{ + domain.PlayerSnapshotSortDateASC, + }, + }, + { + name: "OK: [date:DESC]", + args: args{ + sort: []string{ + "date:DESC", + }, + }, + expectedSort: []domain.PlayerSnapshotSort{ + domain.PlayerSnapshotSortDateDESC, + }, + }, + { + name: "ERR: len(sort) < 1", + args: args{ + 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", + newParams: func(t *testing.T) domain.ListPlayerSnapshotsParams { + t.Helper() + params := domain.NewListPlayerSnapshotsParams() + require.NoError(t, params.SetSort([]domain.PlayerSnapshotSort{ + domain.PlayerSnapshotSortServerKeyASC, + domain.PlayerSnapshotSortIDASC, + })) + return params + }, + args: args{ + sort: []string{ + "date:ASC", + "date:DESC", + }, + }, + expectedErr: domain.ValidationError{ + Model: "ListPlayerSnapshotsParams", + Field: "sort", + Err: domain.LenOutOfRangeError{ + Min: 1, + Max: 1, + Current: 2, + }, + }, + }, + { + name: "ERR: unsupported sort string", + newParams: defaultNewParams, + args: args{ + sort: []string{ + "date:", + }, + }, + expectedErr: domain.SliceElementValidationError{ + Model: "ListPlayerSnapshotsParams", + Field: "sort", + Index: 0, + Err: domain.UnsupportedSortStringError{ + Sort: "date:", + }, + }, + }, + { + name: "ERR: conflict", + args: args{ + sort: []string{ + "date:ASC", + "date:DESC", + }, + }, + expectedErr: domain.ValidationError{ + Model: "ListPlayerSnapshotsParams", + Field: "sort", + Err: domain.SortConflictError{ + Sort: [2]string{domain.PlayerSnapshotSortDateASC.String(), domain.PlayerSnapshotSortDateDESC.String()}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + newParams := defaultNewParams + if tt.newParams != nil { + newParams = tt.newParams + } + params := newParams(t) + + require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) + if tt.expectedErr != nil { + return + } + assert.Equal(t, tt.expectedSort, params.Sort()) + }) + } +} + func TestListPlayerSnapshotsParams_SetEncodedCursor(t *testing.T) { t.Parallel() diff --git a/internal/domain/tribe_snapshot.go b/internal/domain/tribe_snapshot.go index df21530..908153b 100644 --- a/internal/domain/tribe_snapshot.go +++ b/internal/domain/tribe_snapshot.go @@ -467,6 +467,41 @@ func (params *ListTribeSnapshotsParams) SetSort(sort []TribeSnapshotSort) error return nil } +func (params *ListTribeSnapshotsParams) PrependSortString(sort []string) error { + if err := validateSliceLen( + sort, + tribeSnapshotSortMinLength, + max(tribeSnapshotSortMaxLength-len(params.sort), 0), + ); err != nil { + return ValidationError{ + Model: listTribeSnapshotsParamsModelName, + Field: "sort", + Err: err, + } + } + + toPrepend := make([]TribeSnapshotSort, 0, len(sort)) + + for i, s := range sort { + converted, err := newSortFromString( + s, + TribeSnapshotSortDateASC, + TribeSnapshotSortDateDESC, + ) + if err != nil { + return SliceElementValidationError{ + Model: listTribeSnapshotsParamsModelName, + Field: "sort", + Index: i, + Err: err, + } + } + toPrepend = append(toPrepend, converted) + } + + return params.SetSort(append(toPrepend, params.sort...)) +} + func (params *ListTribeSnapshotsParams) Cursor() TribeSnapshotCursor { return params.cursor } diff --git a/internal/domain/tribe_snapshot_test.go b/internal/domain/tribe_snapshot_test.go index 6df0d0e..bfd95c0 100644 --- a/internal/domain/tribe_snapshot_test.go +++ b/internal/domain/tribe_snapshot_test.go @@ -396,6 +396,143 @@ func TestListTribeSnapshotsParams_SetSort(t *testing.T) { } } +func TestListTribeSnapshotsParams_PrependSortString(t *testing.T) { + t.Parallel() + + defaultNewParams := func(t *testing.T) domain.ListTribeSnapshotsParams { + t.Helper() + return domain.ListTribeSnapshotsParams{} + } + + type args struct { + sort []string + } + + tests := []struct { + name string + newParams func(t *testing.T) domain.ListTribeSnapshotsParams + args args + expectedSort []domain.TribeSnapshotSort + expectedErr error + }{ + { + name: "OK: [date:ASC]", + args: args{ + sort: []string{ + "date:ASC", + }, + }, + expectedSort: []domain.TribeSnapshotSort{ + domain.TribeSnapshotSortDateASC, + }, + }, + { + name: "OK: [date:DESC]", + args: args{ + sort: []string{ + "date:DESC", + }, + }, + expectedSort: []domain.TribeSnapshotSort{ + domain.TribeSnapshotSortDateDESC, + }, + }, + { + name: "ERR: len(sort) < 1", + args: args{ + 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", + newParams: func(t *testing.T) domain.ListTribeSnapshotsParams { + t.Helper() + params := domain.NewListTribeSnapshotsParams() + require.NoError(t, params.SetSort([]domain.TribeSnapshotSort{ + domain.TribeSnapshotSortServerKeyASC, + domain.TribeSnapshotSortIDASC, + })) + return params + }, + args: args{ + sort: []string{ + "date:ASC", + "date:DESC", + }, + }, + expectedErr: domain.ValidationError{ + Model: "ListTribeSnapshotsParams", + Field: "sort", + Err: domain.LenOutOfRangeError{ + Min: 1, + Max: 1, + Current: 2, + }, + }, + }, + { + name: "ERR: unsupported sort string", + newParams: defaultNewParams, + args: args{ + sort: []string{ + "date:", + }, + }, + expectedErr: domain.SliceElementValidationError{ + Model: "ListTribeSnapshotsParams", + Field: "sort", + Index: 0, + Err: domain.UnsupportedSortStringError{ + Sort: "date:", + }, + }, + }, + { + name: "ERR: conflict", + args: args{ + sort: []string{ + "date:ASC", + "date:DESC", + }, + }, + expectedErr: domain.ValidationError{ + Model: "ListTribeSnapshotsParams", + Field: "sort", + Err: domain.SortConflictError{ + Sort: [2]string{domain.TribeSnapshotSortDateASC.String(), domain.TribeSnapshotSortDateDESC.String()}, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + newParams := defaultNewParams + if tt.newParams != nil { + newParams = tt.newParams + } + params := newParams(t) + + require.ErrorIs(t, params.PrependSortString(tt.args.sort), tt.expectedErr) + if tt.expectedErr != nil { + return + } + assert.Equal(t, tt.expectedSort, params.Sort()) + }) + } +} + func TestListTribeSnapshotsParams_SetEncodedCursor(t *testing.T) { t.Parallel()