feat: api - GET /api/v2/versions/{versionCode}/servers/{serverKey}/tribes - new query param 'tag'

This commit is contained in:
Dawid Wysokiński 2024-02-20 07:50:16 +01:00
parent 6e4fe7131a
commit 4ce2131ac4
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
6 changed files with 156 additions and 0 deletions

View File

@ -143,6 +143,7 @@ paths:
- $ref: "#/components/parameters/LimitQueryParam"
- $ref: "#/components/parameters/TribeDeletedQueryParam"
- $ref: "#/components/parameters/TribeSortQueryParam"
- $ref: "#/components/parameters/TribeTagQueryParam"
responses:
200:
$ref: "#/components/responses/ListTribesResponse"
@ -972,6 +973,14 @@ components:
- deletedAt:ASC
- deletedAt:DESC
maxItems: 2
TribeTagQueryParam:
name: tag
in: query
schema:
type: array
items:
type: string
maxItems: 100
VersionCodePathParam:
in: path
name: versionCode

View File

@ -165,6 +165,10 @@ func (a listTribesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
q = q.Where("tribe.server_key IN (?)", bun.In(serverKeys))
}
if tags := a.params.Tags(); len(tags) > 0 {
q = q.Where("tribe.tag IN (?)", bun.In(tags))
}
if deleted := a.params.Deleted(); deleted.Valid {
if deleted.Value {
q = q.Where("tribe.deleted_at IS NOT NULL")

View File

@ -460,6 +460,41 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
require.NoError(t, err)
},
},
{
name: "OK: tags serverKeys",
params: func(t *testing.T) domain.ListTribesParams {
t.Helper()
params := domain.NewListTribesParams()
res, err := repos.tribe.List(ctx, params)
require.NoError(t, err)
require.NotEmpty(t, len(res.Tribes()))
randTribe := res.Tribes()[0]
require.NoError(t, params.SetTags([]string{randTribe.Tag()}))
require.NoError(t, params.SetServerKeys([]string{randTribe.ServerKey()}))
return params
},
assertResult: func(t *testing.T, params domain.ListTribesParams, res domain.ListTribesResult) {
t.Helper()
tags := params.Tags()
serverKeys := params.ServerKeys()
tribes := res.Tribes()
assert.NotEmpty(t, tribes)
for _, tr := range tribes {
assert.True(t, slices.Contains(tags, tr.Tag()))
assert.True(t, slices.Contains(serverKeys, tr.ServerKey()))
}
},
assertError: func(t *testing.T, err error) {
t.Helper()
require.NoError(t, err)
},
},
{
name: "OK: deleted=true",
params: func(t *testing.T) domain.ListTribesParams {

View File

@ -618,6 +618,7 @@ func (tc TribeCursor) Encode() string {
type ListTribesParams struct {
ids []int
serverKeys []string
tags []string
deleted NullBool
sort []TribeSort
cursor TribeCursor
@ -669,6 +670,29 @@ func (params *ListTribesParams) SetServerKeys(serverKeys []string) error {
return nil
}
func (params *ListTribesParams) Tags() []string {
return params.tags
}
const (
tribeTagsMinLength = 1
tribeTagsMaxLength = 100
)
func (params *ListTribesParams) SetTags(tags []string) error {
if err := validateSliceLen(tags, tribeTagsMinLength, tribeTagsMaxLength); err != nil {
return ValidationError{
Model: listTribesParamsModelName,
Field: "tags",
Err: err,
}
}
params.tags = tags
return nil
}
func (params *ListTribesParams) Deleted() NullBool {
return params.deleted
}

View File

@ -430,6 +430,83 @@ func TestListTribesParams_SetIDs(t *testing.T) {
}
}
func TestListTribesParams_SetTags(t *testing.T) {
t.Parallel()
type args struct {
tags []string
}
tests := []struct {
name string
args args
expectedErr error
}{
{
name: "OK",
args: args{
tags: []string{
domaintest.RandTribeTag(),
domaintest.RandTribeTag(),
domaintest.RandTribeTag(),
domaintest.RandTribeTag(),
domaintest.RandTribeTag(),
},
},
},
{
name: "ERR: len(tags) < 1",
args: args{
tags: nil,
},
expectedErr: domain.ValidationError{
Model: "ListTribesParams",
Field: "tags",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 100,
Current: 0,
},
},
},
{
name: "ERR: len(tags) > 100",
args: args{
tags: func() []string {
tags := make([]string, 101)
for i := range tags {
tags[i] = domaintest.RandTribeTag()
}
return tags
}(),
},
expectedErr: domain.ValidationError{
Model: "ListTribesParams",
Field: "tags",
Err: domain.LenOutOfRangeError{
Min: 1,
Max: 100,
Current: 101,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
params := domain.NewListTribesParams()
require.ErrorIs(t, params.SetTags(tt.args.tags), tt.expectedErr)
if tt.expectedErr != nil {
return
}
assert.Equal(t, tt.args.tags, params.Tags())
})
}
}
func TestListTribesParams_SetSort(t *testing.T) {
t.Parallel()

View File

@ -35,6 +35,13 @@ func (h *apiHTTPHandler) ListTribes(
return
}
if params.Tag != nil {
if err := domainParams.SetTags(*params.Tag); err != nil {
apiErrorRenderer{errors: []error{err}, formatErrorPath: formatListTribesParamsErrorPath}.render(w, r)
return
}
}
if params.Deleted != nil {
if err := domainParams.SetDeleted(domain.NullBool{
Value: *params.Deleted,