use distinct types for player and session ids

This commit is contained in:
Branden J Brown 2024-01-31 22:40:12 -06:00
parent d61c70da86
commit 73b5ac7960
8 changed files with 42 additions and 32 deletions

View File

@ -3,14 +3,16 @@ package game
import (
"testing"
"github.com/google/uuid"
"git.sunturtle.xyz/studio/shotgun/player"
"git.sunturtle.xyz/studio/shotgun/serve"
)
func TestNewGame(t *testing.T) {
t.Parallel()
dealer := player.ID{1}
chall := player.ID{2}
dealer := player.ID{UUID: uuid.UUID{1}}
chall := player.ID{UUID: uuid.UUID{2}}
for i := 0; i < 10000; i++ {
g := New(dealer, chall)
checks := []struct {
@ -41,7 +43,7 @@ func TestNewGame(t *testing.T) {
func TestGameStartRound(t *testing.T) {
t.Parallel()
g := New(player.ID{1}, player.ID{2})
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
for i := int8(1); i < 100; i++ {
checks := []struct {
failed bool
@ -77,7 +79,7 @@ func TestGameStartRound(t *testing.T) {
func TestGameStartGroup(t *testing.T) {
t.Parallel()
g := New(player.ID{1}, player.ID{2})
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
for i := uint(1); i < 10000; i++ {
checks := []struct {
failed bool
@ -114,7 +116,7 @@ func TestGameStartGroup(t *testing.T) {
func TestGameNextTurn(t *testing.T) {
t.Parallel()
g := New(player.ID{1}, player.ID{2})
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
for i := int8(1); i < 100; i++ {
checks := []struct {
failed bool
@ -143,8 +145,8 @@ func TestGameNextTurn(t *testing.T) {
func TestGamePlayers(t *testing.T) {
t.Parallel()
dealer := player.ID{1}
chall := player.ID{2}
dealer := player.ID{UUID: uuid.UUID{1}}
chall := player.ID{UUID: uuid.UUID{2}}
g := New(dealer, chall)
if g.CurrentPlayer().id != chall {
t.Errorf("challenger isn't current player at start")
@ -183,7 +185,7 @@ func TestGamePlayers(t *testing.T) {
func TestGamePopShell(t *testing.T) {
t.Parallel()
g := New(player.ID{1}, player.ID{2})
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
if live := g.popShell(); live != g.shellArray[0] {
t.Errorf("first pop %t, wanted %t", live, g.shellArray[0])
}
@ -208,8 +210,8 @@ func TestGamePopShell(t *testing.T) {
}
func TestGamePeek(t *testing.T) {
dealer := player.ID{1}
chall := player.ID{2}
dealer := player.ID{UUID: uuid.UUID{1}}
chall := player.ID{UUID: uuid.UUID{2}}
t.Run("empty", func(t *testing.T) {
t.Parallel()
g := New(dealer, chall)
@ -270,8 +272,8 @@ func TestGameEmpty(t *testing.T) {
func TestGameWinner(t *testing.T) {
t.Parallel()
dealer := player.ID{1}
chall := player.ID{2}
dealer := player.ID{UUID: uuid.UUID{1}}
chall := player.ID{UUID: uuid.UUID{2}}
cases := []struct {
name string
p0, p1 int8
@ -311,8 +313,8 @@ func TestGameWinner(t *testing.T) {
}
func TestGameShoot(t *testing.T) {
dealer := player.ID{1}
chall := player.ID{2}
dealer := player.ID{UUID: uuid.UUID{1}}
chall := player.ID{UUID: uuid.UUID{2}}
cases := []struct {
name string
live bool
@ -399,7 +401,7 @@ func TestGameShoot(t *testing.T) {
}
func TestConcede(t *testing.T) {
dealer, chall := player.ID{1}, player.ID{2}
dealer, chall := player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}}
cases := []struct {
name string
p player.ID
@ -417,7 +419,7 @@ func TestConcede(t *testing.T) {
},
{
name: "neither",
p: player.ID{3},
p: player.ID{UUID: uuid.UUID{3}},
winner: player.ID{},
},
}
@ -436,7 +438,7 @@ func TestConcede(t *testing.T) {
func TestGameDTO(t *testing.T) {
t.Parallel()
dealer, chall := player.ID{1}, player.ID{2}
dealer, chall := player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}}
g := New(dealer, chall)
{
want := serve.Game{

View File

@ -5,6 +5,8 @@ import (
"sync/atomic"
"testing"
"github.com/google/uuid"
"git.sunturtle.xyz/studio/shotgun/lobby"
"git.sunturtle.xyz/studio/shotgun/player"
)
@ -20,7 +22,7 @@ func TestQueue(t *testing.T) {
for i := 0; i < N; i++ {
i := i
go func() {
id, _, deal := l.Queue(context.Background(), player.ID{uint8(i), uint8(i >> 8)})
id, _, deal := l.Queue(context.Background(), player.ID{UUID: uuid.UUID{uint8(i), uint8(i >> 8)}})
if deal {
dealers.Add(1)
} else {

View File

@ -85,7 +85,7 @@ func Login(ctx context.Context, db RowQuerier, user, pass string) (ID, error) {
slog.ErrorContext(ctx, "login failed", "user", user)
return ID{}, fmt.Errorf("invalid credentials")
}
return ID(id), nil
return ID{id}, nil
}
const initUsers = `CREATE TABLE shotgun_users (

View File

@ -31,7 +31,7 @@ func TestLogin(t *testing.T) {
if err == nil {
t.Errorf("logging in nonexistent user didn't err")
}
if id != uuid.Nil {
if id.UUID != uuid.Nil {
t.Errorf("got nonzero user %v before registering", id)
}
@ -43,7 +43,7 @@ func TestLogin(t *testing.T) {
if err != nil {
t.Errorf("couldn't login after registering: %v", err)
}
if id == uuid.Nil {
if id.UUID == uuid.Nil {
t.Errorf("got zero player id after registering")
}
@ -51,7 +51,7 @@ func TestLogin(t *testing.T) {
if err == nil {
t.Errorf("logged in with wrong password")
}
if wrong != uuid.Nil {
if wrong.UUID != uuid.Nil {
t.Errorf("got nonzero user %v with wrong password (real is %v)", wrong, id)
}
}

View File

@ -4,4 +4,6 @@ package player
import "github.com/google/uuid"
// ID is a unique ID for a player.
type ID = uuid.UUID
type ID struct {
uuid.UUID
}

View File

@ -11,7 +11,9 @@ import (
)
// Session is a session ID.
type Session = uuid.UUID
type Session struct {
uuid.UUID
}
// InitSessions initializes an SQLite table relating player IDs to sessions.
func InitSessions(ctx context.Context, db Execer) error {
@ -32,7 +34,7 @@ func StartSession(ctx context.Context, db Execer, p ID, now time.Time) (Session,
return Session{}, fmt.Errorf("couldn't start session: %w", err)
}
slog.InfoContext(ctx, "session started", "player", p, "session", id, "now", now)
return Session(id), nil
return Session{id}, nil
}
// FromSession gets the player ID associated with a session and updates the

View File

@ -27,13 +27,13 @@ func TestSessions(t *testing.T) {
t.Fatalf("couldn't init sessions: %v", err)
}
p := player.ID{1}
p := player.ID{uuid.UUID{1}}
now := time.Unix(0, 0)
id, err := player.StartSession(ctx, conn, p, now)
if err != nil {
t.Fatalf("couldn't start session: %v", err)
}
if id == uuid.Nil {
if id.UUID == uuid.Nil {
t.Errorf("got zero session id at start")
}
@ -41,7 +41,7 @@ func TestSessions(t *testing.T) {
if err == nil {
t.Errorf("no error on expired session")
}
if u != uuid.Nil {
if u.UUID != uuid.Nil {
t.Errorf("got nonzero player %v from expired session", u)
}
@ -49,7 +49,7 @@ func TestSessions(t *testing.T) {
if err != nil {
t.Errorf("couldn't get player from session: %v", err)
}
if u == uuid.Nil {
if u.UUID == uuid.Nil {
t.Errorf("got zero player from session")
}
@ -57,7 +57,7 @@ func TestSessions(t *testing.T) {
if err != nil {
t.Errorf("couldn't get player from extended session: %v", err)
}
if u == uuid.Nil {
if u.UUID == uuid.Nil {
t.Errorf("got zero player from extended session")
}
@ -69,7 +69,7 @@ func TestSessions(t *testing.T) {
if err == nil {
t.Errorf("no error on logged out session")
}
if u != uuid.Nil {
if u.UUID != uuid.Nil {
t.Errorf("got nonzero player %v from logged out session", u)
}
}

View File

@ -6,6 +6,8 @@ import (
"net/netip"
"strings"
"github.com/google/uuid"
"git.sunturtle.xyz/studio/shotgun/player"
)
@ -21,7 +23,7 @@ func WithPlayerID(next http.Handler) http.Handler {
http.Error(w, "missing or invalid X-Forwarded-For header; check server configuration", http.StatusInternalServerError)
return
}
id := player.ID(addr.As16())
id := player.ID{UUID: uuid.UUID(addr.As16())}
ctx := ctxWith(r.Context(), id)
next.ServeHTTP(w, r.WithContext(ctx))
})