2024-02-24 06:57:09 +00:00
|
|
|
package port_test
|
2024-01-10 06:39:09 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/fs"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"path"
|
2024-03-16 06:00:29 +00:00
|
|
|
"sync"
|
2024-01-10 06:39:09 +00:00
|
|
|
"syscall"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/adapter"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/app"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/port"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/tw"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/watermill/watermillamqptest"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/watermill/watermillmsg"
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/watermill/watermilltest"
|
|
|
|
"github.com/ThreeDotsLabs/watermill"
|
|
|
|
"github.com/ThreeDotsLabs/watermill-amqp/v2/pkg/amqp"
|
2024-03-01 07:15:06 +00:00
|
|
|
"github.com/brianvoe/gofakeit/v7"
|
2024-01-10 06:39:09 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
// we can't run the subtests in parallel
|
|
|
|
|
|
|
|
//nolint:tparallel
|
|
|
|
func TestDataSync(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("skipping long-running test")
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxTimeout, cancel := context.WithTimeout(context.Background(), 150*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
ctx, stop := signal.NotifyContext(ctxTimeout, os.Interrupt, syscall.SIGTERM)
|
|
|
|
defer stop()
|
|
|
|
|
|
|
|
// bun
|
2024-01-14 10:04:17 +00:00
|
|
|
db := postgres.NewDB(t)
|
2024-01-10 06:39:09 +00:00
|
|
|
|
|
|
|
// watermill
|
|
|
|
marshaler := watermillmsg.JSONMarshaler{NewUUID: watermill.NewUUID}
|
|
|
|
generateExchangeAndRoutingKeyName := func(topic string) string {
|
2024-01-11 06:13:28 +00:00
|
|
|
return topic + "_data_sync"
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
|
|
|
rmqConn := rabbitMQ.NewConnection(t)
|
|
|
|
nopLogger := watermill.NopLogger{}
|
|
|
|
serverPub, serverSub := watermillamqptest.NewPubSub(
|
|
|
|
t,
|
|
|
|
rmqConn,
|
2024-01-11 06:13:28 +00:00
|
|
|
amqp.GenerateQueueNameTopicNameWithSuffix("_data_sync_server"),
|
2024-01-10 06:39:09 +00:00
|
|
|
generateExchangeAndRoutingKeyName,
|
|
|
|
)
|
|
|
|
playerPub, playerSub := watermillamqptest.NewPubSub(
|
|
|
|
t,
|
|
|
|
rmqConn,
|
2024-01-11 06:13:28 +00:00
|
|
|
amqp.GenerateQueueNameTopicNameWithSuffix("_data_sync_player"),
|
2024-01-10 06:39:09 +00:00
|
|
|
generateExchangeAndRoutingKeyName,
|
|
|
|
)
|
|
|
|
tribePub, tribeSub := watermillamqptest.NewPubSub(
|
|
|
|
t,
|
|
|
|
rmqConn,
|
2024-01-11 06:13:28 +00:00
|
|
|
amqp.GenerateQueueNameTopicNameWithSuffix("_data_sync_tribe"),
|
2024-01-10 06:39:09 +00:00
|
|
|
generateExchangeAndRoutingKeyName,
|
|
|
|
)
|
|
|
|
villagePub, villageSub := watermillamqptest.NewPubSub(
|
|
|
|
t,
|
|
|
|
rmqConn,
|
2024-01-11 06:13:28 +00:00
|
|
|
amqp.GenerateQueueNameTopicNameWithSuffix("_data_sync_village"),
|
2024-01-10 06:39:09 +00:00
|
|
|
generateExchangeAndRoutingKeyName,
|
|
|
|
)
|
|
|
|
|
|
|
|
// events/commands
|
|
|
|
serverCmdSync := gofakeit.UUID()
|
|
|
|
serverEventSynced := gofakeit.UUID()
|
|
|
|
playerEventSynced := gofakeit.UUID()
|
|
|
|
tribeEventSynced := gofakeit.UUID()
|
|
|
|
villageEventSynced := gofakeit.UUID()
|
|
|
|
|
|
|
|
// TW service
|
|
|
|
|
2024-01-11 06:13:28 +00:00
|
|
|
// filesys is set later in this test to os.DirFS("./testdata/datasync/stage{n}")
|
2024-01-10 06:39:09 +00:00
|
|
|
var filesys fs.FS
|
|
|
|
|
|
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != http.MethodGet {
|
|
|
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
u, err := url.Parse(r.URL.Query().Get("url"))
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
fname := u.Path + u.Query().Get("func")
|
|
|
|
f, err := filesys.Open(path.Join(u.Host, fname))
|
|
|
|
if err != nil {
|
|
|
|
f, err = filesys.Open(path.Join("default", fname))
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
_ = f.Close()
|
|
|
|
}()
|
|
|
|
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_, _ = io.Copy(w, f)
|
|
|
|
}))
|
|
|
|
t.Cleanup(srv.Close)
|
|
|
|
|
|
|
|
twSvc := adapter.NewTWHTTP(tw.NewClient(tw.WithHTTPClient(&http.Client{
|
|
|
|
Transport: &urlChangerTransport{
|
|
|
|
url: srv.URL,
|
|
|
|
transport: srv.Client().Transport,
|
|
|
|
},
|
|
|
|
})))
|
|
|
|
|
|
|
|
// adapters
|
|
|
|
versionRepo := adapter.NewVersionBunRepository(db)
|
|
|
|
serverRepo := adapter.NewServerBunRepository(db)
|
|
|
|
tribeRepo := adapter.NewTribeBunRepository(db)
|
|
|
|
playerRepo := adapter.NewPlayerBunRepository(db)
|
|
|
|
villageRepo := adapter.NewVillageBunRepository(db)
|
|
|
|
tribeChangeRepo := adapter.NewTribeChangeBunRepository(db)
|
|
|
|
serverPublisher := adapter.NewServerWatermillPublisher(serverPub, marshaler, serverCmdSync, serverEventSynced)
|
|
|
|
playerPublisher := adapter.NewPlayerWatermillPublisher(playerPub, marshaler, playerEventSynced)
|
|
|
|
tribePublisher := adapter.NewTribeWatermillPublisher(tribePub, marshaler, tribeEventSynced)
|
|
|
|
villagePublisher := adapter.NewVillageWatermillPublisher(villagePub, marshaler, villageEventSynced)
|
|
|
|
|
|
|
|
// services
|
|
|
|
versionSvc := app.NewVersionService(versionRepo)
|
|
|
|
serverSvc := app.NewServerService(serverRepo, twSvc, serverPublisher)
|
|
|
|
tribeChangeSvc := app.NewTribeChangeService(tribeChangeRepo)
|
|
|
|
tribeSvc := app.NewTribeService(tribeRepo, twSvc, tribePublisher)
|
|
|
|
playerSvc := app.NewPlayerService(playerRepo, tribeChangeSvc, twSvc, playerPublisher)
|
|
|
|
villageSvc := app.NewVillageService(villageRepo, twSvc, villagePublisher)
|
|
|
|
dataSyncSvc := app.NewDataSyncService(versionSvc, serverSvc, serverPublisher, nil)
|
|
|
|
|
|
|
|
watermilltest.RunRouterWithContext(
|
|
|
|
t,
|
|
|
|
ctx,
|
|
|
|
port.NewServerWatermillConsumer(
|
|
|
|
serverSvc,
|
|
|
|
serverSub,
|
|
|
|
nopLogger,
|
|
|
|
marshaler,
|
|
|
|
serverCmdSync,
|
|
|
|
serverEventSynced,
|
|
|
|
tribeEventSynced,
|
|
|
|
playerEventSynced,
|
|
|
|
villageEventSynced,
|
|
|
|
"",
|
2024-01-15 07:00:08 +00:00
|
|
|
"",
|
2024-01-16 06:28:03 +00:00
|
|
|
"",
|
2024-01-15 07:00:08 +00:00
|
|
|
),
|
|
|
|
port.NewTribeWatermillConsumer(
|
|
|
|
tribeSvc,
|
|
|
|
nil,
|
|
|
|
tribeSub,
|
|
|
|
nopLogger,
|
|
|
|
marshaler,
|
|
|
|
serverEventSynced,
|
|
|
|
villageEventSynced,
|
|
|
|
"",
|
2024-03-24 08:49:01 +00:00
|
|
|
"",
|
2024-01-10 06:39:09 +00:00
|
|
|
),
|
2024-01-16 06:28:03 +00:00
|
|
|
port.NewPlayerWatermillConsumer(
|
|
|
|
playerSvc,
|
|
|
|
nil,
|
|
|
|
playerSub,
|
|
|
|
nopLogger,
|
|
|
|
marshaler,
|
|
|
|
serverEventSynced,
|
|
|
|
"",
|
2024-03-24 08:49:01 +00:00
|
|
|
"",
|
2024-01-16 06:28:03 +00:00
|
|
|
),
|
2024-01-10 06:39:09 +00:00
|
|
|
port.NewVillageWatermillConsumer(villageSvc, villageSub, nopLogger, marshaler, serverEventSynced),
|
|
|
|
)
|
|
|
|
|
|
|
|
for _, stage := range []uint{1, 2} {
|
|
|
|
t.Run(fmt.Sprintf("stage %d", stage), func(t *testing.T) {
|
2024-01-11 06:13:28 +00:00
|
|
|
filesys = os.DirFS(fmt.Sprintf("./testdata/datasync/stage%d", stage))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-01-14 11:57:32 +00:00
|
|
|
require.NoError(t, dataSyncSvc.Sync(ctx))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
2024-01-10 06:39:09 +00:00
|
|
|
var expectedServers []map[string]any
|
|
|
|
readJSONFile(t, filesys, path.Join("expected", "servers.json"), &expectedServers)
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
assert.EventuallyWithTf(t, func(collect *assert.CollectT) {
|
|
|
|
require.NoError(collect, ctx.Err())
|
|
|
|
|
|
|
|
listParams := domain.NewListServersParams()
|
|
|
|
require.NoError(collect, listParams.SetSort([]domain.ServerSort{
|
|
|
|
domain.ServerSortKeyASC,
|
|
|
|
}))
|
|
|
|
require.NoError(collect, listParams.SetSpecial(domain.NullBool{
|
|
|
|
V: false,
|
|
|
|
Valid: true,
|
|
|
|
}))
|
|
|
|
require.NoError(collect, listParams.SetLimit(domain.ServerListMaxLimit))
|
|
|
|
|
|
|
|
allServers := make(domain.Servers, 0, len(expectedServers))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
for {
|
|
|
|
res, err := serverRepo.List(ctx, listParams)
|
|
|
|
require.NoError(collect, err)
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allServers = append(allServers, res.Servers()...)
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if res.Next().IsZero() {
|
|
|
|
break
|
|
|
|
}
|
2024-02-07 07:17:47 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
require.NoError(collect, listParams.SetCursor(res.Next()))
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if !assert.Len(collect, allServers, len(expectedServers)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for i, expected := range expectedServers {
|
|
|
|
actual := allServers[i]
|
|
|
|
msg := fmt.Sprintf("Key=%s", expected["Key"])
|
|
|
|
|
|
|
|
assert.Equal(collect, expected["Key"], actual.Key(), msg)
|
|
|
|
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["NumTribes"], actual.NumTribes(), 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)
|
|
|
|
assert.EqualValues(
|
|
|
|
collect,
|
|
|
|
expected["NumBarbarianVillages"],
|
|
|
|
actual.NumBarbarianVillages(),
|
|
|
|
"Key=%s",
|
|
|
|
expected["Key"],
|
|
|
|
)
|
|
|
|
assert.WithinDuration(collect, time.Now(), actual.PlayerDataSyncedAt(), time.Minute, msg)
|
|
|
|
assert.WithinDuration(collect, time.Now(), actual.TribeDataSyncedAt(), time.Minute, msg)
|
|
|
|
assert.WithinDuration(collect, time.Now(), actual.VillageDataSyncedAt(), time.Minute, msg)
|
|
|
|
assert.JSONEqf(
|
|
|
|
collect,
|
|
|
|
string(marshalJSON(collect, expected["Config"])),
|
|
|
|
string(marshalJSON(collect, serverConfigToMap(actual.Config()))),
|
|
|
|
"Key=%s",
|
|
|
|
expected["Key"],
|
|
|
|
)
|
|
|
|
assert.JSONEq(
|
|
|
|
collect,
|
|
|
|
string(marshalJSON(collect, expected["BuildingInfo"])),
|
|
|
|
string(marshalJSON(collect, buildingInfoToMap(actual.BuildingInfo()))),
|
|
|
|
msg,
|
|
|
|
)
|
|
|
|
assert.JSONEq(
|
|
|
|
collect,
|
|
|
|
string(marshalJSON(collect, expected["UnitInfo"])),
|
|
|
|
string(marshalJSON(collect, unitInfoToMap(actual.UnitInfo()))),
|
|
|
|
msg,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}, 60*time.Second, time.Second, "servers")
|
|
|
|
}()
|
2024-01-10 06:39:09 +00:00
|
|
|
|
|
|
|
var expectedTribes []map[string]any
|
|
|
|
readJSONFile(t, filesys, path.Join("expected", "tribes.json"), &expectedTribes)
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
|
|
|
require.NoError(collect, ctx.Err())
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
listParams := domain.NewListTribesParams()
|
|
|
|
require.NoError(collect, listParams.SetSort([]domain.TribeSort{
|
|
|
|
domain.TribeSortServerKeyASC,
|
|
|
|
domain.TribeSortIDASC,
|
|
|
|
}))
|
|
|
|
require.NoError(collect, listParams.SetLimit(domain.TribeListMaxLimit))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allTribes := make(domain.Tribes, 0, len(expectedTribes))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
for {
|
|
|
|
res, err := tribeRepo.List(ctx, listParams)
|
|
|
|
require.NoError(collect, err)
|
2024-02-12 07:07:15 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allTribes = append(allTribes, res.Tribes()...)
|
|
|
|
|
|
|
|
if res.Next().IsZero() {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(collect, listParams.SetCursor(res.Next()))
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if !assert.Len(collect, allTribes, len(expectedTribes)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for i, expected := range expectedTribes {
|
|
|
|
actual := allTribes[i]
|
|
|
|
msg := fmt.Sprintf("ID=%.0f,ServerKey=%s", expected["ID"], expected["ServerKey"])
|
|
|
|
|
|
|
|
assert.EqualValues(collect, expected["ID"], actual.ID(), msg)
|
|
|
|
assert.Equal(collect, expected["ServerKey"], actual.ServerKey(), msg)
|
|
|
|
assert.Equal(collect, expected["Name"], actual.Name(), msg)
|
|
|
|
assert.Equal(collect, expected["Tag"], actual.Tag(), msg)
|
|
|
|
assert.EqualValues(collect, expected["NumMembers"], actual.NumMembers(), msg)
|
|
|
|
assert.EqualValues(collect, expected["NumVillages"], actual.NumVillages(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Points"], actual.Points(), msg)
|
|
|
|
assert.EqualValues(collect, expected["AllPoints"], actual.AllPoints(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Rank"], actual.Rank(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankAtt"], actual.OD().RankAtt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreAtt"], actual.OD().ScoreAtt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankDef"], actual.OD().RankDef(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreDef"], actual.OD().ScoreDef(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankSup"], actual.OD().RankSup(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreSup"], actual.OD().ScoreSup(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankTotal"], actual.OD().RankTotal(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreTotal"], actual.OD().ScoreTotal(), msg)
|
|
|
|
assert.Equal(collect, expected["ProfileURL"], actual.ProfileURL().String(), msg)
|
|
|
|
assert.InDelta(collect, expected["Dominance"], actual.Dominance(), 0.01, msg)
|
|
|
|
assert.EqualValues(collect, expected["BestRank"], actual.BestRank(), msg)
|
|
|
|
assert.NotEmpty(collect, actual.BestRankAt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["MostPoints"], actual.MostPoints(), msg)
|
|
|
|
assert.NotEmpty(collect, actual.MostPointsAt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["MostVillages"], actual.MostVillages(), msg)
|
|
|
|
assert.NotEmpty(collect, actual.MostVillagesAt(), msg)
|
|
|
|
if deletedAt, ok := expected["DeletedAt"].(string); ok && (time.Time{}).Format(time.RFC3339) != deletedAt {
|
|
|
|
assert.NotEmpty(collect, actual.DeletedAt(), msg)
|
|
|
|
} else {
|
|
|
|
assert.Empty(collect, actual.DeletedAt(), msg)
|
|
|
|
}
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
2024-03-16 06:00:29 +00:00
|
|
|
}, 60*time.Second, time.Second, "tribes")
|
|
|
|
}()
|
2024-01-10 06:39:09 +00:00
|
|
|
|
|
|
|
var expectedPlayers []map[string]any
|
|
|
|
readJSONFile(t, filesys, path.Join("expected", "players.json"), &expectedPlayers)
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
|
|
|
require.NoError(collect, ctx.Err())
|
|
|
|
|
|
|
|
listParams := domain.NewListPlayersParams()
|
|
|
|
require.NoError(collect, listParams.SetSort([]domain.PlayerSort{
|
|
|
|
domain.PlayerSortServerKeyASC,
|
|
|
|
domain.PlayerSortIDASC,
|
|
|
|
}))
|
|
|
|
require.NoError(collect, listParams.SetLimit(domain.PlayerListMaxLimit))
|
|
|
|
|
|
|
|
allPlayers := make(domain.Players, 0, len(expectedPlayers))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
for {
|
|
|
|
res, err := playerRepo.List(ctx, listParams)
|
|
|
|
require.NoError(collect, err)
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allPlayers = append(allPlayers, res.Players()...)
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if res.Next().IsZero() {
|
|
|
|
break
|
|
|
|
}
|
2024-02-26 06:44:39 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
require.NoError(collect, listParams.SetCursor(res.Next()))
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if !assert.Len(collect, allPlayers, len(expectedPlayers)) {
|
|
|
|
return
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
2024-03-16 06:00:29 +00:00
|
|
|
for i, expected := range expectedPlayers {
|
|
|
|
actual := allPlayers[i]
|
|
|
|
msg := fmt.Sprintf("ID=%.0f,ServerKey=%s", expected["ID"], expected["ServerKey"])
|
|
|
|
|
|
|
|
assert.EqualValues(collect, expected["ID"], actual.ID(), msg)
|
|
|
|
assert.Equal(collect, expected["ServerKey"], actual.ServerKey(), msg)
|
|
|
|
assert.Equal(collect, expected["Name"], actual.Name(), msg)
|
|
|
|
assert.EqualValues(collect, expected["NumVillages"], actual.NumVillages(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Points"], actual.Points(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Rank"], actual.Rank(), msg)
|
|
|
|
assert.EqualValues(collect, expected["TribeID"], actual.TribeID(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankAtt"], actual.OD().RankAtt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreAtt"], actual.OD().ScoreAtt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankDef"], actual.OD().RankDef(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreDef"], actual.OD().ScoreDef(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankSup"], actual.OD().RankSup(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreSup"], actual.OD().ScoreSup(), msg)
|
|
|
|
assert.EqualValues(collect, expected["RankTotal"], actual.OD().RankTotal(), msg)
|
|
|
|
assert.EqualValues(collect, expected["ScoreTotal"], actual.OD().ScoreTotal(), msg)
|
|
|
|
assert.Equal(collect, expected["ProfileURL"], actual.ProfileURL().String(), msg)
|
|
|
|
assert.EqualValues(collect, expected["BestRank"], actual.BestRank(), msg)
|
|
|
|
assert.NotEmpty(collect, actual.BestRankAt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["MostPoints"], actual.MostPoints(), msg)
|
|
|
|
assert.NotEmpty(collect, actual.MostPointsAt(), msg)
|
|
|
|
assert.EqualValues(collect, expected["MostVillages"], actual.MostVillages(), msg)
|
|
|
|
assert.NotEmpty(collect, actual.MostVillagesAt(), msg)
|
|
|
|
if deletedAt, ok := expected["DeletedAt"].(string); ok && (time.Time{}).Format(time.RFC3339) != deletedAt {
|
|
|
|
assert.NotEmpty(collect, actual.DeletedAt(), msg)
|
|
|
|
} else {
|
|
|
|
assert.Empty(collect, actual.DeletedAt(), msg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 60*time.Second, time.Second, "players")
|
|
|
|
}()
|
2024-01-10 06:39:09 +00:00
|
|
|
|
|
|
|
var expectedVillages []map[string]any
|
|
|
|
readJSONFile(t, filesys, path.Join("expected", "villages.json"), &expectedVillages)
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
|
|
|
require.NoError(collect, ctx.Err())
|
|
|
|
|
|
|
|
listParams := domain.NewListVillagesParams()
|
|
|
|
require.NoError(collect, listParams.SetSort([]domain.VillageSort{
|
|
|
|
domain.VillageSortServerKeyASC,
|
|
|
|
domain.VillageSortIDASC,
|
|
|
|
}))
|
|
|
|
require.NoError(collect, listParams.SetLimit(domain.VillageListMaxLimit))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allVillages := make(domain.Villages, 0, len(expectedVillages))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
for {
|
|
|
|
res, err := villageRepo.List(ctx, listParams)
|
|
|
|
require.NoError(collect, err)
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allVillages = append(allVillages, res.Villages()...)
|
2024-03-05 06:14:41 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if res.Next().IsZero() {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(collect, listParams.SetCursor(res.Next()))
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
if !assert.Len(collect, allVillages, len(expectedVillages)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for i, expected := range expectedVillages {
|
|
|
|
actual := allVillages[i]
|
|
|
|
msg := fmt.Sprintf("ID=%.0f,ServerKey=%s", expected["ID"], expected["ServerKey"])
|
|
|
|
|
|
|
|
assert.EqualValues(collect, expected["ID"], actual.ID(), msg)
|
|
|
|
assert.Equal(collect, expected["ServerKey"], actual.ServerKey(), msg)
|
|
|
|
assert.Equal(collect, expected["Name"], actual.Name(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Points"], actual.Points(), msg)
|
|
|
|
assert.EqualValues(collect, expected["X"], actual.X(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Y"], actual.Y(), msg)
|
|
|
|
assert.Equal(collect, expected["Continent"], actual.Continent(), msg)
|
|
|
|
assert.EqualValues(collect, expected["Bonus"], actual.Bonus(), msg)
|
|
|
|
assert.EqualValues(collect, expected["PlayerID"], actual.PlayerID(), msg)
|
|
|
|
assert.Equal(collect, expected["ProfileURL"], actual.ProfileURL().String(), msg)
|
|
|
|
}
|
|
|
|
}, 60*time.Second, time.Second, "villages")
|
|
|
|
}()
|
2024-01-10 06:39:09 +00:00
|
|
|
|
|
|
|
var expectedTribeChanges []map[string]any
|
|
|
|
readJSONFile(t, filesys, path.Join("expected", "tribe-changes.json"), &expectedTribeChanges)
|
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
|
|
|
require.NoError(collect, ctx.Err())
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
listParams := domain.NewListTribeChangesParams()
|
|
|
|
require.NoError(collect, listParams.SetSort([]domain.TribeChangeSort{
|
|
|
|
domain.TribeChangeSortIDASC,
|
|
|
|
}))
|
|
|
|
require.NoError(collect, listParams.SetLimit(domain.TribeChangeListMaxLimit))
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
allTribeChanges := make(domain.TribeChanges, 0, len(expectedTribeChanges))
|
2024-03-12 06:19:16 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
for {
|
|
|
|
res, err := tribeChangeRepo.List(ctx, listParams)
|
|
|
|
require.NoError(collect, err)
|
|
|
|
|
|
|
|
allTribeChanges = append(allTribeChanges, res.TribeChanges()...)
|
|
|
|
|
|
|
|
if res.Next().IsZero() {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
require.NoError(collect, listParams.SetCursor(res.Next()))
|
|
|
|
}
|
|
|
|
|
|
|
|
if !assert.Len(collect, allTribeChanges, len(expectedTribeChanges)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for i, expected := range expectedTribeChanges {
|
|
|
|
actual := allTribeChanges[i]
|
|
|
|
msg := fmt.Sprintf("ID=%.0f,ServerKey=%s", expected["ID"], expected["ServerKey"])
|
|
|
|
|
|
|
|
assert.EqualValues(collect, expected["ID"], actual.ID(), msg)
|
|
|
|
assert.Equal(collect, expected["ServerKey"], actual.ServerKey(), msg)
|
|
|
|
assert.EqualValues(collect, expected["PlayerID"], actual.PlayerID(), msg)
|
|
|
|
assert.EqualValues(collect, expected["OldTribeID"], actual.OldTribeID(), msg)
|
|
|
|
assert.EqualValues(collect, expected["NewTribeID"], actual.NewTribeID(), msg)
|
2024-01-10 06:39:09 +00:00
|
|
|
}
|
2024-03-16 06:00:29 +00:00
|
|
|
}, 60*time.Second, time.Second, "tribe changes")
|
|
|
|
}()
|
2024-01-10 06:39:09 +00:00
|
|
|
|
2024-03-16 06:00:29 +00:00
|
|
|
wg.Wait()
|
2024-01-10 06:39:09 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type urlChangerTransport struct {
|
|
|
|
url string
|
|
|
|
transport http.RoundTripper
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *urlChangerTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
|
|
|
u, err := url.Parse(t.url)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
u.RawQuery = url.Values{
|
|
|
|
"url": []string{r.URL.String()},
|
|
|
|
}.Encode()
|
|
|
|
|
|
|
|
r2 := r.Clone(r.Context())
|
|
|
|
r2.URL = u
|
|
|
|
|
|
|
|
return t.transport.RoundTrip(r2)
|
|
|
|
}
|
|
|
|
|
|
|
|
func readJSONFile(tb testing.TB, filesys fs.FS, name string, v any) {
|
|
|
|
tb.Helper()
|
|
|
|
|
|
|
|
f, err := filesys.Open(name)
|
|
|
|
require.NoError(tb, err)
|
|
|
|
defer func() {
|
|
|
|
_ = f.Close()
|
|
|
|
}()
|
|
|
|
|
|
|
|
require.NoError(tb, json.NewDecoder(f).Decode(v))
|
|
|
|
}
|
|
|
|
|
|
|
|
func serverConfigToMap(cfg domain.ServerConfig) map[string]any {
|
|
|
|
return map[string]any{
|
|
|
|
"Speed": cfg.Speed(),
|
|
|
|
"UnitSpeed": cfg.UnitSpeed(),
|
|
|
|
"Moral": cfg.Moral(),
|
|
|
|
"Build": cfg.Build(),
|
|
|
|
"Misc": cfg.Misc(),
|
|
|
|
"Commands": cfg.Commands(),
|
|
|
|
"Newbie": cfg.Newbie(),
|
|
|
|
"Game": cfg.Game(),
|
|
|
|
"Buildings": cfg.Buildings(),
|
|
|
|
"Snob": cfg.Snob(),
|
|
|
|
"Ally": cfg.Ally(),
|
|
|
|
"Coord": cfg.Coord(),
|
|
|
|
"Sitter": cfg.Sitter(),
|
|
|
|
"Sleep": cfg.Sleep(),
|
|
|
|
"Night": cfg.Night(),
|
|
|
|
"Win": cfg.Win(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func unitInfoToMap(info domain.UnitInfo) map[string]any {
|
|
|
|
return map[string]any{
|
|
|
|
"Spear": info.Spear(),
|
|
|
|
"Sword": info.Sword(),
|
|
|
|
"Axe": info.Axe(),
|
|
|
|
"Archer": info.Archer(),
|
|
|
|
"Spy": info.Spy(),
|
|
|
|
"Light": info.Light(),
|
|
|
|
"Marcher": info.Marcher(),
|
|
|
|
"Heavy": info.Heavy(),
|
|
|
|
"Ram": info.Ram(),
|
|
|
|
"Catapult": info.Catapult(),
|
|
|
|
"Knight": info.Knight(),
|
|
|
|
"Snob": info.Snob(),
|
|
|
|
"Militia": info.Militia(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func buildingInfoToMap(info domain.BuildingInfo) map[string]any {
|
|
|
|
return map[string]any{
|
|
|
|
"Main": info.Main(),
|
|
|
|
"Barracks": info.Barracks(),
|
|
|
|
"Stable": info.Stable(),
|
|
|
|
"Garage": info.Garage(),
|
|
|
|
"Watchtower": info.Watchtower(),
|
|
|
|
"Snob": info.Snob(),
|
|
|
|
"Smith": info.Smith(),
|
|
|
|
"Place": info.Place(),
|
|
|
|
"Statue": info.Statue(),
|
|
|
|
"Market": info.Market(),
|
|
|
|
"Wood": info.Wood(),
|
|
|
|
"Stone": info.Stone(),
|
|
|
|
"Iron": info.Iron(),
|
|
|
|
"Farm": info.Farm(),
|
|
|
|
"Storage": info.Storage(),
|
|
|
|
"Hide": info.Hide(),
|
|
|
|
"Wall": info.Wall(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func marshalJSON(tb require.TestingT, v any) []byte {
|
|
|
|
if h, ok := tb.(interface {
|
|
|
|
Helper()
|
|
|
|
}); ok {
|
|
|
|
h.Helper()
|
|
|
|
}
|
|
|
|
b, err := json.Marshal(v)
|
|
|
|
require.NoError(tb, err)
|
|
|
|
return b
|
|
|
|
}
|