feat(TribeConsumer): update dominance (#31)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: twhelp/core#31
This commit is contained in:
parent
b0bf482129
commit
f246e205b4
|
@ -4,6 +4,9 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/uptrace/bun/dbfixture"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/core/internal/bundb/internal/model"
|
||||
|
||||
"github.com/jackc/pgerrcode"
|
||||
|
@ -248,7 +251,7 @@ func TestServer_UpdateByKey(t *testing.T) {
|
|||
db := newDB(t)
|
||||
repo := bundb.NewServer(db)
|
||||
fixture := loadFixtures(t, db)
|
||||
server := fixture.MustRow("Server.de188").(*model.Server)
|
||||
server := getServerFromFixture(t, fixture, "de188")
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -359,3 +362,12 @@ func concatStringSlices(slices ...[]string) []string {
|
|||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getServerFromFixture(tb testing.TB, fixture *dbfixture.Fixture, id string) model.Server {
|
||||
tb.Helper()
|
||||
v, err := fixture.Row("Server." + id)
|
||||
require.NoError(tb, err)
|
||||
s, ok := v.(*model.Server)
|
||||
require.True(tb, ok)
|
||||
return *s
|
||||
}
|
||||
|
|
|
@ -11,6 +11,13 @@ import (
|
|||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNumPlayerVillagesGTE = domain.NewError(
|
||||
domain.WithCode(domain.ErrorCodeValidationError),
|
||||
domain.WithMessage("numPlayerVillages must be greater than or equal to 0"),
|
||||
)
|
||||
)
|
||||
|
||||
type Tribe struct {
|
||||
db *bun.DB
|
||||
}
|
||||
|
@ -72,6 +79,27 @@ func (t *Tribe) List(ctx context.Context, params domain.ListTribesParams) ([]dom
|
|||
return result, int64(count), nil
|
||||
}
|
||||
|
||||
func (t *Tribe) UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int64) error {
|
||||
if numPlayerVillages < 0 {
|
||||
return ErrNumPlayerVillagesGTE
|
||||
}
|
||||
|
||||
q := t.db.NewUpdate().
|
||||
Model(&model.Tribe{}).
|
||||
Returning("NULL").
|
||||
Where("server_key = ?", serverKey)
|
||||
if numPlayerVillages > 0 {
|
||||
q = q.Set("dominance = num_villages::double precision / ? * 100", numPlayerVillages)
|
||||
} else {
|
||||
q = q.Set("dominance = 0")
|
||||
}
|
||||
if _, err := q.Exec(ctx); err != nil {
|
||||
return fmt.Errorf("couldn't update dominance (server=%s): %w", serverKey, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type listTribesParamsApplier struct {
|
||||
params domain.ListTribesParams
|
||||
}
|
||||
|
|
|
@ -270,6 +270,67 @@ func TestTribe_List(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestTribe_UpdateDominance(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db := newDB(t)
|
||||
fixture := loadFixtures(t, db)
|
||||
repo := bundb.NewTribe(db)
|
||||
serverDE188 := getServerFromFixture(t, fixture, "de188")
|
||||
serverPL169 := getServerFromFixture(t, fixture, "pl169")
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
serverKey string
|
||||
numPlayerVillages int64
|
||||
}{
|
||||
{
|
||||
name: "numPlayerVillages=0",
|
||||
serverKey: serverDE188.Key,
|
||||
numPlayerVillages: 0,
|
||||
},
|
||||
{
|
||||
name: "numPlayerVillages=35000",
|
||||
serverKey: serverPL169.Key,
|
||||
numPlayerVillages: 35000,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.NoError(t, repo.UpdateDominance(context.Background(), tt.serverKey, tt.numPlayerVillages))
|
||||
tribes, _, err := repo.List(
|
||||
context.Background(),
|
||||
domain.ListTribesParams{ServerKeys: []string{tt.serverKey}},
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, len(tribes), 0)
|
||||
for _, tribe := range tribes {
|
||||
if tt.numPlayerVillages == 0 {
|
||||
assert.Equal(t, 0.0, tribe.Dominance)
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, float64(tribe.NumVillages)/float64(tt.numPlayerVillages)*100, tribe.Dominance)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ERR: numPlayerVillages < 0", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
err := repo.UpdateDominance(context.Background(), serverDE188.Key, -1)
|
||||
assert.ErrorIs(t, err, bundb.ErrNumPlayerVillagesGTE)
|
||||
})
|
||||
}
|
||||
|
||||
func assertCreatedTribes(tb testing.TB, params []domain.CreateTribeParams, tribes []domain.Tribe) {
|
||||
tb.Helper()
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ import (
|
|||
"fmt"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
)
|
||||
|
||||
//counterfeiter:generate -o internal/mock/tribe_service.gen.go . TribeService
|
||||
type TribeService interface {
|
||||
Refresh(ctx context.Context, key, url string) (int64, error)
|
||||
UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int64) error
|
||||
}
|
||||
|
||||
type TribeConsumer struct {
|
||||
|
@ -83,6 +83,15 @@ func (t *TribeConsumer) refresh(msg *message.Message) ([]*message.Message, error
|
|||
}
|
||||
|
||||
func (t *TribeConsumer) updateDominance(msg *message.Message) error {
|
||||
// TODO: implement this method
|
||||
var payload domain.EventVillagesRefreshedPayload
|
||||
if err := t.marshaler.Unmarshal(msg, &payload); err != nil {
|
||||
// drop message with invalid payload
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := t.svc.UpdateDominance(msg.Context(), payload.Key, payload.NumPlayerVillages); err != nil {
|
||||
return fmt.Errorf("TribeService.UpdateDominance: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -94,3 +94,58 @@ func TestTribeConsumer_refresh(t *testing.T) {
|
|||
assert.Equal(t, 0, tribeSvc.RefreshCallCount())
|
||||
})
|
||||
}
|
||||
|
||||
func TestTribeConsumer_updateDominance(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
marshaler := msg.GobMarshaler{}
|
||||
pubSub := newPubSub(t)
|
||||
|
||||
tribeSvc := &mock.FakeTribeService{}
|
||||
tribeSvc.UpdateDominanceReturns(nil)
|
||||
|
||||
wait := make(chan struct{})
|
||||
runRouter(
|
||||
t,
|
||||
middlewareRegisterer{
|
||||
h: func(h message.HandlerFunc) message.HandlerFunc {
|
||||
return func(msg *message.Message) ([]*message.Message, error) {
|
||||
if message.HandlerNameFromCtx(msg.Context()) != "TribeConsumer.updateDominance" {
|
||||
return h(msg)
|
||||
}
|
||||
|
||||
result, err := h(msg)
|
||||
if len(result) == 0 && err == nil {
|
||||
close(wait)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
},
|
||||
},
|
||||
msg.NewTribeConsumer(marshaler, pubSub, pubSub, tribeSvc),
|
||||
)
|
||||
|
||||
payload := domain.EventVillagesRefreshedPayload{
|
||||
Key: "pl151",
|
||||
URL: "https://pl151.plemiona.pl",
|
||||
VersionCode: "pl",
|
||||
NumVillages: 1500,
|
||||
NumPlayerVillages: 1400,
|
||||
NumBarbarianVillages: 100,
|
||||
NumBonusVillages: 300,
|
||||
}
|
||||
ev, err := marshaler.Marshal(payload)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, pubSub.Publish("villages.event.refreshed", ev))
|
||||
|
||||
select {
|
||||
case <-wait:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("timeout")
|
||||
}
|
||||
|
||||
require.Equal(t, 1, tribeSvc.UpdateDominanceCallCount())
|
||||
_, serverKey, numPlayerVillages := tribeSvc.UpdateDominanceArgsForCall(0)
|
||||
assert.Equal(t, payload.Key, serverKey)
|
||||
assert.Equal(t, payload.NumPlayerVillages, numPlayerVillages)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
type TribeRepository interface {
|
||||
CreateOrUpdate(ctx context.Context, params ...domain.CreateTribeParams) error
|
||||
UpdateDominance(ctx context.Context, serverKey string, numVillages int64) error
|
||||
}
|
||||
|
||||
type TribesGetter interface {
|
||||
|
@ -45,7 +46,9 @@ func (t *Tribe) Refresh(ctx context.Context, key, url string) (int64, error) {
|
|||
return int64(len(tribes)), nil
|
||||
}
|
||||
|
||||
func (t *Tribe) UpdateDominance(ctx context.Context, key string, numVillages int64) error {
|
||||
// TODO: implement this method
|
||||
func (t *Tribe) UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int64) error {
|
||||
if err := t.repo.UpdateDominance(ctx, serverKey, numPlayerVillages); err != nil {
|
||||
return fmt.Errorf("TribeRepository.UpdateDominance: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Reference in New Issue
Block a user