185 lines
6.3 KiB
Go
185 lines
6.3 KiB
Go
package redisstate_test
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"testing"
|
|
|
|
"galaxy/lobby/internal/adapters/redisstate"
|
|
"galaxy/lobby/internal/domain/common"
|
|
"galaxy/lobby/internal/ports"
|
|
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newGameTurnStatsStore(t *testing.T) (*redisstate.GameTurnStatsStore, *miniredis.Miniredis) {
|
|
t.Helper()
|
|
server := miniredis.RunT(t)
|
|
client := redis.NewClient(&redis.Options{Addr: server.Addr()})
|
|
t.Cleanup(func() { _ = client.Close() })
|
|
|
|
store, err := redisstate.NewGameTurnStatsStore(client)
|
|
require.NoError(t, err)
|
|
return store, server
|
|
}
|
|
|
|
func TestGameTurnStatsStoreSaveInitialFreezesValues(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-1")
|
|
|
|
require.NoError(t, store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "user-a", Planets: 3, Population: 100, ShipsBuilt: 7},
|
|
}))
|
|
|
|
require.NoError(t, store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "user-a", Planets: 99, Population: 9999, ShipsBuilt: 999},
|
|
}))
|
|
|
|
aggregate, err := store.Load(ctx, gameID)
|
|
require.NoError(t, err)
|
|
require.Len(t, aggregate.Players, 1)
|
|
assert.Equal(t, int64(3), aggregate.Players[0].InitialPlanets)
|
|
assert.Equal(t, int64(100), aggregate.Players[0].InitialPopulation)
|
|
assert.Equal(t, int64(7), aggregate.Players[0].InitialShipsBuilt)
|
|
assert.Equal(t, int64(3), aggregate.Players[0].MaxPlanets)
|
|
assert.Equal(t, int64(100), aggregate.Players[0].MaxPopulation)
|
|
assert.Equal(t, int64(7), aggregate.Players[0].MaxShipsBuilt)
|
|
}
|
|
|
|
func TestGameTurnStatsStoreUpdateMaxRaisesOnly(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-2")
|
|
|
|
require.NoError(t, store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "user-a", Planets: 3, Population: 100, ShipsBuilt: 7},
|
|
}))
|
|
|
|
require.NoError(t, store.UpdateMax(ctx, gameID, []ports.PlayerObservedStats{
|
|
{UserID: "user-a", Planets: 5, Population: 80, ShipsBuilt: 9},
|
|
}))
|
|
|
|
require.NoError(t, store.UpdateMax(ctx, gameID, []ports.PlayerObservedStats{
|
|
{UserID: "user-a", Planets: 4, Population: 60, ShipsBuilt: 8},
|
|
}))
|
|
|
|
aggregate, err := store.Load(ctx, gameID)
|
|
require.NoError(t, err)
|
|
require.Len(t, aggregate.Players, 1)
|
|
assert.Equal(t, int64(3), aggregate.Players[0].InitialPlanets)
|
|
assert.Equal(t, int64(100), aggregate.Players[0].InitialPopulation)
|
|
assert.Equal(t, int64(7), aggregate.Players[0].InitialShipsBuilt)
|
|
assert.Equal(t, int64(5), aggregate.Players[0].MaxPlanets)
|
|
assert.Equal(t, int64(100), aggregate.Players[0].MaxPopulation)
|
|
assert.Equal(t, int64(9), aggregate.Players[0].MaxShipsBuilt)
|
|
}
|
|
|
|
func TestGameTurnStatsStoreUpdateMaxBeforeSaveInitial(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-3")
|
|
|
|
require.NoError(t, store.UpdateMax(ctx, gameID, []ports.PlayerObservedStats{
|
|
{UserID: "user-a", Planets: 4, Population: 50, ShipsBuilt: 1},
|
|
}))
|
|
|
|
require.NoError(t, store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "user-a", Planets: 99, Population: 99, ShipsBuilt: 99},
|
|
}))
|
|
|
|
aggregate, err := store.Load(ctx, gameID)
|
|
require.NoError(t, err)
|
|
require.Len(t, aggregate.Players, 1)
|
|
assert.Equal(t, int64(4), aggregate.Players[0].InitialPlanets)
|
|
assert.Equal(t, int64(50), aggregate.Players[0].InitialPopulation)
|
|
assert.Equal(t, int64(1), aggregate.Players[0].InitialShipsBuilt)
|
|
assert.Equal(t, int64(4), aggregate.Players[0].MaxPlanets)
|
|
assert.Equal(t, int64(50), aggregate.Players[0].MaxPopulation)
|
|
assert.Equal(t, int64(1), aggregate.Players[0].MaxShipsBuilt)
|
|
}
|
|
|
|
func TestGameTurnStatsStoreLoadEmpty(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
gameID := common.GameID("game-stats-empty")
|
|
|
|
aggregate, err := store.Load(context.Background(), gameID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, gameID, aggregate.GameID)
|
|
assert.Empty(t, aggregate.Players)
|
|
}
|
|
|
|
func TestGameTurnStatsStoreLoadSortsByUserID(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-sorted")
|
|
|
|
require.NoError(t, store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "user-c", Planets: 1, Population: 1, ShipsBuilt: 1},
|
|
{UserID: "user-a", Planets: 2, Population: 2, ShipsBuilt: 2},
|
|
{UserID: "user-b", Planets: 3, Population: 3, ShipsBuilt: 3},
|
|
}))
|
|
|
|
aggregate, err := store.Load(ctx, gameID)
|
|
require.NoError(t, err)
|
|
require.Len(t, aggregate.Players, 3)
|
|
|
|
got := []string{aggregate.Players[0].UserID, aggregate.Players[1].UserID, aggregate.Players[2].UserID}
|
|
expected := []string{"user-a", "user-b", "user-c"}
|
|
require.True(t, sort.StringsAreSorted(got))
|
|
assert.Equal(t, expected, got)
|
|
}
|
|
|
|
func TestGameTurnStatsStoreDeleteRemovesEverything(t *testing.T) {
|
|
store, server := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-del")
|
|
|
|
require.NoError(t, store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "user-a", Planets: 1, Population: 1, ShipsBuilt: 1},
|
|
{UserID: "user-b", Planets: 2, Population: 2, ShipsBuilt: 2},
|
|
}))
|
|
|
|
require.NoError(t, store.Delete(ctx, gameID))
|
|
|
|
aggregate, err := store.Load(ctx, gameID)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, aggregate.Players)
|
|
|
|
keyspace := redisstate.Keyspace{}
|
|
assert.False(t, server.Exists(keyspace.GameTurnStatsByGame(gameID)))
|
|
assert.False(t, server.Exists(keyspace.GameTurnStat(gameID, "user-a")))
|
|
assert.False(t, server.Exists(keyspace.GameTurnStat(gameID, "user-b")))
|
|
}
|
|
|
|
func TestGameTurnStatsStoreDeleteIsIdempotent(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-del-noop")
|
|
|
|
require.NoError(t, store.Delete(ctx, gameID))
|
|
require.NoError(t, store.Delete(ctx, gameID))
|
|
}
|
|
|
|
func TestGameTurnStatsStoreRejectsInvalidInputs(t *testing.T) {
|
|
store, _ := newGameTurnStatsStore(t)
|
|
ctx := context.Background()
|
|
gameID := common.GameID("game-stats-bad")
|
|
|
|
err := store.SaveInitial(ctx, gameID, []ports.PlayerInitialStats{
|
|
{UserID: "", Planets: 1, Population: 1, ShipsBuilt: 1},
|
|
})
|
|
assert.Error(t, err)
|
|
|
|
err = store.UpdateMax(ctx, gameID, []ports.PlayerObservedStats{
|
|
{UserID: "user-a", Planets: -1, Population: 1, ShipsBuilt: 1},
|
|
})
|
|
assert.Error(t, err)
|
|
|
|
_, err = store.Load(ctx, common.GameID(""))
|
|
assert.Error(t, err)
|
|
}
|