feat: api - extend player schema (#8)
ci/woodpecker/push/govulncheck Pipeline was successful Details
ci/woodpecker/push/test Pipeline was successful Details

Reviewed-on: twhelp/corev3#8
This commit is contained in:
Dawid Wysokiński 2024-02-28 06:59:10 +00:00
parent bc3f61ec86
commit 0be010ab50
41 changed files with 538 additions and 144 deletions

View File

@ -941,6 +941,23 @@ components:
deletedAt:
type: string
format: date-time
TribeMeta:
type: object
required:
- id
- name
- tag
- profileUrl
properties:
id:
type: integer
name:
type: string
tag:
type: string
profileUrl:
type: string
format: uri
PlayerOpponentsDefeated:
allOf:
- $ref: "#/components/schemas/TribeOpponentsDefeated"
@ -985,6 +1002,8 @@ components:
profileUrl:
type: string
format: uri
tribe:
$ref: "#/components/schemas/TribeMeta"
lastActivityAt:
type: string
format: date-time
@ -1140,7 +1159,7 @@ components:
required: true
schema:
type: integer
minimum: 0
minimum: 1
responses:
ListVersionsResponse:
description: ""

View File

@ -110,6 +110,30 @@ func (repo *PlayerBunRepository) List(
return domain.NewListPlayersResult(separateListResultAndNext(converted, params.Limit()))
}
func (repo *PlayerBunRepository) ListWithRelations(
ctx context.Context,
params domain.ListPlayersParams,
) (domain.ListPlayersWithRelationsResult, error) {
var players bunmodel.Players
if err := repo.db.NewSelect().
Model(&players).
Apply(listPlayersParamsApplier{params: params}.apply).
Relation("Tribe", func(q *bun.SelectQuery) *bun.SelectQuery {
return q.Column(bunmodel.TribeMetaColumns...)
}).
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
return domain.ListPlayersWithRelationsResult{}, fmt.Errorf("couldn't select players from the db: %w", err)
}
converted, err := players.ToDomainWithRelations()
if err != nil {
return domain.ListPlayersWithRelationsResult{}, err
}
return domain.NewListPlayersWithRelationsResult(separateListResultAndNext(converted, params.Limit()))
}
func (repo *PlayerBunRepository) Delete(ctx context.Context, serverKey string, ids ...int) error {
if len(ids) == 0 {
return nil
@ -145,7 +169,7 @@ func (a listPlayersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
}
if deleted := a.params.Deleted(); deleted.Valid {
if deleted.Value {
if deleted.V {
q = q.Where("player.deleted_at IS NOT NULL")
} else {
q = q.Where("player.deleted_at IS NULL")

View File

@ -115,67 +115,67 @@ type updateServerParamsApplier struct {
//nolint:gocyclo
func (a updateServerParamsApplier) apply(q *bun.UpdateQuery) *bun.UpdateQuery {
if config := a.params.Config(); config.Valid {
q = q.Set("config = ?", bunmodel.NewServerConfig(config.Value))
q = q.Set("config = ?", bunmodel.NewServerConfig(config.V))
}
if unitInfo := a.params.UnitInfo(); unitInfo.Valid {
q = q.Set("unit_info = ?", bunmodel.NewUnitInfo(unitInfo.Value))
q = q.Set("unit_info = ?", bunmodel.NewUnitInfo(unitInfo.V))
}
if buildingInfo := a.params.BuildingInfo(); buildingInfo.Valid {
q = q.Set("building_info = ?", bunmodel.NewBuildingInfo(buildingInfo.Value))
q = q.Set("building_info = ?", bunmodel.NewBuildingInfo(buildingInfo.V))
}
if numTribes := a.params.NumTribes(); numTribes.Valid {
q = q.Set("num_tribes = ?", numTribes.Value)
q = q.Set("num_tribes = ?", numTribes.V)
}
if tribeDataSyncedAt := a.params.TribeDataSyncedAt(); tribeDataSyncedAt.Valid {
// TODO: rename this column to tribe_data_synced_at
q = q.Set("tribe_data_updated_at = ?", tribeDataSyncedAt.Value)
q = q.Set("tribe_data_updated_at = ?", tribeDataSyncedAt.V)
}
if numPlayers := a.params.NumPlayers(); numPlayers.Valid {
q = q.Set("num_players = ?", numPlayers.Value)
q = q.Set("num_players = ?", numPlayers.V)
}
if playerDataSyncedAt := a.params.PlayerDataSyncedAt(); playerDataSyncedAt.Valid {
// TODO: rename this column to player_data_synced_at
q = q.Set("player_data_updated_at = ?", playerDataSyncedAt.Value)
q = q.Set("player_data_updated_at = ?", playerDataSyncedAt.V)
}
if numVillages := a.params.NumVillages(); numVillages.Valid {
q = q.Set("num_villages = ?", numVillages.Value)
q = q.Set("num_villages = ?", numVillages.V)
}
if numPlayerVillages := a.params.NumPlayerVillages(); numPlayerVillages.Valid {
q = q.Set("num_player_villages = ?", numPlayerVillages.Value)
q = q.Set("num_player_villages = ?", numPlayerVillages.V)
}
if numBarbarianVillages := a.params.NumBarbarianVillages(); numBarbarianVillages.Valid {
q = q.Set("num_barbarian_villages = ?", numBarbarianVillages.Value)
q = q.Set("num_barbarian_villages = ?", numBarbarianVillages.V)
}
if numBonusVillages := a.params.NumBonusVillages(); numBonusVillages.Valid {
q = q.Set("num_bonus_villages = ?", numBonusVillages.Value)
q = q.Set("num_bonus_villages = ?", numBonusVillages.V)
}
if villageDataSyncedAt := a.params.VillageDataSyncedAt(); villageDataSyncedAt.Valid {
// TODO: rename this column to village_data_synced_at
q = q.Set("village_data_updated_at = ?", villageDataSyncedAt.Value)
q = q.Set("village_data_updated_at = ?", villageDataSyncedAt.V)
}
if ennoblementDataSyncedAt := a.params.EnnoblementDataSyncedAt(); ennoblementDataSyncedAt.Valid {
// TODO: rename this column to ennoblement_data_synced_at
q = q.Set("ennoblement_data_updated_at = ?", ennoblementDataSyncedAt.Value)
q = q.Set("ennoblement_data_updated_at = ?", ennoblementDataSyncedAt.V)
}
if tribeSnapshotsCreatedAt := a.params.TribeSnapshotsCreatedAt(); tribeSnapshotsCreatedAt.Valid {
q = q.Set("tribe_snapshots_created_at = ?", tribeSnapshotsCreatedAt.Value)
q = q.Set("tribe_snapshots_created_at = ?", tribeSnapshotsCreatedAt.V)
}
if playerSnapshotsCreatedAt := a.params.PlayerSnapshotsCreatedAt(); playerSnapshotsCreatedAt.Valid {
q = q.Set("player_snapshots_created_at = ?", playerSnapshotsCreatedAt.Value)
q = q.Set("player_snapshots_created_at = ?", playerSnapshotsCreatedAt.V)
}
return q
@ -196,24 +196,24 @@ func (a listServersParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
}
if open := a.params.Open(); open.Valid {
q = q.Where("server.open = ?", open.Value)
q = q.Where("server.open = ?", open.V)
}
if special := a.params.Special(); special.Valid {
q = q.Where("server.special = ?", special.Value)
q = q.Where("server.special = ?", special.V)
}
if tribeSnapshotsCreatedAtLT := a.params.TribeSnapshotsCreatedAtLT(); tribeSnapshotsCreatedAtLT.Valid {
q = q.Where(
"server.tribe_snapshots_created_at < ? OR server.tribe_snapshots_created_at is null",
tribeSnapshotsCreatedAtLT.Value,
tribeSnapshotsCreatedAtLT.V,
)
}
if playerSnapshotsCreatedAtLT := a.params.PlayerSnapshotsCreatedAtLT(); playerSnapshotsCreatedAtLT.Valid {
q = q.Where(
"server.player_snapshots_created_at < ? OR server.player_snapshots_created_at is null",
playerSnapshotsCreatedAtLT.Value,
playerSnapshotsCreatedAtLT.V,
)
}

View File

@ -117,10 +117,6 @@ func (repo *TribeBunRepository) List(
) (domain.ListTribesResult, error) {
var tribes bunmodel.Tribes
fmt.Println(repo.db.NewSelect().
Model(&tribes).
Apply(listTribesParamsApplier{params: params}.apply).String())
if err := repo.db.NewSelect().
Model(&tribes).
Apply(listTribesParamsApplier{params: params}.apply).
@ -174,7 +170,7 @@ func (a listTribesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
}
if deleted := a.params.Deleted(); deleted.Valid {
if deleted.Value {
if deleted.V {
q = q.Where("tribe.deleted_at IS NOT NULL")
} else {
q = q.Where("tribe.deleted_at IS NULL")

View File

@ -117,7 +117,7 @@ func (a listVillagesParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery {
}
if idGT := a.params.IDGT(); idGT.Valid {
q = q.Where("village.id > ?", idGT.Value)
q = q.Where("village.id > ?", idGT.V)
}
if serverKeys := a.params.ServerKeys(); len(serverKeys) > 0 {

View File

@ -85,7 +85,7 @@ func testPlayerSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repo
listPlayersParams := domain.NewListPlayersParams()
require.NoError(t, listPlayersParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(t, listPlayersParams.SetLimit(domain.PlayerSnapshotListMaxLimit/2))

View File

@ -100,7 +100,7 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
})
})
t.Run("List", func(t *testing.T) {
t.Run("List & ListWithRelations", func(t *testing.T) {
t.Parallel()
repos := newRepos(t)
@ -374,7 +374,7 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
t.Helper()
params := domain.NewListPlayersParams()
require.NoError(t, params.SetDeleted(domain.NullBool{
Value: true,
V: true,
Valid: true,
}))
return params
@ -398,7 +398,7 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
t.Helper()
params := domain.NewListPlayersParams()
require.NoError(t, params.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
return params
@ -567,6 +567,15 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
res, err := repos.player.List(ctx, params)
tt.assertError(t, err)
tt.assertResult(t, params, res)
resWithRelations, err := repos.player.ListWithRelations(ctx, params)
tt.assertError(t, err)
require.Len(t, resWithRelations.Players(), len(res.Players()))
for i, p := range resWithRelations.Players() {
assert.Equal(t, res.Players()[i], p.Player())
assert.Equal(t, p.Player().TribeID(), p.Tribe().V.ID())
assert.Equal(t, p.Player().TribeID() != 0, p.Tribe().Valid)
}
})
}
})
@ -577,7 +586,7 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
repos := newRepos(t)
listServersParams := domain.NewListServersParams()
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{Value: false, Valid: true}))
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{V: false, Valid: true}))
listServersRes, listServersErr := repos.server.List(ctx, listServersParams)
require.NoError(t, listServersErr)
require.NotEmpty(t, listServersRes)
@ -591,7 +600,7 @@ func testPlayerRepository(t *testing.T, newRepos func(t *testing.T) repositories
}
listPlayersParams := domain.NewListPlayersParams()
require.NoError(t, listPlayersParams.SetDeleted(domain.NullBool{Value: false, Valid: true}))
require.NoError(t, listPlayersParams.SetDeleted(domain.NullBool{V: false, Valid: true}))
require.NoError(t, listPlayersParams.SetServerKeys(serverKeys))
res, err := repos.player.List(ctx, listPlayersParams)

View File

@ -267,7 +267,7 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
t.Helper()
params := domain.NewListServersParams()
require.NoError(t, params.SetSpecial(domain.NullBool{
Value: true,
V: true,
Valid: true,
}))
return params
@ -291,7 +291,7 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
t.Helper()
params := domain.NewListServersParams()
require.NoError(t, params.SetOpen(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
return params
@ -315,7 +315,7 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
t.Helper()
params := domain.NewListServersParams()
require.NoError(t, params.SetPlayerSnapshotsCreatedAtLT(domain.NullTime{
Value: snapshotsCreatedAtLT,
V: snapshotsCreatedAtLT,
Valid: true,
}))
return params
@ -339,7 +339,7 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
t.Helper()
params := domain.NewListServersParams()
require.NoError(t, params.SetTribeSnapshotsCreatedAtLT(domain.NullTime{
Value: snapshotsCreatedAtLT,
V: snapshotsCreatedAtLT,
Valid: true,
}))
return params
@ -528,63 +528,63 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
var updateParams domain.UpdateServerParams
require.NoError(t, updateParams.SetConfig(domain.NullServerConfig{
Value: domaintest.NewServerConfig(t),
V: domaintest.NewServerConfig(t),
Valid: true,
}))
require.NoError(t, updateParams.SetUnitInfo(domain.NullUnitInfo{
Value: domaintest.NewUnitInfo(t),
V: domaintest.NewUnitInfo(t),
Valid: true,
}))
require.NoError(t, updateParams.SetBuildingInfo(domain.NullBuildingInfo{
Value: domaintest.NewBuildingInfo(t),
V: domaintest.NewBuildingInfo(t),
Valid: true,
}))
require.NoError(t, updateParams.SetNumTribes(domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
}))
require.NoError(t, updateParams.SetTribeDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}))
require.NoError(t, updateParams.SetNumPlayers(domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
}))
require.NoError(t, updateParams.SetPlayerDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}))
require.NoError(t, updateParams.SetNumVillages(domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
}))
require.NoError(t, updateParams.SetNumPlayerVillages(domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
}))
require.NoError(t, updateParams.SetNumBonusVillages(domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
}))
require.NoError(t, updateParams.SetNumBarbarianVillages(domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
}))
require.NoError(t, updateParams.SetVillageDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}))
require.NoError(t, updateParams.SetEnnoblementDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}))
require.NoError(t, updateParams.SetTribeSnapshotsCreatedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}))
require.NoError(t, updateParams.SetPlayerSnapshotsCreatedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}))
@ -598,48 +598,48 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
require.NoError(t, err)
require.NotEmpty(t, serversAfterUpdate)
serverAfterUpdate := serversAfterUpdate.Servers()[0]
assert.Equal(t, updateParams.Config().Value, serverAfterUpdate.Config())
assert.Equal(t, updateParams.UnitInfo().Value, serverAfterUpdate.UnitInfo())
assert.Equal(t, updateParams.BuildingInfo().Value, serverAfterUpdate.BuildingInfo())
assert.Equal(t, updateParams.NumTribes().Value, serverAfterUpdate.NumTribes())
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.WithinDuration(
t,
updateParams.TribeDataSyncedAt().Value,
updateParams.TribeDataSyncedAt().V,
serverAfterUpdate.TribeDataSyncedAt(),
time.Minute,
)
assert.Equal(t, updateParams.NumPlayers().Value, serverAfterUpdate.NumPlayers())
assert.Equal(t, updateParams.NumPlayers().V, serverAfterUpdate.NumPlayers())
assert.WithinDuration(
t,
updateParams.PlayerDataSyncedAt().Value,
updateParams.PlayerDataSyncedAt().V,
serverAfterUpdate.PlayerDataSyncedAt(),
time.Minute,
)
assert.Equal(t, updateParams.NumVillages().Value, serverAfterUpdate.NumVillages())
assert.Equal(t, updateParams.NumPlayerVillages().Value, serverAfterUpdate.NumPlayerVillages())
assert.Equal(t, updateParams.NumBarbarianVillages().Value, serverAfterUpdate.NumBarbarianVillages())
assert.Equal(t, updateParams.NumBonusVillages().Value, serverAfterUpdate.NumBonusVillages())
assert.Equal(t, updateParams.NumVillages().V, serverAfterUpdate.NumVillages())
assert.Equal(t, updateParams.NumPlayerVillages().V, serverAfterUpdate.NumPlayerVillages())
assert.Equal(t, updateParams.NumBarbarianVillages().V, serverAfterUpdate.NumBarbarianVillages())
assert.Equal(t, updateParams.NumBonusVillages().V, serverAfterUpdate.NumBonusVillages())
assert.WithinDuration(
t,
updateParams.VillageDataSyncedAt().Value,
updateParams.VillageDataSyncedAt().V,
serverAfterUpdate.VillageDataSyncedAt(),
time.Minute,
)
assert.WithinDuration(
t,
updateParams.EnnoblementDataSyncedAt().Value,
updateParams.EnnoblementDataSyncedAt().V,
serverAfterUpdate.EnnoblementDataSyncedAt(),
time.Minute,
)
assert.WithinDuration(
t,
updateParams.TribeSnapshotsCreatedAt().Value,
updateParams.TribeSnapshotsCreatedAt().V,
serverAfterUpdate.TribeSnapshotsCreatedAt(),
time.Minute,
)
assert.WithinDuration(
t,
updateParams.PlayerSnapshotsCreatedAt().Value,
updateParams.PlayerSnapshotsCreatedAt().V,
serverAfterUpdate.PlayerSnapshotsCreatedAt(),
time.Minute,
)
@ -650,7 +650,7 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories
var updateParams domain.UpdateServerParams
require.NoError(t, updateParams.SetConfig(domain.NullServerConfig{
Value: domaintest.NewServerConfig(t),
V: domaintest.NewServerConfig(t),
Valid: true,
}))

