package domainevents import ( "context" "strconv" "testing" "time" "galaxy/user/internal/domain/common" "galaxy/user/internal/ports" "github.com/alicebob/miniredis/v2" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/require" ) func TestPublisherPublishesFlatRedisStreamEntry(t *testing.T) { t.Parallel() server := miniredis.RunT(t) publisher, err := New(redis.NewClient(&redis.Options{Addr: server.Addr()}), Config{ Stream: "user:test_events", StreamMaxLen: 5, OperationTimeout: time.Second, }) require.NoError(t, err) occurredAt := time.Unix(1_775_240_000, 0).UTC() err = publisher.PublishProfileChanged(context.Background(), ports.ProfileChangedEvent{ UserID: common.UserID("user-123"), OccurredAt: occurredAt, Source: common.Source("gateway_self_service"), TraceID: "4bf92f3577b34da6a3ce929d0e0e4736", Operation: ports.ProfileChangedOperationUpdated, UserName: common.UserName("player-abcdefgh"), DisplayName: common.DisplayName("NovaPrime"), }) require.NoError(t, err) entries, err := publisher.client.XRange(context.Background(), publisher.stream, "-", "+").Result() require.NoError(t, err) require.Len(t, entries, 1) require.Equal(t, ports.ProfileChangedEventType, entries[0].Values["event_type"]) require.Equal(t, "user-123", entries[0].Values["user_id"]) require.Equal(t, strconv.FormatInt(occurredAt.UnixMilli(), 10), entries[0].Values["occurred_at_ms"]) require.Equal(t, "gateway_self_service", entries[0].Values["source"]) require.Equal(t, "4bf92f3577b34da6a3ce929d0e0e4736", entries[0].Values["trace_id"]) require.Equal(t, string(ports.ProfileChangedOperationUpdated), entries[0].Values["operation"]) require.Equal(t, "player-abcdefgh", entries[0].Values["user_name"]) require.Equal(t, "NovaPrime", entries[0].Values["display_name"]) for index := 0; index < 20; index++ { err = publisher.PublishSettingsChanged(context.Background(), ports.SettingsChangedEvent{ UserID: common.UserID("user-123"), OccurredAt: occurredAt.Add(time.Duration(index+1) * time.Second), Source: common.Source("gateway_self_service"), Operation: ports.SettingsChangedOperationUpdated, PreferredLanguage: common.LanguageTag("en-US"), TimeZone: common.TimeZoneName("UTC"), }) require.NoError(t, err) } length, err := publisher.client.XLen(context.Background(), publisher.stream).Result() require.NoError(t, err) require.LessOrEqual(t, length, int64(20)) } func TestPublisherRejectsInvalidEventBeforeXAdd(t *testing.T) { t.Parallel() server := miniredis.RunT(t) publisher, err := New(redis.NewClient(&redis.Options{Addr: server.Addr()}), Config{ Stream: "user:test_events", StreamMaxLen: 5, OperationTimeout: time.Second, }) require.NoError(t, err) err = publisher.PublishProfileChanged(context.Background(), ports.ProfileChangedEvent{ UserID: common.UserID("user-123"), OccurredAt: time.Unix(1_775_240_000, 0).UTC(), Operation: ports.ProfileChangedOperationUpdated, UserName: common.UserName("player-abcdefgh"), DisplayName: common.DisplayName("NovaPrime"), }) require.Error(t, err) length, xLenErr := publisher.client.XLen(context.Background(), publisher.stream).Result() require.NoError(t, xLenErr) require.Zero(t, length) }