package redisstate import ( "testing" "time" "galaxy/mail/internal/domain/common" deliverydomain "galaxy/mail/internal/domain/delivery" "github.com/stretchr/testify/require" ) func TestKeyspaceBuildsStableKeys(t *testing.T) { t.Parallel() keyspace := Keyspace{} require.Equal(t, "mail:deliveries:ZGVsaXZlcnktMTIz", keyspace.Delivery(common.DeliveryID("delivery-123"))) require.Equal(t, "mail:attempts:ZGVsaXZlcnktMTIz:MQ", keyspace.Attempt(common.DeliveryID("delivery-123"), 1)) require.Equal(t, "mail:idempotency:bm90aWZpY2F0aW9u:bm90aWZpY2F0aW9uOm1haWwtMTIz", keyspace.Idempotency(deliverydomain.SourceNotification, common.IdempotencyKey("notification:mail-123"))) require.Equal(t, "mail:dead_letters:ZGVsaXZlcnktMTIz", keyspace.DeadLetter(common.DeliveryID("delivery-123"))) require.Equal(t, "mail:delivery_commands", keyspace.DeliveryCommands()) require.Equal(t, "mail:attempt_schedule", keyspace.AttemptSchedule()) require.Equal(t, "mail:idx:recipient:cGlsb3RAZXhhbXBsZS5jb20", keyspace.RecipientIndex(common.Email("pilot@example.com"))) require.Equal(t, "mail:idx:status:c2VudA", keyspace.StatusIndex(deliverydomain.StatusSent)) require.Equal(t, "mail:idx:source:bm90aWZpY2F0aW9u", keyspace.SourceIndex(deliverydomain.SourceNotification)) require.Equal(t, "mail:idx:template:YXV0aC5sb2dpbl9jb2Rl", keyspace.TemplateIndex(common.TemplateID("auth.login_code"))) require.Equal(t, "mail:idx:idempotency:bm90aWZpY2F0aW9u:bm90aWZpY2F0aW9uOm1haWwtMTIz", keyspace.IdempotencyIndex(deliverydomain.SourceNotification, common.IdempotencyKey("notification:mail-123"))) require.Equal(t, "mail:idx:created_at", keyspace.CreatedAtIndex()) require.Equal(t, "mail:idx:*", keyspace.SecondaryIndexPattern()) } func TestDeliveryIndexKeysDedupeRecipientsAndIgnoreReplyTo(t *testing.T) { t.Parallel() record := validDelivery(t) record.Source = deliverydomain.SourceNotification record.ResendParentDeliveryID = "" record.Status = deliverydomain.StatusQueued record.SentAt = nil record.LocaleFallbackUsed = false record.UpdatedAt = record.CreatedAt.Add(time.Minute) record.Envelope.Cc = []common.Email{common.Email("pilot@example.com")} record.Envelope.ReplyTo = []common.Email{common.Email("reply@example.com")} require.NoError(t, record.Validate()) require.Equal(t, []string{ "mail:idx:created_at", "mail:idx:idempotency:bm90aWZpY2F0aW9u:b3BlcmF0b3I6cmVzZW5kOmRlbGl2ZXJ5LTEyMw", "mail:idx:recipient:b3BzQGV4YW1wbGUuY29t", "mail:idx:recipient:cGlsb3RAZXhhbXBsZS5jb20", "mail:idx:source:bm90aWZpY2F0aW9u", "mail:idx:status:cXVldWVk", "mail:idx:template:YXV0aC5sb2dpbl9jb2Rl", }, Keyspace{}.DeliveryIndexKeys(record)) } func TestScoresAndRetentionConstants(t *testing.T) { t.Parallel() value := time.Unix(1_775_240_000, 123_000_000).UTC() require.Equal(t, float64(value.UnixMilli()), CreatedAtScore(value)) require.Equal(t, float64(value.UnixMilli()), ScheduledForScore(value)) require.Equal(t, 7*24*time.Hour, IdempotencyTTL) require.Equal(t, 30*24*time.Hour, DeliveryTTL) require.Equal(t, 90*24*time.Hour, AttemptTTL) require.Equal(t, 90*24*time.Hour, DeadLetterTTL) }