View File

@ -31,6 +31,7 @@ type tribeRepository interface {
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)
Delete(ctx context.Context, serverKey string, ids ...int) error
}

View File

@ -87,7 +87,7 @@ func testTribeSnapshotRepository(t *testing.T, newRepos func(t *testing.T) repos
listTribesParams := domain.NewListTribesParams()
require.NoError(t, listTribesParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))

View File

@ -106,11 +106,11 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
listServersParams := domain.NewListServersParams()
require.NoError(t, listServersParams.SetOpen(domain.NullBool{
Value: true,
V: true,
Valid: true,
}))
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
@ -143,7 +143,7 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
listTribesParams := domain.NewListTribesParams()
require.NoError(t, listTribesParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(t, listTribesParams.SetServerKeys([]string{tt.serverKey}))
@ -501,7 +501,7 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
t.Helper()
params := domain.NewListTribesParams()
require.NoError(t, params.SetDeleted(domain.NullBool{
Value: true,
V: true,
Valid: true,
}))
return params
@ -525,7 +525,7 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
t.Helper()
params := domain.NewListTribesParams()
require.NoError(t, params.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
return params
@ -797,7 +797,7 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
repos := newRepos(t)
listServersParams := domain.NewListServersParams()
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{Value: false, Valid: true}))
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{V: false, Valid: true}))
listServersRes, listServersErr := repos.server.List(ctx, listServersParams)
require.NoError(t, listServersErr)
require.NotEmpty(t, listServersRes)
@ -811,7 +811,7 @@ func testTribeRepository(t *testing.T, newRepos func(t *testing.T) repositories)
}
listTribesParams := domain.NewListTribesParams()
require.NoError(t, listTribesParams.SetDeleted(domain.NullBool{Value: false, Valid: true}))
require.NoError(t, listTribesParams.SetDeleted(domain.NullBool{V: false, Valid: true}))
require.NoError(t, listTribesParams.SetServerKeys(serverKeys))
res, err := repos.tribe.List(ctx, listTribesParams)

