parent
4d6c1c8982
commit
f8c9bdb321
|
@ -583,8 +583,12 @@ components:
|
|||
- key
|
||||
- open
|
||||
- url
|
||||
- numPlayers
|
||||
- numActivePlayers
|
||||
- numInactivePlayers
|
||||
- numTribes
|
||||
- numActiveTribes
|
||||
- numInactiveTribes
|
||||
- numVillages
|
||||
- numBarbarianVillages
|
||||
- numBonusVillages
|
||||
|
@ -599,13 +603,23 @@ components:
|
|||
type: string
|
||||
format: uri
|
||||
example: https://en138.tribalwars.net
|
||||
numPlayers:
|
||||
type: integer
|
||||
description: numActivePlayers+numInactivePlayers
|
||||
numActivePlayers:
|
||||
type: integer
|
||||
numInactivePlayers:
|
||||
type: integer
|
||||
playerDataSyncedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
numTribes:
|
||||
type: integer
|
||||
description: numActiveTribes+numInactiveTribes
|
||||
numActiveTribes:
|
||||
type: integer
|
||||
numInactiveTribes:
|
||||
type: integer
|
||||
tribeDataSyncedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
|
|
|
@ -38,6 +38,7 @@ func (pub *PlayerWatermillPublisher) EventSynced(
|
|||
ServerKey: p.ServerKey(),
|
||||
VersionCode: p.VersionCode(),
|
||||
ServerURL: p.ServerURL(),
|
||||
NumPlayers: p.NumPlayers(),
|
||||
NumActivePlayers: p.NumActivePlayers(),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -38,6 +38,7 @@ func (pub *TribeWatermillPublisher) EventSynced(
|
|||
ServerKey: p.ServerKey(),
|
||||
VersionCode: p.VersionCode(),
|
||||
ServerURL: p.ServerURL(),
|
||||
NumTribes: p.NumTribes(),
|
||||
NumActiveTribes: p.NumActiveTribes(),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -131,6 +131,17 @@ func (repo *PlayerBunRepository) ListWithRelations(
|
|||
return domain.NewListPlayersWithRelationsResult(separateListResultAndNext(converted, params.Limit()))
|
||||
}
|
||||
|
||||
func (repo *PlayerBunRepository) Count(ctx context.Context, params domain.CountPlayersParams) (int, error) {
|
||||
cnt, err := repo.db.NewSelect().
|
||||
Model((*bunmodel.Player)(nil)).
|
||||
Apply(countPlayersParamsApplier{params: params}.apply).
|
||||
Count(ctx)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("couldnt count players: %w", err)
|
||||
}
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
func (repo *PlayerBunRepository) Delete(ctx context.Context, serverKey string, ids ...int) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
|
@ -323,3 +334,15 @@ func (a listPlayersParamsApplier) sortToColumnAndDirection(
|
|||
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
|
||||
}
|
||||
}
|
||||
|
||||
type countPlayersParamsApplier struct {
|
||||
params domain.CountPlayersParams
|
||||
}
|
||||
|
||||
func (a countPlayersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
|
||||
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {
|
||||
q = q.Where("player.server_key IN (?)", bun.In(serverKeys))
|
||||
}
|
||||
|
||||
return q
|
||||
}
|
||||
|
|
|
@ -126,18 +126,34 @@ func (a updateServerParamsApplier) apply(q *bun.UpdateQuery) *bun.UpdateQuery {
|
|||
q = q.Set("building_info = ?", bunmodel.NewBuildingInfo(buildingInfo.V))
|
||||
}
|
||||
|
||||
if numTribes := a.params.NumTribes(); numTribes.Valid {
|
||||
q = q.Set("num_tribes = ?", numTribes.V)
|
||||
}
|
||||
|
||||
if numActiveTribes := a.params.NumActiveTribes(); numActiveTribes.Valid {
|
||||
q = q.Set("num_active_tribes = ?", numActiveTribes.V)
|
||||
}
|
||||
|
||||
if numInactiveTribes := a.params.NumInactiveTribes(); numInactiveTribes.Valid {
|
||||
q = q.Set("num_inactive_tribes = ?", numInactiveTribes.V)
|
||||
}
|
||||
|
||||
if tribeDataSyncedAt := a.params.TribeDataSyncedAt(); tribeDataSyncedAt.Valid {
|
||||
q = q.Set("tribe_data_synced_at = ?", tribeDataSyncedAt.V)
|
||||
}
|
||||
|
||||
if numPlayers := a.params.NumPlayers(); numPlayers.Valid {
|
||||
q = q.Set("num_players = ?", numPlayers.V)
|
||||
}
|
||||
|
||||
if numActivePlayers := a.params.NumActivePlayers(); numActivePlayers.Valid {
|
||||
q = q.Set("num_active_players = ?", numActivePlayers.V)
|
||||
}
|
||||
|
||||
if numInactivePlayers := a.params.NumInactivePlayers(); numInactivePlayers.Valid {
|
||||
q = q.Set("num_inactive_players = ?", numInactivePlayers.V)
|
||||
}
|
||||
|
||||
if playerDataSyncedAt := a.params.PlayerDataSyncedAt(); playerDataSyncedAt.Valid {
|
||||
q = q.Set("player_data_synced_at = ?", playerDataSyncedAt.V)
|
||||
}
|
||||
|
|
|
@ -132,6 +132,17 @@ func (repo *TribeBunRepository) List(
|
|||
return domain.NewListTribesResult(separateListResultAndNext(converted, params.Limit()))
|
||||
}
|
||||
|
||||
func (repo *TribeBunRepository) Count(ctx context.Context, params domain.CountTribesParams) (int, error) {
|
||||
cnt, err := repo.db.NewSelect().
|
||||
Model((*bunmodel.Tribe)(nil)).
|
||||
Apply(countTribesParamsApplier{params: params}.apply).
|
||||
Count(ctx)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("couldnt count tribes: %w", err)
|
||||
}
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
func (repo *TribeBunRepository) Delete(ctx context.Context, serverKey string, ids ...int) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
|
@ -287,3 +298,15 @@ func (a listTribesParamsApplier) sortToColumnAndDirection(
|
|||
return "", 0, fmt.Errorf("%s: %w", s.String(), errInvalidSortValue)
|
||||
}
|
||||
}
|
||||
|
||||
type countTribesParamsApplier struct {
|
||||
params domain.CountTribesParams
|
||||
}
|
||||
|
||||
func (a countTribesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
|
||||
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {
|
||||
q = q.Where("tribe.server_key IN (?)", bun.In(serverKeys))
|
||||
}
|
||||
|
||||
return q
|
||||
}
|
||||
|
|
|
@ -664,6 +664,78 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
}
|
||||
})
|
||||
|
||||
t.Run("Count", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
repos := newRepos(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
params func(t *testing.T) domain.CountPlayersParams
|
||||
assertResult func(t *testing.T, params domain.CountPlayersParams, count int)
|
||||
assertError func(t *testing.T, err error)
|
||||
}{
|
||||
{
|
||||
name: "OK: default params",
|
||||
params: func(t *testing.T) domain.CountPlayersParams {
|
||||
t.Helper()
|
||||
return domain.NewCountPlayersParams()
|
||||
},
|
||||
assertResult: func(t *testing.T, _ domain.CountPlayersParams, count int) {
|
||||
t.Helper()
|
||||
res, err := repos.player.List(ctx, domain.NewListPlayersParams())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res.Players(), count)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: serverKeys",
|
||||
params: func(t *testing.T) domain.CountPlayersParams {
|
||||
t.Helper()
|
||||
|
||||
res, err := repos.player.List(ctx, domain.NewListPlayersParams())
|
||||
require.NoError(t, err)
|
||||
|
||||
params := domain.NewCountPlayersParams()
|
||||
require.NoError(t, params.SetServerKeys([]string{res.Players()[0].ServerKey()}))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.CountPlayersParams, count int) {
|
||||
t.Helper()
|
||||
|
||||
listParams := domain.NewListPlayersParams()
|
||||
require.NoError(t, listParams.SetServerKeys(params.ServerKeys()))
|
||||
|
||||
res, err := repos.player.List(ctx, listParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, res.Players(), count)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assertError := tt.assertError
|
||||
if assertError == nil {
|
||||
assertError = func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
params := tt.params(t)
|
||||
|
||||
cnt, err := repos.player.Count(ctx, params)
|
||||
assertError(t, err)
|
||||
tt.assertResult(t, params, cnt)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -494,18 +494,34 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
V: domaintest.NewBuildingInfo(t),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetNumTribes(domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetNumActiveTribes(domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetNumInactiveTribes(domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetTribeDataSyncedAt(domain.NullTime{
|
||||
V: time.Now(),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetNumPlayers(domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetNumActivePlayers(domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetNumInactivePlayers(domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
}))
|
||||
require.NoError(t, updateParams.SetPlayerDataSyncedAt(domain.NullTime{
|
||||
V: time.Now(),
|
||||
Valid: true,
|
||||
|
@ -556,14 +572,18 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
|
|||
assert.Equal(t, updateParams.Config().V, serverAfterUpdate.Config())
|
||||
assert.Equal(t, updateParams.UnitInfo().V, serverAfterUpdate.UnitInfo())
|
||||
assert.Equal(t, updateParams.BuildingInfo().V, serverAfterUpdate.BuildingInfo())
|
||||
assert.Equal(t, updateParams.NumTribes().V, serverAfterUpdate.NumTribes())
|
||||
assert.Equal(t, updateParams.NumActiveTribes().V, serverAfterUpdate.NumActiveTribes())
|
||||
assert.Equal(t, updateParams.NumInactiveTribes().V, serverAfterUpdate.NumInactiveTribes())
|
||||
assert.WithinDuration(
|
||||
t,
|
||||
updateParams.TribeDataSyncedAt().V,
|
||||
serverAfterUpdate.TribeDataSyncedAt(),
|
||||
time.Minute,
|
||||
)
|
||||
assert.Equal(t, updateParams.NumPlayers().V, serverAfterUpdate.NumPlayers())
|
||||
assert.Equal(t, updateParams.NumActivePlayers().V, serverAfterUpdate.NumActivePlayers())
|
||||
assert.Equal(t, updateParams.NumInactivePlayers().V, serverAfterUpdate.NumInactivePlayers())
|
||||
assert.WithinDuration(
|
||||
t,
|
||||
updateParams.PlayerDataSyncedAt().V,
|
||||
|
|
|
@ -26,6 +26,7 @@ type tribeRepository interface {
|
|||
CreateOrUpdate(ctx context.Context, params ...domain.CreateTribeParams) error
|
||||
UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int) error
|
||||
List(ctx context.Context, params domain.ListTribesParams) (domain.ListTribesResult, error)
|
||||
Count(ctx context.Context, params domain.CountTribesParams) (int, error)
|
||||
Delete(ctx context.Context, serverKey string, ids ...int) error
|
||||
}
|
||||
|
||||
|
@ -33,6 +34,7 @@ type playerRepository interface {
|
|||
CreateOrUpdate(ctx context.Context, params ...domain.CreatePlayerParams) error
|
||||
List(ctx context.Context, params domain.ListPlayersParams) (domain.ListPlayersResult, error)
|
||||
ListWithRelations(ctx context.Context, params domain.ListPlayersParams) (domain.ListPlayersWithRelationsResult, error)
|
||||
Count(ctx context.Context, params domain.CountPlayersParams) (int, error)
|
||||
Delete(ctx context.Context, serverKey string, ids ...int) error
|
||||
}
|
||||
|
||||
|
|
|
@ -718,6 +718,78 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
|
|||
}
|
||||
})
|
||||
|
||||
t.Run("Count", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
repos := newRepos(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
params func(t *testing.T) domain.CountTribesParams
|
||||
assertResult func(t *testing.T, params domain.CountTribesParams, count int)
|
||||
assertError func(t *testing.T, err error)
|
||||
}{
|
||||
{
|
||||
name: "OK: default params",
|
||||
params: func(t *testing.T) domain.CountTribesParams {
|
||||
t.Helper()
|
||||
return domain.NewCountTribesParams()
|
||||
},
|
||||
assertResult: func(t *testing.T, _ domain.CountTribesParams, count int) {
|
||||
t.Helper()
|
||||
res, err := repos.tribe.List(ctx, domain.NewListTribesParams())
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, res.Tribes(), count)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: serverKeys",
|
||||
params: func(t *testing.T) domain.CountTribesParams {
|
||||
t.Helper()
|
||||
|
||||
res, err := repos.tribe.List(ctx, domain.NewListTribesParams())
|
||||
require.NoError(t, err)
|
||||
|
||||
params := domain.NewCountTribesParams()
|
||||
require.NoError(t, params.SetServerKeys([]string{res.Tribes()[0].ServerKey()}))
|
||||
|
||||
return params
|
||||
},
|
||||
assertResult: func(t *testing.T, params domain.CountTribesParams, count int) {
|
||||
t.Helper()
|
||||
|
||||
listParams := domain.NewListTribesParams()
|
||||
require.NoError(t, listParams.SetServerKeys(params.ServerKeys()))
|
||||
|
||||
res, err := repos.tribe.List(ctx, listParams)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, res.Tribes(), count)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assertError := tt.assertError
|
||||
if assertError == nil {
|
||||
assertError = func(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
params := tt.params(t)
|
||||
|
||||
cnt, err := repos.tribe.Count(ctx, params)
|
||||
assertError(t, err)
|
||||
tt.assertResult(t, params, cnt)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ type PlayerRepository interface {
|
|||
CreateOrUpdate(ctx context.Context, params ...domain.CreatePlayerParams) error
|
||||
List(ctx context.Context, params domain.ListPlayersParams) (domain.ListPlayersResult, error)
|
||||
ListWithRelations(ctx context.Context, params domain.ListPlayersParams) (domain.ListPlayersWithRelationsResult, error)
|
||||
Count(ctx context.Context, params domain.CountPlayersParams) (int, error)
|
||||
// Delete marks players with the given serverKey and ids as deleted (sets deleted at to now).
|
||||
// In addition, Delete sets TribeID to null.
|
||||
//
|
||||
|
@ -51,10 +52,21 @@ func (svc *PlayerService) Sync(ctx context.Context, serverSyncedPayload domain.S
|
|||
return fmt.Errorf("%s: couldn't delete players: %w", serverKey, err)
|
||||
}
|
||||
|
||||
countParams := domain.NewCountPlayersParams()
|
||||
if err = countParams.SetServerKeys([]string{serverKey}); err != nil {
|
||||
return fmt.Errorf("%s: %w", serverKey, err)
|
||||
}
|
||||
|
||||
numPlayers, err := svc.repo.Count(ctx, countParams)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", serverKey, err)
|
||||
}
|
||||
|
||||
payload, err := domain.NewPlayersSyncedEventPayload(
|
||||
serverKey,
|
||||
serverURL,
|
||||
serverSyncedPayload.VersionCode(),
|
||||
numPlayers,
|
||||
len(players),
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -101,7 +113,7 @@ func (svc *PlayerService) createOrUpdateChunk(ctx context.Context, serverKey str
|
|||
if err := listParams.SetSort([]domain.PlayerSort{domain.PlayerSortIDASC}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := listParams.SetLimit(domain.PlayerListMaxLimit); err != nil {
|
||||
if err := listParams.SetLimit(len(ids)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -183,12 +183,24 @@ func (svc *ServerService) UpdateNumTribes(ctx context.Context, payload domain.Tr
|
|||
key := payload.ServerKey()
|
||||
|
||||
var updateParams domain.UpdateServerParams
|
||||
if err := updateParams.SetNumTribes(domain.NullInt{
|
||||
V: payload.NumTribes(),
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%s: %w", key, err)
|
||||
}
|
||||
if err := updateParams.SetNumActiveTribes(domain.NullInt{
|
||||
V: payload.NumActiveTribes(),
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%s: %w", key, err)
|
||||
}
|
||||
if err := updateParams.SetNumInactiveTribes(domain.NullInt{
|
||||
V: payload.NumInactiveTribes(),
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%s: %w", key, err)
|
||||
}
|
||||
if err := updateParams.SetTribeDataSyncedAt(domain.NullTime{
|
||||
V: time.Now(),
|
||||
Valid: true,
|
||||
|
@ -203,12 +215,24 @@ func (svc *ServerService) UpdateNumPlayers(ctx context.Context, payload domain.P
|
|||
key := payload.ServerKey()
|
||||
|
||||
var updateParams domain.UpdateServerParams
|
||||
if err := updateParams.SetNumPlayers(domain.NullInt{
|
||||
V: payload.NumPlayers(),
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%s: %w", key, err)
|
||||
}
|
||||
if err := updateParams.SetNumActivePlayers(domain.NullInt{
|
||||
V: payload.NumActivePlayers(),
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%s: %w", key, err)
|
||||
}
|
||||
if err := updateParams.SetNumInactivePlayers(domain.NullInt{
|
||||
V: payload.NumInactivePlayers(),
|
||||
Valid: true,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%s: %w", key, err)
|
||||
}
|
||||
if err := updateParams.SetPlayerDataSyncedAt(domain.NullTime{
|
||||
V: time.Now(),
|
||||
Valid: true,
|
||||
|
|
|
@ -11,6 +11,7 @@ type TribeRepository interface {
|
|||
CreateOrUpdate(ctx context.Context, params ...domain.CreateTribeParams) error
|
||||
UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int) error
|
||||
List(ctx context.Context, params domain.ListTribesParams) (domain.ListTribesResult, error)
|
||||
Count(ctx context.Context, params domain.CountTribesParams) (int, error)
|
||||
// Delete marks players with the given serverKey and ids as deleted (sets deleted at to now).
|
||||
//
|
||||
// https://en.wiktionary.org/wiki/soft_deletion
|
||||
|
@ -44,10 +45,21 @@ func (svc *TribeService) Sync(ctx context.Context, serverSyncedPayload domain.Se
|
|||
return fmt.Errorf("%s: couldn't delete tribes: %w", serverKey, err)
|
||||
}
|
||||
|
||||
countParams := domain.NewCountTribesParams()
|
||||
if err = countParams.SetServerKeys([]string{serverKey}); err != nil {
|
||||
return fmt.Errorf("%s: %w", serverKey, err)
|
||||
}
|
||||
|
||||
numTribes, err := svc.repo.Count(ctx, countParams)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", serverKey, err)
|
||||
}
|
||||
|
||||
payload, err := domain.NewTribesSyncedEventPayload(
|
||||
serverKey,
|
||||
serverURL,
|
||||
serverSyncedPayload.VersionCode(),
|
||||
numTribes,
|
||||
len(tribes),
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -94,7 +106,7 @@ func (svc *TribeService) createOrUpdateChunk(ctx context.Context, serverKey stri
|
|||
if err := listParams.SetSort([]domain.TribeSort{domain.TribeSortIDASC}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := listParams.SetLimit(domain.TribeListMaxLimit); err != nil {
|
||||
if err := listParams.SetLimit(len(ids)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,12 @@ type Server struct {
|
|||
URL string `bun:"url,nullzero"`
|
||||
Open bool `bun:"open"`
|
||||
Special bool `bun:"special"`
|
||||
NumPlayers int `bun:"num_players"`
|
||||
NumActivePlayers int `bun:"num_active_players"`
|
||||
NumInactivePlayers int `bun:"num_inactive_players"`
|
||||
NumTribes int `bun:"num_tribes"`
|
||||
NumActiveTribes int `bun:"num_active_tribes"`
|
||||
NumInactiveTribes int `bun:"num_inactive_tribes"`
|
||||
NumVillages int `bun:"num_villages"`
|
||||
NumPlayerVillages int `bun:"num_player_villages"`
|
||||
NumBarbarianVillages int `bun:"num_barbarian_villages"`
|
||||
|
@ -57,8 +61,12 @@ func (s Server) ToDomain() (domain.Server, error) {
|
|||
s.URL,
|
||||
s.Open,
|
||||
s.Special,
|
||||
s.NumPlayers,
|
||||
s.NumActivePlayers,
|
||||
s.NumInactivePlayers,
|
||||
s.NumTribes,
|
||||
s.NumActiveTribes,
|
||||
s.NumInactiveTribes,
|
||||
s.NumVillages,
|
||||
s.NumPlayerVillages,
|
||||
s.NumBarbarianVillages,
|
||||
|
@ -84,7 +92,7 @@ func (s Server) ToDomain() (domain.Server, error) {
|
|||
func (s Server) ToMeta() (domain.ServerMeta, error) {
|
||||
converted, err := domain.UnmarshalServerMetaFromDatabase(s.Key, s.URL, s.Open)
|
||||
if err != nil {
|
||||
return domain.ServerMeta{}, fmt.Errorf("couldn't construct domain.Server (key=%s): %w", s.Key, err)
|
||||
return domain.ServerMeta{}, fmt.Errorf("couldn't construct domain.ServerMeta (key=%s): %w", s.Key, err)
|
||||
}
|
||||
return converted, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
|
||||
return db.RunInTx(ctx, &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error {
|
||||
for _, column := range getColumnsToAdd20240506051128() {
|
||||
_, err := tx.ExecContext(ctx, "ALTER TABLE servers ADD ? bigint DEFAULT 0", bun.Safe(column))
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", column, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}, func(ctx context.Context, db *bun.DB) error {
|
||||
return db.RunInTx(ctx, &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error {
|
||||
for _, column := range getColumnsToAdd20240506051128() {
|
||||
_, err := tx.ExecContext(ctx, "ALTER TABLE servers DROP COLUMN ?", bun.Safe(column))
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", column, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func getColumnsToAdd20240506051128() []string {
|
||||
return []string{
|
||||
"num_players",
|
||||
"num_inactive_players",
|
||||
"num_tribes",
|
||||
"num_inactive_tribes",
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/core/internal/bun/bunmodel"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
func init() {
|
||||
migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
|
||||
var servers bunmodel.Servers
|
||||
|
||||
if err := db.NewSelect().Model(&servers).Where("special = false").Scan(ctx); err != nil {
|
||||
return fmt.Errorf("couldn't select servers from the db: %w", err)
|
||||
}
|
||||
|
||||
for _, s := range servers {
|
||||
numPlayers, err := db.NewSelect().Model((*bunmodel.Player)(nil)).Where("server_key = ?", s.Key).Count(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: numPlayers: %w", s.Key, err)
|
||||
}
|
||||
|
||||
numTribes, err := db.NewSelect().Model((*bunmodel.Tribe)(nil)).Where("server_key = ?", s.Key).Count(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: numTribes: %w", s.Key, err)
|
||||
}
|
||||
|
||||
_, err = db.NewUpdate().
|
||||
Model((*bunmodel.Server)(nil)).
|
||||
Returning("NULL").
|
||||
Where("key = ?", s.Key).
|
||||
Set("num_players = ?", numPlayers).
|
||||
Set("num_inactive_players = ?", numPlayers-s.NumActivePlayers).
|
||||
Set("num_tribes = ?", numTribes).
|
||||
Set("num_inactive_tribes = ?", numTribes-s.NumActiveTribes).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %w", s.Key, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(_ context.Context, _ *bun.DB) error {
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -89,6 +89,10 @@ func NewServer(tb TestingTB, opts ...func(cfg *ServerConfig)) domain.Server {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NewServerConfig(tb),
|
||||
NewBuildingInfo(tb),
|
||||
NewUnitInfo(tb),
|
||||
|
|
|
@ -112,6 +112,7 @@ type TribesSyncedEventPayload struct {
|
|||
serverKey string
|
||||
serverURL *url.URL
|
||||
versionCode string
|
||||
numTribes int
|
||||
numActiveTribes int
|
||||
}
|
||||
|
||||
|
@ -121,6 +122,7 @@ func NewTribesSyncedEventPayload(
|
|||
serverKey string,
|
||||
serverURL *url.URL,
|
||||
versionCode string,
|
||||
numTribes int,
|
||||
numActiveTribes int,
|
||||
) (TribesSyncedEventPayload, error) {
|
||||
if serverKey == "" {
|
||||
|
@ -147,6 +149,14 @@ func NewTribesSyncedEventPayload(
|
|||
}
|
||||
}
|
||||
|
||||
if err := validateIntInRange(numTribes, 0, math.MaxInt); err != nil {
|
||||
return TribesSyncedEventPayload{}, ValidationError{
|
||||
Model: tribesSyncedEventPayloadModelName,
|
||||
Field: "numTribes",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateIntInRange(numActiveTribes, 0, math.MaxInt); err != nil {
|
||||
return TribesSyncedEventPayload{}, ValidationError{
|
||||
Model: tribesSyncedEventPayloadModelName,
|
||||
|
@ -159,6 +169,7 @@ func NewTribesSyncedEventPayload(
|
|||
serverKey: serverKey,
|
||||
serverURL: serverURL,
|
||||
versionCode: versionCode,
|
||||
numTribes: numTribes,
|
||||
numActiveTribes: numActiveTribes,
|
||||
}, nil
|
||||
}
|
||||
|
@ -175,14 +186,23 @@ func (p TribesSyncedEventPayload) VersionCode() string {
|
|||
return p.versionCode
|
||||
}
|
||||
|
||||
func (p TribesSyncedEventPayload) NumTribes() int {
|
||||
return p.numTribes
|
||||
}
|
||||
|
||||
func (p TribesSyncedEventPayload) NumActiveTribes() int {
|
||||
return p.numActiveTribes
|
||||
}
|
||||
|
||||
func (p TribesSyncedEventPayload) NumInactiveTribes() int {
|
||||
return p.numTribes - p.numActiveTribes
|
||||
}
|
||||
|
||||
type PlayersSyncedEventPayload struct {
|
||||
serverKey string
|
||||
serverURL *url.URL
|
||||
versionCode string
|
||||
numPlayers int
|
||||
numActivePlayers int
|
||||
}
|
||||
|
||||
|
@ -192,6 +212,7 @@ func NewPlayersSyncedEventPayload(
|
|||
serverKey string,
|
||||
serverURL *url.URL,
|
||||
versionCode string,
|
||||
numPlayers int,
|
||||
numActivePlayers int,
|
||||
) (PlayersSyncedEventPayload, error) {
|
||||
if serverKey == "" {
|
||||
|
@ -218,6 +239,14 @@ func NewPlayersSyncedEventPayload(
|
|||
}
|
||||
}
|
||||
|
||||
if err := validateIntInRange(numPlayers, 0, math.MaxInt); err != nil {
|
||||
return PlayersSyncedEventPayload{}, ValidationError{
|
||||
Model: playersSyncedEventPayloadModelName,
|
||||
Field: "numPlayers",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateIntInRange(numActivePlayers, 0, math.MaxInt); err != nil {
|
||||
return PlayersSyncedEventPayload{}, ValidationError{
|
||||
Model: playersSyncedEventPayloadModelName,
|
||||
|
@ -230,6 +259,7 @@ func NewPlayersSyncedEventPayload(
|
|||
serverKey: serverKey,
|
||||
serverURL: serverURL,
|
||||
versionCode: versionCode,
|
||||
numPlayers: numPlayers,
|
||||
numActivePlayers: numActivePlayers,
|
||||
}, nil
|
||||
}
|
||||
|
@ -246,10 +276,18 @@ func (p PlayersSyncedEventPayload) VersionCode() string {
|
|||
return p.versionCode
|
||||
}
|
||||
|
||||
func (p PlayersSyncedEventPayload) NumPlayers() int {
|
||||
return p.numPlayers
|
||||
}
|
||||
|
||||
func (p PlayersSyncedEventPayload) NumActivePlayers() int {
|
||||
return p.numActivePlayers
|
||||
}
|
||||
|
||||
func (p PlayersSyncedEventPayload) NumInactivePlayers() int {
|
||||
return p.numPlayers - p.numActivePlayers
|
||||
}
|
||||
|
||||
type VillagesSyncedEventPayload struct {
|
||||
serverKey string
|
||||
serverURL *url.URL
|
||||
|
|
|
@ -58,38 +58,46 @@ func TestNewTribesSyncedEventPayload(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
server := domaintest.NewServer(t)
|
||||
numTribes := gofakeit.IntRange(0, math.MaxInt)
|
||||
numActiveTribes := gofakeit.IntRange(0, math.MaxInt)
|
||||
|
||||
payload, err := domain.NewTribesSyncedEventPayload(
|
||||
server.Key(),
|
||||
server.URL(),
|
||||
server.VersionCode(),
|
||||
numTribes,
|
||||
numActiveTribes,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, server.Key(), payload.ServerKey())
|
||||
assert.Equal(t, server.URL(), payload.ServerURL())
|
||||
assert.Equal(t, server.VersionCode(), payload.VersionCode())
|
||||
assert.Equal(t, numTribes, payload.NumTribes())
|
||||
assert.Equal(t, numActiveTribes, payload.NumActiveTribes())
|
||||
assert.Equal(t, numTribes-numActiveTribes, payload.NumInactiveTribes())
|
||||
}
|
||||
|
||||
func TestNewPlayersSyncedEventPayload(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
server := domaintest.NewServer(t)
|
||||
numPlayers := gofakeit.IntRange(0, math.MaxInt)
|
||||
numActivePlayers := gofakeit.IntRange(0, math.MaxInt)
|
||||
|
||||
payload, err := domain.NewPlayersSyncedEventPayload(
|
||||
server.Key(),
|
||||
server.URL(),
|
||||
server.VersionCode(),
|
||||
numPlayers,
|
||||
numActivePlayers,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, server.Key(), payload.ServerKey())
|
||||
assert.Equal(t, server.URL(), payload.ServerURL())
|
||||
assert.Equal(t, server.VersionCode(), payload.VersionCode())
|
||||
assert.Equal(t, numPlayers, payload.NumPlayers())
|
||||
assert.Equal(t, numActivePlayers, payload.NumActivePlayers())
|
||||
assert.Equal(t, numPlayers-numActivePlayers, payload.NumInactivePlayers())
|
||||
}
|
||||
|
||||
func TestNewVillagesSyncedEventPayload(t *testing.T) {
|
||||
|
|
|
@ -1180,6 +1180,37 @@ func (res ListPlayersWithRelationsResult) Next() PlayerCursor {
|
|||
return res.next
|
||||
}
|
||||
|
||||
type CountPlayersParams struct {
|
||||
serverKeys []string
|
||||
}
|
||||
|
||||
const countPlayersParamsModelName = "CountPlayersParams"
|
||||
|
||||
func NewCountPlayersParams() CountPlayersParams {
|
||||
return CountPlayersParams{}
|
||||
}
|
||||
|
||||
func (params *CountPlayersParams) ServerKeys() []string {
|
||||
return params.serverKeys
|
||||
}
|
||||
|
||||
func (params *CountPlayersParams) SetServerKeys(serverKeys []string) error {
|
||||
for i, sk := range serverKeys {
|
||||
if err := validateServerKey(sk); err != nil {
|
||||
return SliceElementValidationError{
|
||||
Model: countPlayersParamsModelName,
|
||||
Field: "serverKeys",
|
||||
Index: i,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.serverKeys = serverKeys
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type PlayerNotFoundError struct {
|
||||
ID int
|
||||
ServerKey string
|
||||
|
|
|
@ -1614,3 +1614,57 @@ func TestNewListPlayersWithRelationsResult(t *testing.T) {
|
|||
assert.True(t, res.Next().IsZero())
|
||||
})
|
||||
}
|
||||
|
||||
func TestCountPlayersParams_SetServerKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
serverKeys []string
|
||||
}
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
serverKeys: []string{
|
||||
domaintest.RandServerKey(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, serverKeyTest := range newServerKeyValidationTests() {
|
||||
tests = append(tests, test{
|
||||
name: serverKeyTest.name,
|
||||
args: args{
|
||||
serverKeys: []string{serverKeyTest.key},
|
||||
},
|
||||
expectedErr: domain.SliceElementValidationError{
|
||||
Model: "CountPlayersParams",
|
||||
Field: "serverKeys",
|
||||
Index: 0,
|
||||
Err: serverKeyTest.expectedErr,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewCountPlayersParams()
|
||||
|
||||
require.ErrorIs(t, params.SetServerKeys(tt.args.serverKeys), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.serverKeys, params.ServerKeys())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,12 @@ type Server struct {
|
|||
url *url.URL
|
||||
open bool
|
||||
special bool
|
||||
numPlayers int
|
||||
numActivePlayers int
|
||||
numInactivePlayers int
|
||||
numTribes int
|
||||
numActiveTribes int
|
||||
numInactiveTribes int
|
||||
numVillages int
|
||||
numPlayerVillages int
|
||||
numBarbarianVillages int
|
||||
|
@ -44,8 +48,12 @@ func UnmarshalServerFromDatabase(
|
|||
rawURL string,
|
||||
open bool,
|
||||
special bool,
|
||||
numPlayers int,
|
||||
numActivePlayers int,
|
||||
numInactivePlayers int,
|
||||
numTribes int,
|
||||
numActiveTribes int,
|
||||
numInactiveTribes int,
|
||||
numVillages int,
|
||||
numPlayerVillages int,
|
||||
numBarbarianVillages int,
|
||||
|
@ -88,11 +96,16 @@ func UnmarshalServerFromDatabase(
|
|||
|
||||
return Server{
|
||||
key: key,
|
||||
versionCode: versionCode,
|
||||
url: u,
|
||||
open: open,
|
||||
special: special,
|
||||
numPlayers: numPlayers,
|
||||
numActivePlayers: numActivePlayers,
|
||||
numInactivePlayers: numInactivePlayers,
|
||||
numTribes: numTribes,
|
||||
numActiveTribes: numActiveTribes,
|
||||
numInactiveTribes: numInactiveTribes,
|
||||
numVillages: numVillages,
|
||||
numPlayerVillages: numPlayerVillages,
|
||||
numBarbarianVillages: numBarbarianVillages,
|
||||
|
@ -107,7 +120,6 @@ func UnmarshalServerFromDatabase(
|
|||
tribeSnapshotsCreatedAt: tribeSnapshotsCreatedAt,
|
||||
villageDataSyncedAt: villageDataSyncedAt,
|
||||
ennoblementDataSyncedAt: ennoblementDataSyncedAt,
|
||||
versionCode: versionCode,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -131,14 +143,30 @@ func (s Server) Special() bool {
|
|||
return s.special
|
||||
}
|
||||
|
||||
func (s Server) NumPlayers() int {
|
||||
return s.numPlayers
|
||||
}
|
||||
|
||||
func (s Server) NumActivePlayers() int {
|
||||
return s.numActivePlayers
|
||||
}
|
||||
|
||||
func (s Server) NumInactivePlayers() int {
|
||||
return s.numInactivePlayers
|
||||
}
|
||||
|
||||
func (s Server) NumTribes() int {
|
||||
return s.numTribes
|
||||
}
|
||||
|
||||
func (s Server) NumActiveTribes() int {
|
||||
return s.numActiveTribes
|
||||
}
|
||||
|
||||
func (s Server) NumInactiveTribes() int {
|
||||
return s.numInactiveTribes
|
||||
}
|
||||
|
||||
func (s Server) NumVillages() int {
|
||||
return s.numVillages
|
||||
}
|
||||
|
@ -377,9 +405,13 @@ type UpdateServerParams struct {
|
|||
config NullServerConfig
|
||||
buildingInfo NullBuildingInfo
|
||||
unitInfo NullUnitInfo
|
||||
numTribes NullInt
|
||||
numActiveTribes NullInt
|
||||
numInactiveTribes NullInt
|
||||
tribeDataSyncedAt NullTime
|
||||
numPlayers NullInt
|
||||
numActivePlayers NullInt
|
||||
numInactivePlayers NullInt
|
||||
playerDataSyncedAt NullTime
|
||||
numVillages NullInt
|
||||
numPlayerVillages NullInt
|
||||
|
@ -420,6 +452,26 @@ func (params *UpdateServerParams) SetUnitInfo(unitInfo NullUnitInfo) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) NumTribes() NullInt {
|
||||
return params.numTribes
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) SetNumTribes(num NullInt) error {
|
||||
if num.Valid {
|
||||
if err := validateIntInRange(num.V, 0, math.MaxInt); err != nil {
|
||||
return ValidationError{
|
||||
Model: updateServerParamsModelName,
|
||||
Field: "numTribes",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.numTribes = num
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) NumActiveTribes() NullInt {
|
||||
return params.numActiveTribes
|
||||
}
|
||||
|
@ -440,6 +492,26 @@ func (params *UpdateServerParams) SetNumActiveTribes(num NullInt) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) NumInactiveTribes() NullInt {
|
||||
return params.numInactiveTribes
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) SetNumInactiveTribes(num NullInt) error {
|
||||
if num.Valid {
|
||||
if err := validateIntInRange(num.V, 0, math.MaxInt); err != nil {
|
||||
return ValidationError{
|
||||
Model: updateServerParamsModelName,
|
||||
Field: "numInactiveTribes",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.numInactiveTribes = num
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) TribeDataSyncedAt() NullTime {
|
||||
return params.tribeDataSyncedAt
|
||||
}
|
||||
|
@ -449,6 +521,26 @@ func (params *UpdateServerParams) SetTribeDataSyncedAt(tribeDataSyncedAt NullTim
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) NumPlayers() NullInt {
|
||||
return params.numPlayers
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) SetNumPlayers(num NullInt) error {
|
||||
if num.Valid {
|
||||
if err := validateIntInRange(num.V, 0, math.MaxInt); err != nil {
|
||||
return ValidationError{
|
||||
Model: updateServerParamsModelName,
|
||||
Field: "numPlayers",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.numPlayers = num
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) NumActivePlayers() NullInt {
|
||||
return params.numActivePlayers
|
||||
}
|
||||
|
@ -469,6 +561,26 @@ func (params *UpdateServerParams) SetNumActivePlayers(num NullInt) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) NumInactivePlayers() NullInt {
|
||||
return params.numInactivePlayers
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) SetNumInactivePlayers(num NullInt) error {
|
||||
if num.Valid {
|
||||
if err := validateIntInRange(num.V, 0, math.MaxInt); err != nil {
|
||||
return ValidationError{
|
||||
Model: updateServerParamsModelName,
|
||||
Field: "numInactivePlayers",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.numInactivePlayers = num
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (params *UpdateServerParams) PlayerDataSyncedAt() NullTime {
|
||||
return params.playerDataSyncedAt
|
||||
}
|
||||
|
|
|
@ -161,6 +161,69 @@ func TestNewCreateServerParams(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumTribes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
numTribes domain.NullInt
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
numTribes: domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: null value",
|
||||
args: args{
|
||||
numTribes: domain.NullInt{
|
||||
Valid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: numTribes < 0",
|
||||
args: args{
|
||||
numTribes: domain.NullInt{
|
||||
V: -1,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "UpdateServerParams",
|
||||
Field: "numTribes",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var params domain.UpdateServerParams
|
||||
|
||||
require.ErrorIs(t, params.SetNumTribes(tt.args.numTribes), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.numTribes, params.NumTribes())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumActiveTribes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -224,6 +287,132 @@ func TestUpdateServerParams_SetNumActiveTribes(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumInactiveTribes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
numInactiveTribes domain.NullInt
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
numInactiveTribes: domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: null value",
|
||||
args: args{
|
||||
numInactiveTribes: domain.NullInt{
|
||||
Valid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: numInactiveTribes < 0",
|
||||
args: args{
|
||||
numInactiveTribes: domain.NullInt{
|
||||
V: -1,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "UpdateServerParams",
|
||||
Field: "numInactiveTribes",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var params domain.UpdateServerParams
|
||||
|
||||
require.ErrorIs(t, params.SetNumInactiveTribes(tt.args.numInactiveTribes), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.numInactiveTribes, params.NumInactiveTribes())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumPlayers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
numPlayers domain.NullInt
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
numPlayers: domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: null value",
|
||||
args: args{
|
||||
numPlayers: domain.NullInt{
|
||||
Valid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: numPlayers < 0",
|
||||
args: args{
|
||||
numPlayers: domain.NullInt{
|
||||
V: -1,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "UpdateServerParams",
|
||||
Field: "numPlayers",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var params domain.UpdateServerParams
|
||||
|
||||
require.ErrorIs(t, params.SetNumPlayers(tt.args.numPlayers), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.numPlayers, params.NumPlayers())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumActivePlayers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -287,6 +476,69 @@ func TestUpdateServerParams_SetNumActivePlayers(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumInactivePlayers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
numInactivePlayers domain.NullInt
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
numInactivePlayers: domain.NullInt{
|
||||
V: gofakeit.IntRange(0, math.MaxInt),
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OK: null value",
|
||||
args: args{
|
||||
numInactivePlayers: domain.NullInt{
|
||||
Valid: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ERR: numInactivePlayers < 0",
|
||||
args: args{
|
||||
numInactivePlayers: domain.NullInt{
|
||||
V: -1,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
expectedErr: domain.ValidationError{
|
||||
Model: "UpdateServerParams",
|
||||
Field: "numInactivePlayers",
|
||||
Err: domain.MinGreaterEqualError{
|
||||
Min: 0,
|
||||
Current: -1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var params domain.UpdateServerParams
|
||||
|
||||
require.ErrorIs(t, params.SetNumInactivePlayers(tt.args.numInactivePlayers), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.numInactivePlayers, params.NumInactivePlayers())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateServerParams_SetNumVillages(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -969,6 +969,37 @@ func (res ListTribesResult) Next() TribeCursor {
|
|||
return res.next
|
||||
}
|
||||
|
||||
type CountTribesParams struct {
|
||||
serverKeys []string
|
||||
}
|
||||
|
||||
const countTribesParamsModelName = "CountTribesParams"
|
||||
|
||||
func NewCountTribesParams() CountTribesParams {
|
||||
return CountTribesParams{}
|
||||
}
|
||||
|
||||
func (params *CountTribesParams) ServerKeys() []string {
|
||||
return params.serverKeys
|
||||
}
|
||||
|
||||
func (params *CountTribesParams) SetServerKeys(serverKeys []string) error {
|
||||
for i, sk := range serverKeys {
|
||||
if err := validateServerKey(sk); err != nil {
|
||||
return SliceElementValidationError{
|
||||
Model: countTribesParamsModelName,
|
||||
Field: "serverKeys",
|
||||
Index: i,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.serverKeys = serverKeys
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type TribeNotFoundError struct {
|
||||
ID int
|
||||
ServerKey string
|
||||
|
|
|
@ -1205,3 +1205,57 @@ func TestNewListTribesResult(t *testing.T) {
|
|||
assert.True(t, res.Next().IsZero())
|
||||
})
|
||||
}
|
||||
|
||||
func TestCountTribesParams_SetServerKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type args struct {
|
||||
serverKeys []string
|
||||
}
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
expectedErr error
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "OK",
|
||||
args: args{
|
||||
serverKeys: []string{
|
||||
domaintest.RandServerKey(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, serverKeyTest := range newServerKeyValidationTests() {
|
||||
tests = append(tests, test{
|
||||
name: serverKeyTest.name,
|
||||
args: args{
|
||||
serverKeys: []string{serverKeyTest.key},
|
||||
},
|
||||
expectedErr: domain.SliceElementValidationError{
|
||||
Model: "CountTribesParams",
|
||||
Field: "serverKeys",
|
||||
Index: 0,
|
||||
Err: serverKeyTest.expectedErr,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
params := domain.NewCountTribesParams()
|
||||
|
||||
require.ErrorIs(t, params.SetServerKeys(tt.args.serverKeys), tt.expectedErr)
|
||||
if tt.expectedErr != nil {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, tt.args.serverKeys, params.ServerKeys())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,8 +248,12 @@ func TestDataSync(t *testing.T) {
|
|||
assert.Equal(collect, expected["URL"], actual.URL().String(), msg)
|
||||
assert.Equal(collect, expected["Open"], actual.Open(), msg)
|
||||
assert.Equal(collect, expected["VersionCode"], actual.VersionCode(), msg)
|
||||
assert.EqualValues(collect, expected["NumPlayers"], actual.NumPlayers(), msg)
|
||||
assert.EqualValues(collect, expected["NumActivePlayers"], actual.NumActivePlayers(), msg)
|
||||
assert.EqualValues(collect, expected["NumInactivePlayers"], actual.NumInactivePlayers(), msg)
|
||||
assert.EqualValues(collect, expected["NumTribes"], actual.NumTribes(), msg)
|
||||
assert.EqualValues(collect, expected["NumActiveTribes"], actual.NumActiveTribes(), msg)
|
||||
assert.EqualValues(collect, expected["NumInactiveTribes"], actual.NumInactiveTribes(), msg)
|
||||
assert.EqualValues(collect, expected["NumVillages"], actual.NumVillages(), msg)
|
||||
assert.EqualValues(collect, expected["NumPlayerVillages"], actual.NumPlayerVillages(), msg)
|
||||
assert.EqualValues(collect, expected["NumBonusVillages"], actual.NumBonusVillages(), msg)
|
||||
|
@ -257,8 +261,7 @@ func TestDataSync(t *testing.T) {
|
|||
collect,
|
||||
expected["NumBarbarianVillages"],
|
||||
actual.NumBarbarianVillages(),
|
||||
"Key=%s",
|
||||
expected["Key"],
|
||||
msg,
|
||||
)
|
||||
assert.WithinDuration(collect, time.Now(), actual.PlayerDataSyncedAt(), time.Minute, msg)
|
||||
assert.WithinDuration(collect, time.Now(), actual.TribeDataSyncedAt(), time.Minute, msg)
|
||||
|
@ -267,8 +270,7 @@ func TestDataSync(t *testing.T) {
|
|||
collect,
|
||||
string(marshalJSON(collect, expected["Config"])),
|
||||
string(marshalJSON(collect, serverConfigToMap(actual.Config()))),
|
||||
"Key=%s",
|
||||
expected["Key"],
|
||||
msg,
|
||||
)
|
||||
assert.JSONEq(
|
||||
collect,
|
||||
|
|
|
@ -155,6 +155,7 @@ func (c *ServerWatermillConsumer) updateNumTribes(msg *message.Message) error {
|
|||
rawPayload.ServerKey,
|
||||
rawPayload.ServerURL,
|
||||
rawPayload.VersionCode,
|
||||
rawPayload.NumTribes,
|
||||
rawPayload.NumActiveTribes,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -181,6 +182,7 @@ func (c *ServerWatermillConsumer) updateNumPlayers(msg *message.Message) error {
|
|||
rawPayload.ServerKey,
|
||||
rawPayload.ServerURL,
|
||||
rawPayload.VersionCode,
|
||||
rawPayload.NumPlayers,
|
||||
rawPayload.NumActivePlayers,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
@ -6,13 +6,17 @@ import (
|
|||
|
||||
func NewServer(s domain.Server) Server {
|
||||
converted := Server{
|
||||
Key: s.Key(),
|
||||
CreatedAt: s.CreatedAt(),
|
||||
NumBarbarianVillages: s.NumBarbarianVillages(),
|
||||
NumBonusVillages: s.NumBonusVillages(),
|
||||
NumPlayerVillages: s.NumPlayerVillages(),
|
||||
Key: s.Key(),
|
||||
NumActivePlayers: s.NumActivePlayers(),
|
||||
NumActiveTribes: s.NumActiveTribes(),
|
||||
NumBarbarianVillages: s.NumBarbarianVillages(),
|
||||
NumBonusVillages: s.NumBonusVillages(),
|
||||
NumInactivePlayers: s.NumInactivePlayers(),
|
||||
NumInactiveTribes: s.NumInactiveTribes(),
|
||||
NumPlayerVillages: s.NumPlayerVillages(),
|
||||
NumPlayers: s.NumPlayers(),
|
||||
NumTribes: s.NumTribes(),
|
||||
NumVillages: s.NumVillages(),
|
||||
Open: s.Open(),
|
||||
Url: s.URL().String(),
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -6,5 +6,6 @@ type PlayersSyncedEventPayload struct {
|
|||
ServerKey string `json:"serverKey"`
|
||||
ServerURL *url.URL `json:"serverUrl"`
|
||||
VersionCode string `json:"versionCode"`
|
||||
NumPlayers int `json:"numPlayers"`
|
||||
NumActivePlayers int `json:"numActivePlayers"`
|
||||
}
|
||||
|
|
|
@ -6,5 +6,6 @@ type TribesSyncedEventPayload struct {
|
|||
ServerKey string `json:"serverKey"`
|
||||
ServerURL *url.URL `json:"serverUrl"`
|
||||
VersionCode string `json:"versionCode"`
|
||||
NumTribes int `json:"numTribes"`
|
||||
NumActiveTribes int `json:"numActiveTribes"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue