feat: game lobby service

This commit is contained in:
Ilia Denisov
2026-04-25 23:20:55 +02:00
committed by GitHub
parent 32dc29359a
commit 48b0056b49
336 changed files with 57074 additions and 1418 deletions
+91 -42
View File
@@ -21,11 +21,11 @@ func TestUserAccountValidate(t *testing.T) {
wantErr bool
}{
{
name: "valid without declared country",
name: "valid without declared country or display name",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
RaceName: common.RaceName("Pilot Nova"),
UserName: common.UserName("player-abcdefgh"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
@@ -33,11 +33,12 @@ func TestUserAccountValidate(t *testing.T) {
},
},
{
name: "valid with declared country",
name: "valid with declared country and display name",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
RaceName: common.RaceName("Pilot Nova"),
UserName: common.UserName("player-abcdefgh"),
DisplayName: common.DisplayName("PilotNova"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
DeclaredCountry: common.CountryCode("DE"),
@@ -45,12 +46,38 @@ func TestUserAccountValidate(t *testing.T) {
UpdatedAt: updatedAt,
},
},
{
name: "missing user name",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
},
wantErr: true,
},
{
name: "invalid display name",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
UserName: common.UserName("player-abcdefgh"),
DisplayName: common.DisplayName("Pilot Nova"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
},
wantErr: true,
},
{
name: "updated before created",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
RaceName: common.RaceName("Pilot Nova"),
UserName: common.UserName("player-abcdefgh"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
@@ -58,53 +85,50 @@ func TestUserAccountValidate(t *testing.T) {
},
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := tt.record.Validate()
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}
func TestRaceNameReservationValidate(t *testing.T) {
t.Parallel()
tests := []struct {
name string
record RaceNameReservation
wantErr bool
}{
{
name: "valid",
record: RaceNameReservation{
CanonicalKey: RaceNameCanonicalKey("pilot-nova"),
UserID: common.UserID("user-123"),
RaceName: common.RaceName("Pilot Nova"),
ReservedAt: time.Unix(1_775_240_100, 0).UTC(),
name: "valid soft-deleted after update",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
UserName: common.UserName("player-abcdefgh"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
DeletedAt: timePtr(updatedAt),
},
},
{
name: "empty canonical key",
record: RaceNameReservation{
UserID: common.UserID("user-123"),
RaceName: common.RaceName("Pilot Nova"),
ReservedAt: time.Unix(1_775_240_100, 0).UTC(),
name: "deleted at before created",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
UserName: common.UserName("player-abcdefgh"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
DeletedAt: timePtr(createdAt.Add(-time.Second)),
},
wantErr: true,
},
{
name: "deleted at zero",
record: UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
UserName: common.UserName("player-abcdefgh"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
UpdatedAt: updatedAt,
DeletedAt: timePtr(time.Time{}),
},
wantErr: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
@@ -117,3 +141,28 @@ func TestRaceNameReservationValidate(t *testing.T) {
})
}
}
func TestUserAccountIsDeleted(t *testing.T) {
t.Parallel()
createdAt := time.Unix(1_775_240_000, 0).UTC()
record := UserAccount{
UserID: common.UserID("user-123"),
Email: common.Email("pilot@example.com"),
UserName: common.UserName("player-abcdefgh"),
PreferredLanguage: common.LanguageTag("en"),
TimeZone: common.TimeZoneName("Europe/Berlin"),
CreatedAt: createdAt,
UpdatedAt: createdAt,
}
require.False(t, record.IsDeleted())
deleted := record
deletedAt := createdAt.Add(time.Minute)
deleted.DeletedAt = &deletedAt
require.True(t, deleted.IsDeleted())
}
func timePtr(value time.Time) *time.Time {
return &value
}