package redisstate import ( "context" "testing" "time" "galaxy/mail/internal/domain/common" deliverydomain "galaxy/mail/internal/domain/delivery" "galaxy/mail/internal/service/acceptgenericdelivery" "github.com/alicebob/miniredis/v2" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/require" ) func TestGenericAcceptanceStoreCreateAndReadRenderedDelivery(t *testing.T) { t.Parallel() server := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: server.Addr()}) t.Cleanup(func() { require.NoError(t, client.Close()) }) store, err := NewGenericAcceptanceStore(client) require.NoError(t, err) record := validDelivery(t) record.Source = deliverydomain.SourceNotification record.ResendParentDeliveryID = "" record.PayloadMode = deliverydomain.PayloadModeRendered record.TemplateID = "" record.TemplateVariables = nil record.Locale = "" record.LocaleFallbackUsed = false record.Status = deliverydomain.StatusQueued record.AttemptCount = 1 record.LastAttemptStatus = "" record.ProviderSummary = "" record.SentAt = nil record.UpdatedAt = record.CreatedAt require.NoError(t, record.Validate()) input := acceptgenericdelivery.CreateAcceptanceInput{ Delivery: record, FirstAttempt: validScheduledAttempt(t, record.DeliveryID), DeliveryPayload: ptr(validDeliveryPayload(t, record.DeliveryID)), Idempotency: validIdempotencyRecord(t, record.Source, record.DeliveryID, record.IdempotencyKey), } require.NoError(t, store.CreateAcceptance(context.Background(), input)) storedDelivery, found, err := store.GetDelivery(context.Background(), record.DeliveryID) require.NoError(t, err) require.True(t, found) require.Equal(t, record, storedDelivery) storedPayload, found, err := store.GetDeliveryPayload(context.Background(), record.DeliveryID) require.NoError(t, err) require.True(t, found) require.Equal(t, *input.DeliveryPayload, storedPayload) } func TestGenericAcceptanceStoreReturnsMissingPayload(t *testing.T) { t.Parallel() server := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: server.Addr()}) t.Cleanup(func() { require.NoError(t, client.Close()) }) store, err := NewGenericAcceptanceStore(client) require.NoError(t, err) payload, found, err := store.GetDeliveryPayload(context.Background(), common.DeliveryID("missing")) require.NoError(t, err) require.False(t, found) require.Equal(t, acceptgenericdelivery.DeliveryPayload{}, payload) } func TestMalformedCommandStoreRecordIsIdempotent(t *testing.T) { t.Parallel() server := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: server.Addr()}) t.Cleanup(func() { require.NoError(t, client.Close()) }) store, err := NewMalformedCommandStore(client) require.NoError(t, err) entry := validMalformedCommandEntry(t) require.NoError(t, store.Record(context.Background(), entry)) require.NoError(t, store.Record(context.Background(), entry)) storedEntry, found, err := store.Get(context.Background(), entry.StreamEntryID) require.NoError(t, err) require.True(t, found) require.Equal(t, entry, storedEntry) indexCard, err := client.ZCard(context.Background(), Keyspace{}.MalformedCommandCreatedAtIndex()).Result() require.NoError(t, err) require.EqualValues(t, 1, indexCard) } func TestMalformedCommandStoreAppliesRetention(t *testing.T) { t.Parallel() server := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: server.Addr()}) t.Cleanup(func() { require.NoError(t, client.Close()) }) store, err := NewMalformedCommandStore(client) require.NoError(t, err) entry := validMalformedCommandEntry(t) require.NoError(t, store.Record(context.Background(), entry)) ttl := server.TTL(Keyspace{}.MalformedCommand(entry.StreamEntryID)) require.InDelta(t, DeadLetterTTL.Seconds(), ttl.Seconds(), 1) } func TestStreamOffsetStoreSaveAndLoad(t *testing.T) { t.Parallel() server := miniredis.RunT(t) client := redis.NewClient(&redis.Options{Addr: server.Addr()}) t.Cleanup(func() { require.NoError(t, client.Close()) }) store, err := NewStreamOffsetStore(client) require.NoError(t, err) require.NoError(t, store.Save(context.Background(), "mail:delivery_commands", "1775121700000-0")) entryID, found, err := store.Load(context.Background(), "mail:delivery_commands") require.NoError(t, err) require.True(t, found) require.Equal(t, "1775121700000-0", entryID) payload, err := client.Get(context.Background(), Keyspace{}.StreamOffset("mail:delivery_commands")).Bytes() require.NoError(t, err) offset, err := UnmarshalStreamOffset(payload) require.NoError(t, err) require.Equal(t, "mail:delivery_commands", offset.Stream) require.Equal(t, "1775121700000-0", offset.LastProcessedEntryID) require.WithinDuration(t, time.Now().UTC(), offset.UpdatedAt, time.Second) }