View File

@ -196,7 +196,7 @@ func testVillageRepository(t *testing.T, newRepos func(t *testing.T) repositorie
t.Helper()
params := domain.NewListVillagesParams()
require.NoError(t, params.SetIDGT(domain.NullInt{
Value: randVillage.ID(),
V: randVillage.ID(),
Valid: true,
}))
return params
@ -205,7 +205,7 @@ func testVillageRepository(t *testing.T, newRepos func(t *testing.T) repositorie
t.Helper()
assert.NotEmpty(t, villages)
for _, v := range villages {
assert.Greater(t, v.ID(), params.IDGT().Value, v.ID())
assert.Greater(t, v.ID(), params.IDGT().V, v.ID())
}
},
assertError: func(t *testing.T, err error) {
@ -260,7 +260,7 @@ func testVillageRepository(t *testing.T, newRepos func(t *testing.T) repositorie
repos := newRepos(t)
listServersParams := domain.NewListServersParams()
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{Value: false, Valid: true}))
require.NoError(t, listServersParams.SetSpecial(domain.NullBool{V: false, Valid: true}))
listServersRes, listServersErr := repos.server.List(ctx, listServersParams)
require.NoError(t, listServersErr)
require.NotEmpty(t, listServersRes)

View File

@ -10,6 +10,7 @@ import (
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)
// Delete marks players with the given serverKey and ids as deleted (sets deleted at to now).
// In addition, Delete sets TribeID to null.
//
@ -134,7 +135,7 @@ func (svc *PlayerService) delete(ctx context.Context, serverKey string, players
return err
}
if err := listParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}); err != nil {
return err
@ -182,3 +183,10 @@ func (svc *PlayerService) delete(ctx context.Context, serverKey string, players
func (svc *PlayerService) List(ctx context.Context, params domain.ListPlayersParams) (domain.ListPlayersResult, error) {
return svc.repo.List(ctx, params)
}
func (svc *PlayerService) ListWithRelations(
ctx context.Context,
params domain.ListPlayersParams,
) (domain.ListPlayersWithRelationsResult, error) {
return svc.repo.ListWithRelations(ctx, params)
}

View File

@ -40,7 +40,7 @@ func (svc *PlayerSnapshotService) Create(
return fmt.Errorf("%s: %w", serverKey, err)
}
if err := listPlayersParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", serverKey, err)

View File

@ -76,7 +76,7 @@ func (svc *ServerService) listAllSpecial(ctx context.Context, versionCode string
return nil, err
}
if err := params.SetSpecial(domain.NullBool{
Value: true,
V: true,
Valid: true,
}); err != nil {
return nil, err
@ -91,7 +91,7 @@ func (svc *ServerService) ListAllOpen(ctx context.Context, versionCode string) (
return nil, err
}
if err := params.SetOpen(domain.NullBool{
Value: true,
V: true,
Valid: true,
}); err != nil {
return nil, err
@ -158,19 +158,19 @@ func (svc *ServerService) SyncConfigAndInfo(ctx context.Context, payload domain.
var updateParams domain.UpdateServerParams
if err = updateParams.SetConfig(domain.NullServerConfig{
Value: cfg,
V: cfg,
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err = updateParams.SetBuildingInfo(domain.NullBuildingInfo{
Value: buildingInfo,
V: buildingInfo,
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err = updateParams.SetUnitInfo(domain.NullUnitInfo{
Value: unitInfo,
V: unitInfo,
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -184,13 +184,13 @@ func (svc *ServerService) UpdateNumTribes(ctx context.Context, payload domain.Tr
var updateParams domain.UpdateServerParams
if err := updateParams.SetNumTribes(domain.NullInt{
Value: payload.NumTribes(),
V: payload.NumTribes(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err := updateParams.SetTribeDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -204,13 +204,13 @@ func (svc *ServerService) UpdateNumPlayers(ctx context.Context, payload domain.P
var updateParams domain.UpdateServerParams
if err := updateParams.SetNumPlayers(domain.NullInt{
Value: payload.NumPlayers(),
V: payload.NumPlayers(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err := updateParams.SetPlayerDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -224,31 +224,31 @@ func (svc *ServerService) UpdateNumVillages(ctx context.Context, payload domain.
var updateParams domain.UpdateServerParams
if err := updateParams.SetNumVillages(domain.NullInt{
Value: payload.NumVillages(),
V: payload.NumVillages(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err := updateParams.SetNumPlayerVillages(domain.NullInt{
Value: payload.NumPlayerVillages(),
V: payload.NumPlayerVillages(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err := updateParams.SetNumBarbarianVillages(domain.NullInt{
Value: payload.NumBarbarianVillages(),
V: payload.NumBarbarianVillages(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err := updateParams.SetNumBonusVillages(domain.NullInt{
Value: payload.NumBonusVillages(),
V: payload.NumBonusVillages(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
}
if err := updateParams.SetVillageDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -265,7 +265,7 @@ func (svc *ServerService) UpdateEnnoblementDataSyncedAt(
var updateParams domain.UpdateServerParams
if err := updateParams.SetEnnoblementDataSyncedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -282,7 +282,7 @@ func (svc *ServerService) UpdateTribeSnapshotsCreatedAt(
var updateParams domain.UpdateServerParams
if err := updateParams.SetTribeSnapshotsCreatedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -299,7 +299,7 @@ func (svc *ServerService) UpdatePlayerSnapshotsCreatedAt(
var updateParams domain.UpdateServerParams
if err := updateParams.SetPlayerSnapshotsCreatedAt(domain.NullTime{
Value: time.Now(),
V: time.Now(),
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", key, err)
@ -320,7 +320,7 @@ func (svc *ServerService) GetNormalByVersionCodeAndServerKey(
return domain.Server{}, err
}
if err := params.SetSpecial(domain.NullBool{
Value: false,
V: false,
Valid: true,
}); err != nil {
return domain.Server{}, err

View File

@ -70,13 +70,13 @@ func (svc *SnapshotService) publishTribe(
return err
}
if err := params.SetOpen(domain.NullBool{
Value: true,
V: true,
Valid: true,
}); err != nil {
return err
}
if err := params.SetTribeSnapshotsCreatedAtLT(domain.NullTime{
Value: snapshotsCreatedAtLT,
V: snapshotsCreatedAtLT,
Valid: true,
}); err != nil {
return err
@ -106,13 +106,13 @@ func (svc *SnapshotService) publishPlayer(
return err
}
if err := params.SetOpen(domain.NullBool{
Value: true,
V: true,
Valid: true,
}); err != nil {
return err
}
if err := params.SetPlayerSnapshotsCreatedAtLT(domain.NullTime{
Value: snapshotsCreatedAtLT,
V: snapshotsCreatedAtLT,
Valid: true,
}); err != nil {
return err

View File

@ -117,7 +117,7 @@ func (svc *TribeService) delete(ctx context.Context, serverKey string, tribes do
return err
}
if err := listParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}); err != nil {
return err

View File

@ -40,7 +40,7 @@ func (svc *TribeSnapshotService) Create(
return fmt.Errorf("%s: %w", serverKey, err)
}
if err := listTribesParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}); err != nil {
return fmt.Errorf("%s: %w", serverKey, err)

View File

@ -106,7 +106,7 @@ func (svc *VillageService) delete(ctx context.Context, serverKey string, village
toDelete = append(toDelete, storedVillages.Delete(serverKey, villages)...)
if err = listParams.SetIDGT(domain.NullInt{
Value: storedVillages[len(storedVillages)-1].ID(),
V: storedVillages[len(storedVillages)-1].ID(),
Valid: true,
}); err != nil {
return err

View File

@ -93,3 +93,29 @@ func (ps Players) ToDomain() (domain.Players, error) {
return res, nil
}
func (ps Players) ToDomainWithRelations() (domain.PlayersWithRelations, error) {
res := make(domain.PlayersWithRelations, 0, len(ps))
for _, p := range ps {
var err error
var tribe domain.NullTribeMeta
if p.Tribe.ID > 0 {
tribe.Valid = true
tribe.V, err = p.Tribe.ToMeta()
if err != nil {
return nil, err
}
}
converted, err := p.ToDomain()
if err != nil {
return nil, err
}
res = append(res, converted.WithRelations(tribe))
}
return res, nil
}

View File

@ -8,6 +8,8 @@ import (
"github.com/uptrace/bun"
)
var TribeMetaColumns = []string{"id", "name", "tag", "profile_url"}
type Tribe struct {
bun.BaseModel `bun:"table:tribes,alias:tribe"`
@ -34,6 +36,24 @@ type Tribe struct {
OpponentsDefeated
}
func (t Tribe) ToMeta() (domain.TribeMeta, error) {
converted, err := domain.UnmarshalTribeMetaFromDatabase(
t.ID,
t.Name,
t.Tag,
t.ProfileURL,
)
if err != nil {
return domain.TribeMeta{}, fmt.Errorf(
"couldn't construct domain.TribeMeta (id=%d,serverKey=%s): %w",
t.ID,
t.ServerKey,
err,
)
}
return converted, nil
}
func (t Tribe) ToDomain() (domain.Tribe, error) {
od, err := t.OpponentsDefeated.ToDomain()
if err != nil {

View File

@ -117,3 +117,35 @@ func NewPlayer(tb TestingTB, opts ...func(cfg *PlayerConfig)) domain.Player {
return p
}
type PlayerWithRelationsConfig struct {
TribeID int
}
func NewPlayerWithRelations(tb TestingTB, opts ...func(cfg *PlayerWithRelationsConfig)) domain.PlayerWithRelations {
tb.Helper()
cfg := &PlayerWithRelationsConfig{
TribeID: RandID(),
}
for _, opt := range opts {
opt(cfg)
}
p := NewPlayer(tb, func(playerCfg *PlayerConfig) {
playerCfg.TribeID = cfg.TribeID
})
var tribeMeta domain.TribeMeta
if p.TribeID() > 0 {
tribeMeta = NewTribeMeta(tb, func(cfg *TribeMetaConfig) {
cfg.ID = p.TribeID()
})
}
return p.WithRelations(domain.NullTribeMeta{
V: tribeMeta,
Valid: !tribeMeta.IsZero(),
})
}

View File

@ -120,3 +120,26 @@ func NewTribe(tb TestingTB, opts ...func(cfg *TribeConfig)) domain.Tribe {
return t
}
type TribeMetaConfig struct {
ID int
Tag string
}
func NewTribeMeta(tb TestingTB, opts ...func(cfg *TribeMetaConfig)) domain.TribeMeta {
tb.Helper()
cfg := &TribeMetaConfig{
ID: RandID(),
Tag: RandTribeTag(),
}
for _, opt := range opts {
opt(cfg)
}
return NewTribe(tb, func(tribeCfg *TribeConfig) {
tribeCfg.ID = cfg.ID
tribeCfg.Tag = cfg.Tag
}).Meta()
}

View File

@ -3,8 +3,8 @@ package domain
import "time"
type NullValue[T any] struct {
Value T
Valid bool // Valid is true if Value is not NULL
V T
Valid bool // Valid is true if V is not NULL
}
type NullInt = NullValue[int]

View File

@ -181,6 +181,13 @@ func (p Player) DeletedAt() time.Time {
return p.deletedAt
}
func (p Player) WithRelations(tribe NullTribeMeta) PlayerWithRelations {
return PlayerWithRelations{
player: p,
tribe: tribe,
}
}
func (p Player) Base() BasePlayer {
return BasePlayer{
id: p.id,
@ -241,6 +248,23 @@ func (ps Players) Delete(serverKey string, active BasePlayers) ([]int, []CreateT
return toDelete, params, nil
}
type PlayerWithRelations struct {
player Player
tribe NullTribeMeta
}
func (p PlayerWithRelations) Player() Player {
return p.player
}
func (p PlayerWithRelations) Tribe() NullTribeMeta {
return p.tribe
}
func (p PlayerWithRelations) IsZero() bool {
return p.player.IsZero() && p.tribe.IsZero()
}
type CreatePlayerParams struct {
base BasePlayer
serverKey string
@ -253,6 +277,8 @@ type CreatePlayerParams struct {
lastActivityAt time.Time
}
type PlayersWithRelations []PlayerWithRelations
const createPlayerParamsModelName = "CreatePlayerParams"
// NewCreatePlayerParams constructs a slice of CreatePlayerParams based on the given parameters.
@ -630,7 +656,7 @@ func (params *ListPlayersParams) IDs() []int {
func (params *ListPlayersParams) SetIDs(ids []int) error {
for i, id := range ids {
if err := validateIntInRange(id, 0, math.MaxInt); err != nil {
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
return SliceElementValidationError{
Model: listPlayersParamsModelName,
Field: "ids",
@ -821,3 +847,78 @@ func (res ListPlayersResult) Self() PlayerCursor {
func (res ListPlayersResult) Next() PlayerCursor {
return res.next
}
type ListPlayersWithRelationsResult struct {
players PlayersWithRelations
self PlayerCursor
next PlayerCursor
}
const listPlayersWithRelationsResultModelName = "ListPlayersWithRelationsResult"
func NewListPlayersWithRelationsResult(
players PlayersWithRelations,
next PlayerWithRelations,
) (ListPlayersWithRelationsResult, error) {
var err error
res := ListPlayersWithRelationsResult{
players: players,
}
if len(players) > 0 {
player := players[0].Player()
od := player.OD()
res.self, err = NewPlayerCursor(
player.ID(),
player.ServerKey(),
od.ScoreAtt(),
od.ScoreDef(),
od.ScoreTotal(),
player.Points(),
player.DeletedAt(),
)
if err != nil {
return ListPlayersWithRelationsResult{}, ValidationError{
Model: listPlayersWithRelationsResultModelName,
Field: "self",
Err: err,
}
}
}
if !next.IsZero() {
fmt.Println(next.IsZero())
player := next.Player()
od := player.OD()
res.next, err = NewPlayerCursor(
player.ID(),
player.ServerKey(),
od.ScoreAtt(),
od.ScoreDef(),
od.ScoreTotal(),
player.Points(),
player.DeletedAt(),
)
if err != nil {
return ListPlayersWithRelationsResult{}, ValidationError{
Model: listPlayersWithRelationsResultModelName,
Field: "next",
Err: err,
}
}
}
return res, nil
}
func (res ListPlayersWithRelationsResult) Players() PlayersWithRelations {
return res.players
}
func (res ListPlayersWithRelationsResult) Self() PlayerCursor {
return res.self
}
func (res ListPlayersWithRelationsResult) Next() PlayerCursor {
return res.next
}

View File

@ -437,13 +437,13 @@ func TestListPlayersParams_SetIDs(t *testing.T) {
},
},
{
name: "ERR: value < 0",
name: "ERR: value < 1",
args: args{
ids: []int{
domaintest.RandID(),
domaintest.RandID(),
domaintest.RandID(),
-1,
0,
domaintest.RandID(),
},
},
@ -452,8 +452,8 @@ func TestListPlayersParams_SetIDs(t *testing.T) {
Field: "ids",
Index: 3,
Err: domain.MinGreaterEqualError{
Min: 0,
Current: -1,
Min: 1,
Current: 0,
},
},
},
@ -910,3 +910,47 @@ func TestNewListPlayersResult(t *testing.T) {
assert.True(t, res.Next().IsZero())
})
}
func TestNewListPlayersWithRelationsResult(t *testing.T) {
t.Parallel()
players := domain.PlayersWithRelations{
domaintest.NewPlayerWithRelations(t),
domaintest.NewPlayerWithRelations(t),
domaintest.NewPlayerWithRelations(t),
}
next := domaintest.NewPlayerWithRelations(t)
t.Run("OK: with next", func(t *testing.T) {
t.Parallel()
res, err := domain.NewListPlayersWithRelationsResult(players, next)
require.NoError(t, err)
assert.Equal(t, players, res.Players())
assert.Equal(t, players[0].Player().ID(), res.Self().ID())
assert.Equal(t, players[0].Player().ServerKey(), res.Self().ServerKey())
assert.Equal(t, next.Player().ID(), res.Next().ID())
assert.Equal(t, next.Player().ServerKey(), res.Next().ServerKey())
})
t.Run("OK: without next", func(t *testing.T) {
t.Parallel()
res, err := domain.NewListPlayersWithRelationsResult(players, domain.PlayerWithRelations{})
require.NoError(t, err)
assert.Equal(t, players, res.Players())
assert.Equal(t, players[0].Player().ID(), res.Self().ID())
assert.Equal(t, players[0].Player().ServerKey(), res.Self().ServerKey())
assert.True(t, res.Next().IsZero())
})
t.Run("OK: 0 players", func(t *testing.T) {
t.Parallel()
res, err := domain.NewListPlayersWithRelationsResult(nil, domain.PlayerWithRelations{})
require.NoError(t, err)
assert.Zero(t, res.Players())
assert.True(t, res.Self().IsZero())
assert.True(t, res.Next().IsZero())
})
}

View File

@ -330,7 +330,7 @@ func (params *UpdateServerParams) NumTribes() NullInt {
func (params *UpdateServerParams) SetNumTribes(numTribes NullInt) error {
if numTribes.Valid {
if err := validateIntInRange(numTribes.Value, 0, math.MaxInt); err != nil {
if err := validateIntInRange(numTribes.V, 0, math.MaxInt); err != nil {
return ValidationError{
Model: updateServerParamsModelName,
Field: "numTribes",
@ -556,7 +556,7 @@ func NewListServersParams() ListServersParams {
sort: []ServerSort{ServerSortKeyASC},
limit: ServerListMaxLimit,
special: NullBool{
Value: false,
V: false,
Valid: true,
},
}

View File

@ -136,7 +136,7 @@ func TestUpdateServerParams_SetNumTribes(t *testing.T) {
name: "OK",
args: args{
numTribes: domain.NullInt{
Value: gofakeit.IntRange(0, math.MaxInt),
V: gofakeit.IntRange(0, math.MaxInt),
Valid: true,
},
},
@ -153,7 +153,7 @@ func TestUpdateServerParams_SetNumTribes(t *testing.T) {
name: "ERR: numTribes < 0",
args: args{
numTribes: domain.NullInt{
Value: -1,
V: -1,
Valid: true,
},
},

View File

@ -216,6 +216,15 @@ func (t Tribe) Base() BaseTribe {
}
}
func (t Tribe) Meta() TribeMeta {
return TribeMeta{
id: t.id,
name: t.name,
tag: t.tag,
profileURL: t.profileURL,
}
}
func (t Tribe) IsZero() bool {
return t == Tribe{}
}
@ -247,6 +256,66 @@ func (ts Tribes) Delete(serverKey string, active BaseTribes) []int {
return toDelete
}
type TribeMeta struct {
id int
name string
tag string
profileURL *url.URL
}
const tribeMetaModelName = "TribeMeta"
// UnmarshalTribeMetaFromDatabase unmarshals TribeMeta from the database.
//
// It should be used only for unmarshalling from the database!
// You can't use UnmarshalTribeMetaFromDatabase as constructor - It may put domain into the invalid state!
func UnmarshalTribeMetaFromDatabase(id int, name string, tag string, rawProfileURL string) (TribeMeta, error) {
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
return TribeMeta{}, ValidationError{
Model: tribeMetaModelName,
Field: "id",
Err: err,
}
}
profileURL, err := parseURL(rawProfileURL)
if err != nil {
return TribeMeta{}, ValidationError{
Model: tribeMetaModelName,
Field: "profileURL",
Err: err,
}
}
return TribeMeta{id: id, name: name, tag: tag, profileURL: profileURL}, nil
}
func (t TribeMeta) ID() int {
return t.id
}
func (t TribeMeta) Name() string {
return t.name
}
func (t TribeMeta) Tag() string {
return t.tag
}
func (t TribeMeta) ProfileURL() *url.URL {
return t.profileURL
}
func (t TribeMeta) IsZero() bool {
return t == TribeMeta{}
}
type NullTribeMeta NullValue[TribeMeta]
func (t NullTribeMeta) IsZero() bool {
return !t.Valid
}
type CreateTribeParams struct {
base BaseTribe
serverKey string
@ -646,7 +715,7 @@ func (params *ListTribesParams) IDs() []int {
func (params *ListTribesParams) SetIDs(ids []int) error {
for i, id := range ids {
if err := validateIntInRange(id, 0, math.MaxInt); err != nil {
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
return SliceElementValidationError{
Model: listTribesParamsModelName,
Field: "ids",

View File

@ -399,13 +399,13 @@ func TestListTribesParams_SetIDs(t *testing.T) {
},
},
{
name: "ERR: value < 0",
name: "ERR: value < 1",
args: args{
ids: []int{
domaintest.RandID(),
domaintest.RandID(),
domaintest.RandID(),
-1,
0,
domaintest.RandID(),
},
},
@ -414,8 +414,8 @@ func TestListTribesParams_SetIDs(t *testing.T) {
Field: "ids",
Index: 3,
Err: domain.MinGreaterEqualError{
Min: 0,
Current: -1,
Min: 1,
Current: 0,
},
},
},

View File

@ -254,7 +254,7 @@ func (params *ListVillagesParams) IDs() []int {
func (params *ListVillagesParams) SetIDs(ids []int) error {
for i, id := range ids {
if err := validateIntInRange(id, 0, math.MaxInt); err != nil {
if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
return SliceElementValidationError{
Model: listVillagesParamsModelName,
Field: "ids",
@ -275,7 +275,7 @@ func (params *ListVillagesParams) IDGT() NullInt {
func (params *ListVillagesParams) SetIDGT(idGT NullInt) error {
if idGT.Valid {
if err := validateIntInRange(idGT.Value, 0, math.MaxInt); err != nil {
if err := validateIntInRange(idGT.V, 0, math.MaxInt); err != nil {
return ValidationError{
Model: listVillagesParamsModelName,
Field: "idGT",

View File

@ -111,13 +111,13 @@ func TestListVillagesParams_SetIDs(t *testing.T) {
},
},
{
name: "ERR: value < 0",
name: "ERR: value < 1",
args: args{
ids: []int{
domaintest.RandID(),
domaintest.RandID(),
domaintest.RandID(),
-1,
0,
domaintest.RandID(),
},
},
@ -126,8 +126,8 @@ func TestListVillagesParams_SetIDs(t *testing.T) {
Field: "ids",
Index: 3,
Err: domain.MinGreaterEqualError{
Min: 0,
Current: -1,
Min: 1,
Current: 0,
},
},
},
@ -164,7 +164,7 @@ func TestListVillagesParams_SetIDGT(t *testing.T) {
name: "OK",
args: args{
idGT: domain.NullInt{
Value: domaintest.RandID(),
V: domaintest.RandID(),
Valid: true,
},
},
@ -173,7 +173,7 @@ func TestListVillagesParams_SetIDGT(t *testing.T) {
name: "ERR: value < 0",
args: args{
idGT: domain.NullInt{
Value: -1,
V: -1,
Valid: true,
},
},

View File

@ -207,7 +207,7 @@ func TestDataSync(t *testing.T) {
domain.ServerSortKeyASC,
}))
require.NoError(collect, listParams.SetSpecial(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(collect, listParams.SetLimit(domain.ServerListMaxLimit))
@ -431,7 +431,7 @@ func TestDataSync(t *testing.T) {
allVillages = append(allVillages, villages...)
require.NoError(collect, listParams.SetIDGT(domain.NullInt{
Value: villages[len(villages)-1].ID(),
V: villages[len(villages)-1].ID(),
Valid: true,
}))
}

View File

@ -167,7 +167,7 @@ func TestEnnoblementSync(t *testing.T) {
domain.ServerSortKeyASC,
}))
require.NoError(collect, listParams.SetSpecial(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(collect, listParams.SetLimit(domain.ServerListMaxLimit))

View File

@ -151,7 +151,7 @@ func TestSnapshotCreation(t *testing.T) {
domain.ServerSortKeyASC,
}))
require.NoError(collect, listParams.SetSpecial(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(collect, listParams.SetLimit(domain.ServerListMaxLimit))
@ -182,7 +182,7 @@ func TestSnapshotCreation(t *testing.T) {
domain.TribeSortIDASC,
}))
require.NoError(collect, listTribesParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(collect, listTribesParams.SetLimit(domain.TribeListMaxLimit))
@ -268,7 +268,7 @@ func TestSnapshotCreation(t *testing.T) {
domain.PlayerSortIDASC,
}))
require.NoError(collect, listPlayersParams.SetDeleted(domain.NullBool{
Value: false,
V: false,
Valid: true,
}))
require.NoError(collect, listPlayersParams.SetLimit(domain.PlayerListMaxLimit))

View File

@ -37,7 +37,7 @@ func (h *apiHTTPHandler) ListPlayers(
if params.Deleted != nil {
if err := domainParams.SetDeleted(domain.NullBool{
Value: *params.Deleted,
V: *params.Deleted,
Valid: true,
}); err != nil {
h.errorRenderer.withErrorPathFormatter(formatListPlayersErrorPath).render(w, r, err)
@ -59,7 +59,7 @@ func (h *apiHTTPHandler) ListPlayers(
}
}
res, err := h.playerSvc.List(r.Context(), domainParams)
res, err := h.playerSvc.ListWithRelations(r.Context(), domainParams)
if err != nil {
h.errorRenderer.render(w, r, err)
return

View File

@ -30,7 +30,7 @@ func (h *apiHTTPHandler) ListServers(
if params.Open != nil {
if err := domainParams.SetOpen(domain.NullBool{
Value: *params.Open,
V: *params.Open,
Valid: true,
}); err != nil {
h.errorRenderer.withErrorPathFormatter(formatListServersErrorPath).render(w, r, err)

View File

@ -47,7 +47,7 @@ func (h *apiHTTPHandler) ListTribes(
if params.Deleted != nil {
if err := domainParams.SetDeleted(domain.NullBool{
Value: *params.Deleted,
V: *params.Deleted,
Valid: true,
}); err != nil {
h.errorRenderer.withErrorPathFormatter(formatListTribesErrorPath).render(w, r, err)

View File

@ -704,7 +704,7 @@ func TestGetTribe(t *testing.T) {
},
},
{
name: "ERR: id < 0",
name: "ERR: id < 1",
reqModifier: func(t *testing.T, req *http.Request) {
t.Helper()
req.URL.Path = fmt.Sprintf(
@ -726,7 +726,7 @@ func TestGetTribe(t *testing.T) {
id, err := strconv.Atoi(pathSegments[7])
require.NoError(t, err)
domainErr := domain.MinGreaterEqualError{
Min: 0,
Min: 1,
Current: id,
}
assert.Equal(t, apimodel.ErrorResponse{

View File

@ -17,7 +17,9 @@ func NewPlayerOpponentsDefeated(od domain.OpponentsDefeated) PlayerOpponentsDefe
}
}
func NewPlayer(p domain.Player) Player {
func NewPlayer(withRelations domain.PlayerWithRelations) Player {
p := withRelations.Player()
converted := Player{
BestRank: p.BestRank(),
BestRankAt: p.BestRankAt(),
@ -34,6 +36,7 @@ func NewPlayer(p domain.Player) Player {
Points: p.Points(),
ProfileUrl: p.ProfileURL().String(),
Rank: p.Rank(),
Tribe: NewNullTribeMeta(withRelations.Tribe()),
}
if deletedAt := p.DeletedAt(); !deletedAt.IsZero() {
@ -43,7 +46,7 @@ func NewPlayer(p domain.Player) Player {
return converted
}
func NewListPlayersResponse(res domain.ListPlayersResult) ListPlayersResponse {
func NewListPlayersResponse(res domain.ListPlayersWithRelationsResult) ListPlayersResponse {
players := res.Players()
resp := ListPlayersResponse{

View File

@ -44,6 +44,25 @@ func NewTribe(t domain.Tribe) Tribe {
return converted
}
func NewTribeMeta(t domain.TribeMeta) TribeMeta {
return TribeMeta{
Id: t.ID(),
Name: t.Name(),
ProfileUrl: t.ProfileURL().String(),
Tag: t.Tag(),
}
}
func NewNullTribeMeta(t domain.NullTribeMeta) *TribeMeta {
if !t.Valid {
return nil
}
converted := NewTribeMeta(t.V)
return &converted
}
func NewListTribesResponse(res domain.ListTribesResult) ListTribesResponse {
tribes := res.Tribes()