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"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/uptrace/bun/dbfixture"
|
||||||
|
|
||||||
"gitea.dwysokinski.me/twhelp/core/internal/bundb/internal/model"
|
"gitea.dwysokinski.me/twhelp/core/internal/bundb/internal/model"
|
||||||
|
|
||||||
"github.com/jackc/pgerrcode"
|
"github.com/jackc/pgerrcode"
|
||||||
|
@ -248,7 +251,7 @@ func TestServer_UpdateByKey(t *testing.T) {
|
||||||
db := newDB(t)
|
db := newDB(t)
|
||||||
repo := bundb.NewServer(db)
|
repo := bundb.NewServer(db)
|
||||||
fixture := loadFixtures(t, 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.Run("OK", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
@ -359,3 +362,12 @@ func concatStringSlices(slices ...[]string) []string {
|
||||||
}
|
}
|
||||||
return res
|
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"
|
"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 {
|
type Tribe struct {
|
||||||
db *bun.DB
|
db *bun.DB
|
||||||
}
|
}
|
||||||
|
@ -72,6 +79,27 @@ func (t *Tribe) List(ctx context.Context, params domain.ListTribesParams) ([]dom
|
||||||
return result, int64(count), nil
|
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 {
|
type listTribesParamsApplier struct {
|
||||||
params domain.ListTribesParams
|
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) {
|
func assertCreatedTribes(tb testing.TB, params []domain.CreateTribeParams, tribes []domain.Tribe) {
|
||||||
tb.Helper()
|
tb.Helper()
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
||||||
|
|
||||||
"github.com/ThreeDotsLabs/watermill/message"
|
"github.com/ThreeDotsLabs/watermill/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
//counterfeiter:generate -o internal/mock/tribe_service.gen.go . TribeService
|
//counterfeiter:generate -o internal/mock/tribe_service.gen.go . TribeService
|
||||||
type TribeService interface {
|
type TribeService interface {
|
||||||
Refresh(ctx context.Context, key, url string) (int64, error)
|
Refresh(ctx context.Context, key, url string) (int64, error)
|
||||||
|
UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type TribeConsumer struct {
|
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 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,3 +94,58 @@ func TestTribeConsumer_refresh(t *testing.T) {
|
||||||
assert.Equal(t, 0, tribeSvc.RefreshCallCount())
|
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 {
|
type TribeRepository interface {
|
||||||
CreateOrUpdate(ctx context.Context, params ...domain.CreateTribeParams) error
|
CreateOrUpdate(ctx context.Context, params ...domain.CreateTribeParams) error
|
||||||
|
UpdateDominance(ctx context.Context, serverKey string, numVillages int64) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type TribesGetter interface {
|
type TribesGetter interface {
|
||||||
|
@ -45,7 +46,9 @@ func (t *Tribe) Refresh(ctx context.Context, key, url string) (int64, error) {
|
||||||
return int64(len(tribes)), nil
|
return int64(len(tribes)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tribe) UpdateDominance(ctx context.Context, key string, numVillages int64) error {
|
func (t *Tribe) UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int64) error {
|
||||||
// TODO: implement this method
|
if err := t.repo.UpdateDominance(ctx, serverKey, numPlayerVillages); err != nil {
|
||||||
|
return fmt.Errorf("TribeRepository.UpdateDominance: %w", err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue
Block a user