From 4bae71da472415070d170fdbea9a5a18aaa0c96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Wysoki=C5=84ski?= Date: Wed, 13 Mar 2024 06:55:23 +0100 Subject: [PATCH] feat: add more filters to ListTribeChangesParams --- .../adapter/repository_bun_tribe_change.go | 19 ++ .../adapter/repository_ennoblement_test.go | 84 +++++++++ .../adapter/repository_tribe_change_test.go | 164 ++++++++++++++++++ internal/domain/tribe_change.go | 64 +++++++ internal/domain/tribe_change_test.go | 120 +++++++++++++ 5 files changed, 451 insertions(+) diff --git a/internal/adapter/repository_bun_tribe_change.go b/internal/adapter/repository_bun_tribe_change.go index 337ea25..5b6cd67 100644 --- a/internal/adapter/repository_bun_tribe_change.go +++ b/internal/adapter/repository_bun_tribe_change.go @@ -110,6 +110,25 @@ func (a listTribeChangesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuer q = q.Where("tc.server_key IN (?)", bun.In(serverKeys)) } + if playerIDs := a.params.PlayerIDs(); len(playerIDs) > 0 { + q = q.Where("tc.player_id IN (?)", bun.In(playerIDs)) + } + + if tribeIDs := a.params.TribeIDs(); len(tribeIDs) > 0 { + q = q.WhereGroup(" AND ", func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Where("tc.new_tribe_id IN (?)", bun.In(tribeIDs)). + WhereOr("tc.old_tribe_id IN (?)", bun.In(tribeIDs)) + }) + } + + if since := a.params.Since(); since.Valid { + q = q.Where("tc.created_at >= ?", since.V) + } + + if before := a.params.Before(); before.Valid { + q = q.Where("tc.created_at < ?", before.V) + } + for _, s := range a.params.Sort() { switch s { case domain.TribeChangeSortCreatedAtASC: diff --git a/internal/adapter/repository_ennoblement_test.go b/internal/adapter/repository_ennoblement_test.go index 0e6207c..6416c27 100644 --- a/internal/adapter/repository_ennoblement_test.go +++ b/internal/adapter/repository_ennoblement_test.go @@ -373,6 +373,90 @@ func testEnnoblementRepository(t *testing.T, newRepos func(t *testing.T) reposit require.NoError(t, err) }, }, + { + name: "OK: tribeIDs (new tribe) serverKeys", + params: func(t *testing.T) domain.ListEnnoblementsParams { + t.Helper() + + params := domain.NewListEnnoblementsParams() + + res, err := repos.ennoblement.List(ctx, params) + require.NoError(t, err) + require.NotEmpty(t, res.Ennoblements()) + + var randEnnoblement domain.Ennoblement + for _, e := range res.Ennoblements() { + if e.NewTribeID() > 0 { + randEnnoblement = e + break + } + } + + require.NoError(t, params.SetServerKeys([]string{randEnnoblement.ServerKey()})) + require.NoError(t, params.SetTribeIDs([]int{randEnnoblement.NewTribeID()})) + + return params + }, + assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) { + t.Helper() + + serverKeys := params.ServerKeys() + tribeIDs := params.TribeIDs() + + ennoblements := res.Ennoblements() + assert.NotZero(t, ennoblements) + for _, e := range ennoblements { + assert.True(t, slices.Contains(serverKeys, e.ServerKey())) + assert.True(t, slices.Contains(tribeIDs, e.NewTribeID()) || slices.Contains(tribeIDs, e.OldTribeID())) + } + }, + assertError: func(t *testing.T, err error) { + t.Helper() + require.NoError(t, err) + }, + }, + { + name: "OK: tribeIDs (old tribe) serverKeys", + params: func(t *testing.T) domain.ListEnnoblementsParams { + t.Helper() + + params := domain.NewListEnnoblementsParams() + + res, err := repos.ennoblement.List(ctx, params) + require.NoError(t, err) + require.NotEmpty(t, res.Ennoblements()) + + var randEnnoblement domain.Ennoblement + for _, e := range res.Ennoblements() { + if e.OldTribeID() > 0 { + randEnnoblement = e + break + } + } + + require.NoError(t, params.SetServerKeys([]string{randEnnoblement.ServerKey()})) + require.NoError(t, params.SetTribeIDs([]int{randEnnoblement.OldTribeID()})) + + return params + }, + assertResult: func(t *testing.T, params domain.ListEnnoblementsParams, res domain.ListEnnoblementsResult) { + t.Helper() + + serverKeys := params.ServerKeys() + tribeIDs := params.TribeIDs() + + ennoblements := res.Ennoblements() + assert.NotZero(t, ennoblements) + for _, e := range ennoblements { + assert.True(t, slices.Contains(serverKeys, e.ServerKey())) + assert.True(t, slices.Contains(tribeIDs, e.NewTribeID()) || slices.Contains(tribeIDs, e.OldTribeID())) + } + }, + assertError: func(t *testing.T, err error) { + t.Helper() + require.NoError(t, err) + }, + }, { name: "OK: since before", params: func(t *testing.T) domain.ListEnnoblementsParams { diff --git a/internal/adapter/repository_tribe_change_test.go b/internal/adapter/repository_tribe_change_test.go index 8cc4b26..2d60166 100644 --- a/internal/adapter/repository_tribe_change_test.go +++ b/internal/adapter/repository_tribe_change_test.go @@ -277,6 +277,170 @@ func testTribeChangeRepository(t *testing.T, newRepos func(t *testing.T) reposit require.NoError(t, err) }, }, + { + name: "OK: playerIDs serverKeys", + params: func(t *testing.T) domain.ListTribeChangesParams { + t.Helper() + + params := domain.NewListTribeChangesParams() + + res, err := repos.tribeChange.List(ctx, params) + require.NoError(t, err) + require.NotEmpty(t, res.TribeChanges()) + randTC := res.TribeChanges()[0] + + require.NoError(t, params.SetServerKeys([]string{randTC.ServerKey()})) + require.NoError(t, params.SetPlayerIDs([]int{randTC.PlayerID()})) + + return params + }, + assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) { + t.Helper() + + serverKeys := params.ServerKeys() + playerIDs := params.PlayerIDs() + + tcs := res.TribeChanges() + assert.NotZero(t, tcs) + for _, tc := range tcs { + assert.True(t, slices.Contains(serverKeys, tc.ServerKey())) + assert.True(t, slices.Contains(playerIDs, tc.PlayerID())) + } + }, + assertError: func(t *testing.T, err error) { + t.Helper() + require.NoError(t, err) + }, + }, + { + name: "OK: tribeIDs (new tribe) serverKeys", + params: func(t *testing.T) domain.ListTribeChangesParams { + t.Helper() + + params := domain.NewListTribeChangesParams() + + res, err := repos.tribeChange.List(ctx, params) + require.NoError(t, err) + require.NotEmpty(t, res.TribeChanges()) + + var randTC domain.TribeChange + for _, tc := range res.TribeChanges() { + if tc.NewTribeID() > 0 { + randTC = tc + break + } + } + + require.NoError(t, params.SetServerKeys([]string{randTC.ServerKey()})) + require.NoError(t, params.SetTribeIDs([]int{randTC.NewTribeID()})) + + return params + }, + assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) { + t.Helper() + + serverKeys := params.ServerKeys() + tribeIDs := params.TribeIDs() + + tcs := res.TribeChanges() + assert.NotZero(t, tcs) + for _, tc := range tcs { + assert.True(t, slices.Contains(serverKeys, tc.ServerKey())) + assert.True(t, slices.Contains(tribeIDs, tc.NewTribeID()) || slices.Contains(tribeIDs, tc.OldTribeID())) + } + }, + assertError: func(t *testing.T, err error) { + t.Helper() + require.NoError(t, err) + }, + }, + { + name: "OK: tribeIDs (old tribe) serverKeys", + params: func(t *testing.T) domain.ListTribeChangesParams { + t.Helper() + + params := domain.NewListTribeChangesParams() + + res, err := repos.tribeChange.List(ctx, params) + require.NoError(t, err) + require.NotEmpty(t, res.TribeChanges()) + + var randTC domain.TribeChange + for _, tc := range res.TribeChanges() { + if tc.OldTribeID() > 0 { + randTC = tc + break + } + } + + require.NoError(t, params.SetServerKeys([]string{randTC.ServerKey()})) + require.NoError(t, params.SetTribeIDs([]int{randTC.OldTribeID()})) + + return params + }, + assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) { + t.Helper() + + serverKeys := params.ServerKeys() + tribeIDs := params.TribeIDs() + + tcs := res.TribeChanges() + assert.NotZero(t, tcs) + for _, tc := range tcs { + assert.True(t, slices.Contains(serverKeys, tc.ServerKey())) + assert.True(t, slices.Contains(tribeIDs, tc.NewTribeID()) || slices.Contains(tribeIDs, tc.OldTribeID())) + } + }, + assertError: func(t *testing.T, err error) { + t.Helper() + require.NoError(t, err) + }, + }, + { + name: "OK: since before", + params: func(t *testing.T) domain.ListTribeChangesParams { + t.Helper() + + params := domain.NewListTribeChangesParams() + require.NoError(t, params.SetSort([]domain.TribeChangeSort{ + domain.TribeChangeSortCreatedAtASC, + domain.TribeChangeSortIDASC, + })) + + res, err := repos.tribeChange.List(ctx, params) + require.NoError(t, err) + require.GreaterOrEqual(t, len(res.TribeChanges()), 4) + + params = domain.NewListTribeChangesParams() + require.NoError(t, params.SetSince(domain.NullTime{ + V: res.TribeChanges()[1].CreatedAt(), + Valid: true, + })) + require.NoError(t, params.SetBefore(domain.NullTime{ + V: res.TribeChanges()[3].CreatedAt(), + Valid: true, + })) + + return params + }, + assertResult: func(t *testing.T, params domain.ListTribeChangesParams, res domain.ListTribeChangesResult) { + t.Helper() + + since := params.Since().V + before := params.Before().V + + tcs := res.TribeChanges() + assert.NotZero(t, tcs) + for _, tc := range tcs { + assert.True(t, tc.CreatedAt().After(since) || tc.CreatedAt().Equal(since)) + assert.True(t, tc.CreatedAt().Before(before)) + } + }, + assertError: func(t *testing.T, err error) { + t.Helper() + require.NoError(t, err) + }, + }, { name: "OK: cursor serverKeys sort=[id ASC]", params: func(t *testing.T) domain.ListTribeChangesParams { diff --git a/internal/domain/tribe_change.go b/internal/domain/tribe_change.go index 56b5c50..400587a 100644 --- a/internal/domain/tribe_change.go +++ b/internal/domain/tribe_change.go @@ -387,6 +387,10 @@ func (tcc TribeChangeCursor) Encode() string { type ListTribeChangesParams struct { serverKeys []string + playerIDs []int + tribeIDs []int // TribeChange.NewTribeID or TribeChange.OldTribeID + since NullTime + before NullTime sort []TribeChangeSort cursor TribeChangeCursor limit int @@ -429,6 +433,66 @@ func (params *ListTribeChangesParams) SetServerKeys(serverKeys []string) error { return nil } +func (params *ListTribeChangesParams) PlayerIDs() []int { + return params.playerIDs +} + +func (params *ListTribeChangesParams) SetPlayerIDs(playerIDs []int) error { + for i, id := range playerIDs { + if err := validateIntInRange(id, 1, math.MaxInt); err != nil { + return SliceElementValidationError{ + Model: listTribeChangesParamsModelName, + Field: "playerIDs", + Index: i, + Err: err, + } + } + } + + params.playerIDs = playerIDs + + return nil +} + +func (params *ListTribeChangesParams) TribeIDs() []int { + return params.tribeIDs +} + +func (params *ListTribeChangesParams) SetTribeIDs(tribeIDs []int) error { + for i, id := range tribeIDs { + if err := validateIntInRange(id, 1, math.MaxInt); err != nil { + return SliceElementValidationError{ + Model: listTribeChangesParamsModelName, + Field: "tribeIDs", + Index: i, + Err: err, + } + } + } + + params.tribeIDs = tribeIDs + + return nil +} + +func (params *ListTribeChangesParams) Since() NullTime { + return params.since +} + +func (params *ListTribeChangesParams) SetSince(since NullTime) error { + params.since = since + return nil +} + +func (params *ListTribeChangesParams) Before() NullTime { + return params.before +} + +func (params *ListTribeChangesParams) SetBefore(before NullTime) error { + params.before = before + return nil +} + func (params *ListTribeChangesParams) Sort() []TribeChangeSort { return params.sort } diff --git a/internal/domain/tribe_change_test.go b/internal/domain/tribe_change_test.go index 78ac367..532618a 100644 --- a/internal/domain/tribe_change_test.go +++ b/internal/domain/tribe_change_test.go @@ -416,6 +416,126 @@ func TestListTribeChangesParams_SetServerKeys(t *testing.T) { } } +func TestListTribeChangesParams_SetPlayerIDs(t *testing.T) { + t.Parallel() + + type args struct { + playerIDs []int + } + + tests := []struct { + name string + args args + expectedErr error + }{ + { + name: "OK", + args: args{ + playerIDs: []int{ + domaintest.RandID(), + domaintest.RandID(), + domaintest.RandID(), + }, + }, + }, + { + name: "ERR: value < 1", + args: args{ + playerIDs: []int{ + domaintest.RandID(), + domaintest.RandID(), + domaintest.RandID(), + 0, + domaintest.RandID(), + }, + }, + expectedErr: domain.SliceElementValidationError{ + Model: "ListTribeChangesParams", + Field: "playerIDs", + Index: 3, + Err: domain.MinGreaterEqualError{ + Min: 1, + Current: 0, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + params := domain.NewListTribeChangesParams() + + require.ErrorIs(t, params.SetPlayerIDs(tt.args.playerIDs), tt.expectedErr) + if tt.expectedErr != nil { + return + } + assert.Equal(t, tt.args.playerIDs, params.PlayerIDs()) + }) + } +} + +func TestListTribeChangesParams_SetTribeIDs(t *testing.T) { + t.Parallel() + + type args struct { + tribeIDs []int + } + + tests := []struct { + name string + args args + expectedErr error + }{ + { + name: "OK", + args: args{ + tribeIDs: []int{ + domaintest.RandID(), + domaintest.RandID(), + domaintest.RandID(), + }, + }, + }, + { + name: "ERR: value < 1", + args: args{ + tribeIDs: []int{ + domaintest.RandID(), + domaintest.RandID(), + domaintest.RandID(), + 0, + domaintest.RandID(), + }, + }, + expectedErr: domain.SliceElementValidationError{ + Model: "ListTribeChangesParams", + Field: "tribeIDs", + Index: 3, + Err: domain.MinGreaterEqualError{ + Min: 1, + Current: 0, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + params := domain.NewListTribeChangesParams() + + require.ErrorIs(t, params.SetTribeIDs(tt.args.tribeIDs), tt.expectedErr) + if tt.expectedErr != nil { + return + } + assert.Equal(t, tt.args.tribeIDs, params.TribeIDs()) + }) + } +} + func TestListTribeChangesParams_SetSort(t *testing.T) { t.Parallel()