202 lines
6.5 KiB
Go
202 lines
6.5 KiB
Go
package redisstate
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"time"
|
|
|
|
"galaxy/mail/internal/domain/attempt"
|
|
"galaxy/mail/internal/domain/common"
|
|
deliverydomain "galaxy/mail/internal/domain/delivery"
|
|
"galaxy/mail/internal/domain/idempotency"
|
|
"galaxy/mail/internal/domain/malformedcommand"
|
|
"galaxy/mail/internal/service/acceptgenericdelivery"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func validDelivery(t require.TestingT) deliverydomain.Delivery {
|
|
locale, err := common.ParseLocale("fr-fr")
|
|
require.NoError(t, err)
|
|
|
|
createdAt := time.Unix(1_775_121_700, 0).UTC()
|
|
updatedAt := createdAt.Add(2 * time.Minute)
|
|
sentAt := updatedAt.Add(15 * time.Second)
|
|
|
|
record := deliverydomain.Delivery{
|
|
DeliveryID: common.DeliveryID("delivery-123"),
|
|
ResendParentDeliveryID: common.DeliveryID("delivery-parent-001"),
|
|
Source: deliverydomain.SourceOperatorResend,
|
|
PayloadMode: deliverydomain.PayloadModeTemplate,
|
|
TemplateID: common.TemplateID("auth.login_code"),
|
|
Envelope: deliverydomain.Envelope{
|
|
To: []common.Email{common.Email("pilot@example.com")},
|
|
Cc: []common.Email{common.Email("copilot@example.com")},
|
|
Bcc: []common.Email{common.Email("ops@example.com")},
|
|
ReplyTo: []common.Email{common.Email("noreply@example.com")},
|
|
},
|
|
Content: deliverydomain.Content{
|
|
Subject: "Your login code",
|
|
TextBody: "Code: 123456",
|
|
HTMLBody: "<p>Code: <strong>123456</strong></p>",
|
|
},
|
|
Attachments: []common.AttachmentMetadata{
|
|
{Filename: "instructions.txt", ContentType: "text/plain; charset=utf-8", SizeBytes: 128},
|
|
},
|
|
Locale: locale,
|
|
TemplateVariables: map[string]any{
|
|
"code": "123456",
|
|
},
|
|
LocaleFallbackUsed: true,
|
|
IdempotencyKey: common.IdempotencyKey("operator:resend:delivery-123"),
|
|
Status: deliverydomain.StatusSent,
|
|
AttemptCount: 2,
|
|
LastAttemptStatus: attempt.StatusProviderAccepted,
|
|
ProviderSummary: "queued by provider",
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
SentAt: &sentAt,
|
|
}
|
|
require.NoError(t, record.Validate())
|
|
|
|
return record
|
|
}
|
|
|
|
func validScheduledAttempt(t require.TestingT, deliveryID common.DeliveryID) attempt.Attempt {
|
|
scheduledFor := time.Unix(1_775_121_820, 0).UTC()
|
|
|
|
record := attempt.Attempt{
|
|
DeliveryID: deliveryID,
|
|
AttemptNo: 1,
|
|
ScheduledFor: scheduledFor,
|
|
Status: attempt.StatusScheduled,
|
|
}
|
|
require.NoError(t, record.Validate())
|
|
|
|
return record
|
|
}
|
|
|
|
func validQueuedTemplateDelivery(t require.TestingT) deliverydomain.Delivery {
|
|
record := validDelivery(t)
|
|
record.DeliveryID = common.DeliveryID("delivery-queued")
|
|
record.ResendParentDeliveryID = ""
|
|
record.Source = deliverydomain.SourceNotification
|
|
record.Status = deliverydomain.StatusQueued
|
|
record.AttemptCount = 1
|
|
record.LastAttemptStatus = ""
|
|
record.ProviderSummary = ""
|
|
record.LocaleFallbackUsed = false
|
|
record.Content = deliverydomain.Content{}
|
|
record.CreatedAt = time.Unix(1_775_121_700, 0).UTC()
|
|
record.UpdatedAt = record.CreatedAt
|
|
record.SentAt = nil
|
|
record.SuppressedAt = nil
|
|
record.FailedAt = nil
|
|
record.DeadLetteredAt = nil
|
|
record.IdempotencyKey = common.IdempotencyKey("notification:delivery-queued")
|
|
require.NoError(t, record.Validate())
|
|
|
|
return record
|
|
}
|
|
|
|
func validTerminalAttempt(t require.TestingT, deliveryID common.DeliveryID) attempt.Attempt {
|
|
scheduledFor := time.Unix(1_775_121_820, 0).UTC()
|
|
startedAt := scheduledFor.Add(5 * time.Second)
|
|
finishedAt := startedAt.Add(2 * time.Second)
|
|
|
|
record := attempt.Attempt{
|
|
DeliveryID: deliveryID,
|
|
AttemptNo: 2,
|
|
ScheduledFor: scheduledFor,
|
|
StartedAt: &startedAt,
|
|
FinishedAt: &finishedAt,
|
|
Status: attempt.StatusProviderAccepted,
|
|
ProviderClassification: "accepted",
|
|
ProviderSummary: "queued by provider",
|
|
}
|
|
require.NoError(t, record.Validate())
|
|
|
|
return record
|
|
}
|
|
|
|
func validRenderFailedAttempt(t require.TestingT, deliveryID common.DeliveryID) attempt.Attempt {
|
|
record := validScheduledAttempt(t, deliveryID)
|
|
startedAt := record.ScheduledFor.Add(time.Second)
|
|
finishedAt := startedAt
|
|
record.StartedAt = &startedAt
|
|
record.FinishedAt = &finishedAt
|
|
record.Status = attempt.StatusRenderFailed
|
|
record.ProviderClassification = "missing_required_variable"
|
|
record.ProviderSummary = "missing required variables: player.name"
|
|
require.NoError(t, record.Validate())
|
|
|
|
return record
|
|
}
|
|
|
|
func validIdempotencyRecord(t require.TestingT, source deliverydomain.Source, deliveryID common.DeliveryID, key common.IdempotencyKey) idempotency.Record {
|
|
createdAt := time.Now().UTC().Truncate(time.Millisecond).Add(-time.Minute)
|
|
|
|
record := idempotency.Record{
|
|
Source: source,
|
|
IdempotencyKey: key,
|
|
DeliveryID: deliveryID,
|
|
RequestFingerprint: "sha256:abcdef123456",
|
|
CreatedAt: createdAt,
|
|
ExpiresAt: createdAt.Add(IdempotencyTTL),
|
|
}
|
|
require.NoError(t, record.Validate())
|
|
|
|
return record
|
|
}
|
|
|
|
func validDeadLetterEntry(t require.TestingT, deliveryID common.DeliveryID) deliverydomain.DeadLetterEntry {
|
|
entry := deliverydomain.DeadLetterEntry{
|
|
DeliveryID: deliveryID,
|
|
FinalAttemptNo: 3,
|
|
FailureClassification: "retry_exhausted",
|
|
ProviderSummary: "smtp timeout",
|
|
CreatedAt: time.Unix(1_775_122_000, 0).UTC(),
|
|
RecoveryHint: "check SMTP connectivity",
|
|
}
|
|
require.NoError(t, entry.Validate())
|
|
|
|
return entry
|
|
}
|
|
|
|
func validDeliveryPayload(t require.TestingT, deliveryID common.DeliveryID) acceptgenericdelivery.DeliveryPayload {
|
|
payload := acceptgenericdelivery.DeliveryPayload{
|
|
DeliveryID: deliveryID,
|
|
Attachments: []acceptgenericdelivery.AttachmentPayload{
|
|
{
|
|
Filename: "instructions.txt",
|
|
ContentType: "text/plain; charset=utf-8",
|
|
ContentBase64: base64.StdEncoding.EncodeToString([]byte("read me")),
|
|
SizeBytes: int64(len([]byte("read me"))),
|
|
},
|
|
},
|
|
}
|
|
require.NoError(t, payload.Validate())
|
|
|
|
return payload
|
|
}
|
|
|
|
func validMalformedCommandEntry(t require.TestingT) malformedcommand.Entry {
|
|
entry := malformedcommand.Entry{
|
|
StreamEntryID: "1775121700000-0",
|
|
DeliveryID: "mail-123",
|
|
Source: "notification",
|
|
IdempotencyKey: "notification:mail-123",
|
|
FailureCode: malformedcommand.FailureCodeInvalidPayload,
|
|
FailureMessage: "payload_json.subject is required",
|
|
RawFields: map[string]any{
|
|
"delivery_id": "mail-123",
|
|
"source": "notification",
|
|
"payload_mode": "rendered",
|
|
"idempotency_key": "notification:mail-123",
|
|
},
|
|
RecordedAt: time.Unix(1_775_121_700, 0).UTC(),
|
|
}
|
|
require.NoError(t, entry.Validate())
|
|
|
|
return entry
|
|
}
|