feat: tribe - sort by most points (#55)
All checks were successful
ci/woodpecker/push/govulncheck Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/tag/deployment Pipeline was successful
ci/woodpecker/cron/govulncheck Pipeline was successful
All checks were successful
ci/woodpecker/push/govulncheck Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/tag/release Pipeline was successful
ci/woodpecker/tag/deployment Pipeline was successful
ci/woodpecker/cron/govulncheck Pipeline was successful
Reviewed-on: #55
This commit is contained in:
parent
4db3fee03f
commit
51a6270812
|
@ -1794,6 +1794,8 @@ components:
|
|||
- odScoreTotal:DESC
|
||||
- points:ASC
|
||||
- points:DESC
|
||||
- mostPoints:ASC
|
||||
- mostPoints:DESC
|
||||
- dominance:ASC
|
||||
- dominance:DESC
|
||||
- deletedAt:ASC
|
||||
|
|
|
@ -241,6 +241,9 @@ func (a listTribesParamsApplier) applyCursor(q *bun.SelectQuery) *bun.SelectQuer
|
|||
case domain.TribeSortPointsASC,
|
||||
domain.TribeSortPointsDESC:
|
||||
el.value = cursor.Points()
|
||||
case domain.TribeSortMostPointsASC,
|
||||
domain.TribeSortMostPointsDESC:
|
||||
el.value = cursor.MostPoints()
|
||||
case domain.TribeSortDominanceASC,
|
||||
domain.TribeSortDominanceDESC:
|
||||
el.value = cursor.Dominance()
|
||||
|
@ -286,6 +289,10 @@ func (a listTribesParamsApplier) sortToColumnAndDirection(
|
|||
return "tribe.points", sortDirectionASC, nil
|
||||
case domain.TribeSortPointsDESC:
|
||||
return "tribe.points", sortDirectionDESC, nil
|
||||
case domain.TribeSortMostPointsASC:
|
||||
return "tribe.most_points", sortDirectionASC, nil
|
||||
case domain.TribeSortMostPointsDESC:
|
||||
return "tribe.most_points", sortDirectionDESC, nil
|
||||
case domain.TribeSortDominanceASC:
|
||||
return "tribe.dominance", sortDirectionASC, nil
|
||||
case domain.TribeSortDominanceDESC:
|
||||
|
|
|
@ -339,6 +339,56 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[mostPoints ASC, serverKey ASC, id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribesParams {
|
||||
t.Helper()
|
||||
params := domain.NewListTribesParams()
|
||||
require.NoError(t, params.SetSort([]domain.TribeSort{
|
||||
domain.TribeSortMostPointsASC,
|
||||
domain.TribeSortServerKeyASC,
|
||||
domain.TribeSortIDASC,
|
||||
}))
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, _ domain.ListTribesParams, res domain.ListTribesResult) {
|
||||
t.Helper()
|
||||
tribes := res.Tribes()
|
||||
assert.NotEmpty(t, tribes)
|
||||
assert.True(t, slices.IsSortedFunc(tribes, func(a, b domain.Tribe) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.MostPoints(), b.MostPoints()),
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[mostPoints DESC, serverKey ASC, id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribesParams {
|
||||
t.Helper()
|
||||
params := domain.NewListTribesParams()
|
||||
require.NoError(t, params.SetSort([]domain.TribeSort{
|
||||
domain.TribeSortMostPointsDESC,
|
||||
domain.TribeSortServerKeyASC,
|
||||
domain.TribeSortIDASC,
|
||||
}))
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, _ domain.ListTribesParams, res domain.ListTribesResult) {
|
||||
t.Helper()
|
||||
tribes := res.Tribes()
|
||||
assert.NotEmpty(t, tribes)
|
||||
assert.True(t, slices.IsSortedFunc(tribes, func(a, b domain.Tribe) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.MostPoints(), b.MostPoints())*-1,
|
||||
cmp.Compare(a.ServerKey(), b.ServerKey()),
|
||||
cmp.Compare(a.ID(), b.ID()),
|
||||
)
|
||||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[deletedAt ASC, serverKey ASC, id ASC]",
|
||||
params: func(t *testing.T) domain.ListTribesParams {
|
||||
|
|
|
@ -20,6 +20,7 @@ type TribeCursorConfig struct {
|
|||
ODScoreDef int
|
||||
ODScoreTotal int
|
||||
Points int
|
||||
MostPoints int
|
||||
Dominance float64
|
||||
DeletedAt time.Time
|
||||
}
|
||||
|
@ -34,6 +35,7 @@ func NewTribeCursor(tb TestingTB, opts ...func(cfg *TribeCursorConfig)) domain.T
|
|||
ODScoreDef: gofakeit.IntRange(0, math.MaxInt),
|
||||
ODScoreTotal: gofakeit.IntRange(0, math.MaxInt),
|
||||
Points: gofakeit.IntRange(0, math.MaxInt),
|
||||
MostPoints: gofakeit.IntRange(0, math.MaxInt),
|
||||
Dominance: gofakeit.Float64Range(0.1, 99.9),
|
||||
DeletedAt: time.Time{},
|
||||
}
|
||||
|
@ -49,6 +51,7 @@ func NewTribeCursor(tb TestingTB, opts ...func(cfg *TribeCursorConfig)) domain.T
|
|||
cfg.ODScoreDef,
|
||||
cfg.ODScoreTotal,
|
||||
cfg.Points,
|
||||
cfg.MostPoints,
|
||||
cfg.Dominance,
|
||||
cfg.DeletedAt,
|
||||
)
|
||||
|
|
|
@ -207,6 +207,7 @@ func (t Tribe) ToCursor() (TribeCursor, error) {
|
|||
t.od.scoreDef,
|
||||
t.od.scoreTotal,
|
||||
t.points,
|
||||
t.mostPoints,
|
||||
t.dominance,
|
||||
t.deletedAt,
|
||||
)
|
||||
|
@ -472,6 +473,8 @@ const (
|
|||
TribeSortODScoreTotalDESC
|
||||
TribeSortPointsASC
|
||||
TribeSortPointsDESC
|
||||
TribeSortMostPointsASC
|
||||
TribeSortMostPointsDESC
|
||||
TribeSortDominanceASC
|
||||
TribeSortDominanceDESC
|
||||
TribeSortDeletedAtASC
|
||||
|
@ -510,6 +513,10 @@ func (s TribeSort) String() string {
|
|||
return "points:ASC"
|
||||
case TribeSortPointsDESC:
|
||||
return "points:DESC"
|
||||
case TribeSortMostPointsASC:
|
||||
return "mostPoints:ASC"
|
||||
case TribeSortMostPointsDESC:
|
||||
return "mostPoints:DESC"
|
||||
case TribeSortDominanceASC:
|
||||
return "dominance:ASC"
|
||||
case TribeSortDominanceDESC:
|
||||
|
@ -530,6 +537,7 @@ type TribeCursor struct {
|
|||
odScoreDef int
|
||||
odScoreTotal int
|
||||
points int
|
||||
mostPoints int
|
||||
dominance float64
|
||||
deletedAt time.Time
|
||||
}
|
||||
|
@ -543,6 +551,7 @@ func NewTribeCursor(
|
|||
odScoreDef int,
|
||||
odScoreTotal int,
|
||||
points int,
|
||||
mostPoints int,
|
||||
dominance float64,
|
||||
deletedAt time.Time,
|
||||
) (TribeCursor, error) {
|
||||
|
@ -594,6 +603,14 @@ func NewTribeCursor(
|
|||
}
|
||||
}
|
||||
|
||||
if err := validateIntInRange(mostPoints, 0, math.MaxInt); err != nil {
|
||||
return TribeCursor{}, ValidationError{
|
||||
Model: tribeCursorModelName,
|
||||
Field: "mostPoints",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return TribeCursor{
|
||||
id: id,
|
||||
serverKey: serverKey,
|
||||
|
@ -601,6 +618,7 @@ func NewTribeCursor(
|
|||
odScoreDef: odScoreDef,
|
||||
odScoreTotal: odScoreTotal,
|
||||
points: points,
|
||||
mostPoints: mostPoints,
|
||||
dominance: dominance,
|
||||
deletedAt: deletedAt,
|
||||
}, nil
|
||||
|
@ -643,6 +661,11 @@ func decodeTribeCursor(encoded string) (TribeCursor, error) {
|
|||
return TribeCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
mostPoints, err := m.int("mostPoints")
|
||||
if err != nil {
|
||||
return TribeCursor{}, ErrInvalidCursor
|
||||
}
|
||||
|
||||
dominance, err := m.float64("dominance")
|
||||
if err != nil {
|
||||
return TribeCursor{}, ErrInvalidCursor
|
||||
|
@ -660,6 +683,7 @@ func decodeTribeCursor(encoded string) (TribeCursor, error) {
|
|||
odScoreDef,
|
||||
odScoreTotal,
|
||||
points,
|
||||
mostPoints,
|
||||
dominance,
|
||||
deletedAt,
|
||||
)
|
||||
|
@ -694,6 +718,10 @@ func (tc TribeCursor) Points() int {
|
|||
return tc.points
|
||||
}
|
||||
|
||||
func (tc TribeCursor) MostPoints() int {
|
||||
return tc.mostPoints
|
||||
}
|
||||
|
||||
func (tc TribeCursor) Dominance() float64 {
|
||||
return tc.dominance
|
||||
}
|
||||
|
@ -718,6 +746,7 @@ func (tc TribeCursor) Encode() string {
|
|||
{"odScoreDef", tc.odScoreDef},
|
||||
{"odScoreTotal", tc.odScoreTotal},
|
||||
{"points", tc.points},
|
||||
{"mostPoints", tc.mostPoints},
|
||||
{"dominance", tc.dominance},
|
||||
{"deletedAt", tc.deletedAt},
|
||||
})
|
||||
|
|
|
@ -255,6 +255,13 @@ func TestTribeSort_IsInConflict(t *testing.T) {
|
|||
},
|
||||
expectedRes: true,
|
||||
},
|
||||
{
|
||||
name: "OK: mostPoints:ASC mostPoints:DESC",
|
||||
args: args{
|
||||
sorts: [2]domain.TribeSort{domain.TribeSortMostPointsASC, domain.TribeSortMostPointsDESC},
|
||||
},
|
||||
expectedRes: true,
|
||||
},
|
||||
{
|
||||
name: "OK: dominance:ASC dominance:DESC",
|
||||
args: args{
|
||||
|
@ -292,6 +299,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef int
|
||||
odScoreTotal int
|
||||
points int
|
||||
mostPoints int
|
||||
dominance float64
|
||||
deletedAt time.Time
|
||||
}
|
||||
|
@ -312,6 +320,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -326,6 +335,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -347,6 +357,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -368,6 +379,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: -1,
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -389,6 +401,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: -1,
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -410,6 +423,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: -1,
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -422,6 +436,28 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: points < 0",
|
||||
args: args{
|
||||
id: validTribeCursor.ID(),
|
||||
serverKey: validTribeCursor.ServerKey(),
|
||||
odScoreAtt: validTribeCursor.ODScoreAtt(),
|
||||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: -1,
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "TribeCursor",
|
||||
Field: "mostPoints",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, serverKeyTest := range newServerKeyValidationTests() {
|
||||
|
@ -434,6 +470,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
odScoreDef: validTribeCursor.ODScoreDef(),
|
||||
odScoreTotal: validTribeCursor.ODScoreTotal(),
|
||||
points: validTribeCursor.Points(),
|
||||
mostPoints: validTribeCursor.MostPoints(),
|
||||
dominance: validTribeCursor.Dominance(),
|
||||
deletedAt: validTribeCursor.DeletedAt(),
|
||||
},
|
||||
|
@ -456,6 +493,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
tt.args.odScoreDef,
|
||||
tt.args.odScoreTotal,
|
||||
tt.args.points,
|
||||
tt.args.mostPoints,
|
||||
tt.args.dominance,
|
||||
tt.args.deletedAt,
|
||||
)
|
||||
|
@ -469,6 +507,7 @@ func TestNewTribeCursor(t *testing.T) {
|
|||
assert.Equal(t, tt.args.odScoreDef, tc.ODScoreDef())
|
||||
assert.Equal(t, tt.args.odScoreTotal, tc.ODScoreTotal())
|
||||
assert.Equal(t, tt.args.points, tc.Points())
|
||||
assert.Equal(t, tt.args.mostPoints, tc.MostPoints())
|
||||
assert.InDelta(t, tt.args.dominance, tc.Dominance(), 0.001)
|
||||
assert.Equal(t, tt.args.deletedAt, tc.DeletedAt())
|
||||
assert.NotEmpty(t, tc.Encode())
|
||||
|
|
|
@ -22,6 +22,8 @@ var apiTribeSortAllowedValues = []domain.TribeSort{
|
|||
domain.TribeSortODScoreTotalDESC,
|
||||
domain.TribeSortPointsASC,
|
||||
domain.TribeSortPointsDESC,
|
||||
domain.TribeSortMostPointsASC,
|
||||
domain.TribeSortMostPointsDESC,
|
||||
domain.TribeSortDominanceASC,
|
||||
domain.TribeSortDominanceDESC,
|
||||
domain.TribeSortDeletedAtASC,
|
||||
|
|
|
@ -176,6 +176,32 @@ func TestListTribes(t *testing.T) {
|
|||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: sort=[mostPoints:DESC]",
|
||||
reqModifier: func(t *testing.T, req *http.Request) {
|
||||
t.Helper()
|
||||
q := req.URL.Query()
|
||||
q.Set("sort", "mostPoints:DESC")
|
||||
req.URL.RawQuery = q.Encode()
|
||||
},
|
||||
assertResp: func(t *testing.T, _ *http.Request, resp *http.Response) {
|
||||
t.Helper()
|
||||
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
// body
|
||||
body := decodeJSON[apimodel.ListTribesResponse](t, resp.Body)
|
||||
assert.Zero(t, body.Cursor.Next)
|
||||
assert.NotZero(t, body.Cursor.Self)
|
||||
assert.NotZero(t, body.Data)
|
||||
assert.True(t, slices.IsSortedFunc(body.Data, func(a, b apimodel.Tribe) int {
|
||||
return cmp.Or(
|
||||
cmp.Compare(a.MostPoints, b.MostPoints)*-1,
|
||||
cmp.Compare(a.Id, b.Id),
|
||||
)
|
||||
}))
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: tag",
|
||||
reqModifier: func(t *testing.T, req *http.Request) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user