package idgen import ( "bytes" "io" "strings" "testing" "galaxy/lobby/internal/domain/common" "github.com/stretchr/testify/require" ) func TestNewGameIDShape(t *testing.T) { t.Parallel() gen := NewGenerator() gameID, err := gen.NewGameID() require.NoError(t, err) require.NoError(t, gameID.Validate()) require.True(t, strings.HasPrefix(gameID.String(), "game-")) require.Equal(t, strings.ToLower(gameID.String()), gameID.String()) } func TestNewGameIDDeterministicWithFixedReader(t *testing.T) { t.Parallel() source := bytes.NewReader(bytes.Repeat([]byte{0x00}, gameIDTokenBytes*2)) gen := NewGenerator(WithRandomSource(source)) first, err := gen.NewGameID() require.NoError(t, err) require.Equal(t, common.GameID("game-aaaaaaaaaaaaaaaa"), first) second, err := gen.NewGameID() require.NoError(t, err) require.Equal(t, common.GameID("game-aaaaaaaaaaaaaaaa"), second) } func TestNewGameIDUniquenessOverManyDraws(t *testing.T) { t.Parallel() gen := NewGenerator() seen := make(map[common.GameID]struct{}, 1024) for i := range 1024 { gameID, err := gen.NewGameID() require.NoError(t, err) _, dup := seen[gameID] require.False(t, dup, "duplicate game id %q on draw %d", gameID, i) seen[gameID] = struct{}{} } } func TestNewGameIDSourceError(t *testing.T) { t.Parallel() gen := NewGenerator(WithRandomSource(failingReader{})) _, err := gen.NewGameID() require.Error(t, err) require.Contains(t, err.Error(), "generate game id") } func TestNewApplicationIDShape(t *testing.T) { t.Parallel() gen := NewGenerator() applicationID, err := gen.NewApplicationID() require.NoError(t, err) require.NoError(t, applicationID.Validate()) require.True(t, strings.HasPrefix(applicationID.String(), "application-")) require.Equal(t, strings.ToLower(applicationID.String()), applicationID.String()) } func TestNewApplicationIDDeterministicWithFixedReader(t *testing.T) { t.Parallel() source := bytes.NewReader(bytes.Repeat([]byte{0x00}, applicationIDTokenBytes*2)) gen := NewGenerator(WithRandomSource(source)) first, err := gen.NewApplicationID() require.NoError(t, err) require.Equal(t, common.ApplicationID("application-aaaaaaaaaaaaaaaa"), first) second, err := gen.NewApplicationID() require.NoError(t, err) require.Equal(t, common.ApplicationID("application-aaaaaaaaaaaaaaaa"), second) } func TestNewApplicationIDUniquenessOverManyDraws(t *testing.T) { t.Parallel() gen := NewGenerator() seen := make(map[common.ApplicationID]struct{}, 1024) for i := range 1024 { applicationID, err := gen.NewApplicationID() require.NoError(t, err) _, dup := seen[applicationID] require.False(t, dup, "duplicate application id %q on draw %d", applicationID, i) seen[applicationID] = struct{}{} } } func TestNewApplicationIDSourceError(t *testing.T) { t.Parallel() gen := NewGenerator(WithRandomSource(failingReader{})) _, err := gen.NewApplicationID() require.Error(t, err) require.Contains(t, err.Error(), "generate application id") } func TestNewInviteIDShape(t *testing.T) { t.Parallel() gen := NewGenerator() inviteID, err := gen.NewInviteID() require.NoError(t, err) require.NoError(t, inviteID.Validate()) require.True(t, strings.HasPrefix(inviteID.String(), "invite-")) require.Equal(t, strings.ToLower(inviteID.String()), inviteID.String()) } func TestNewInviteIDDeterministicWithFixedReader(t *testing.T) { t.Parallel() source := bytes.NewReader(bytes.Repeat([]byte{0x00}, inviteIDTokenBytes*2)) gen := NewGenerator(WithRandomSource(source)) first, err := gen.NewInviteID() require.NoError(t, err) require.Equal(t, common.InviteID("invite-aaaaaaaaaaaaaaaa"), first) second, err := gen.NewInviteID() require.NoError(t, err) require.Equal(t, common.InviteID("invite-aaaaaaaaaaaaaaaa"), second) } func TestNewInviteIDUniquenessOverManyDraws(t *testing.T) { t.Parallel() gen := NewGenerator() seen := make(map[common.InviteID]struct{}, 1024) for i := range 1024 { inviteID, err := gen.NewInviteID() require.NoError(t, err) _, dup := seen[inviteID] require.False(t, dup, "duplicate invite id %q on draw %d", inviteID, i) seen[inviteID] = struct{}{} } } func TestNewInviteIDSourceError(t *testing.T) { t.Parallel() gen := NewGenerator(WithRandomSource(failingReader{})) _, err := gen.NewInviteID() require.Error(t, err) require.Contains(t, err.Error(), "generate invite id") } func TestNewMembershipIDShape(t *testing.T) { t.Parallel() gen := NewGenerator() membershipID, err := gen.NewMembershipID() require.NoError(t, err) require.NoError(t, membershipID.Validate()) require.True(t, strings.HasPrefix(membershipID.String(), "membership-")) require.Equal(t, strings.ToLower(membershipID.String()), membershipID.String()) } func TestNewMembershipIDDeterministicWithFixedReader(t *testing.T) { t.Parallel() source := bytes.NewReader(bytes.Repeat([]byte{0x00}, membershipIDTokenBytes*2)) gen := NewGenerator(WithRandomSource(source)) first, err := gen.NewMembershipID() require.NoError(t, err) require.Equal(t, common.MembershipID("membership-aaaaaaaaaaaaaaaa"), first) second, err := gen.NewMembershipID() require.NoError(t, err) require.Equal(t, common.MembershipID("membership-aaaaaaaaaaaaaaaa"), second) } func TestNewMembershipIDUniquenessOverManyDraws(t *testing.T) { t.Parallel() gen := NewGenerator() seen := make(map[common.MembershipID]struct{}, 1024) for i := range 1024 { membershipID, err := gen.NewMembershipID() require.NoError(t, err) _, dup := seen[membershipID] require.False(t, dup, "duplicate membership id %q on draw %d", membershipID, i) seen[membershipID] = struct{}{} } } func TestNewMembershipIDSourceError(t *testing.T) { t.Parallel() gen := NewGenerator(WithRandomSource(failingReader{})) _, err := gen.NewMembershipID() require.Error(t, err) require.Contains(t, err.Error(), "generate membership id") } type failingReader struct{} func (failingReader) Read(_ []byte) (int, error) { return 0, io.ErrUnexpectedEOF }