package getdelivery import ( "context" "errors" "testing" "time" "galaxy/mail/internal/domain/common" deliverydomain "galaxy/mail/internal/domain/delivery" "github.com/stretchr/testify/require" ) func TestServiceExecuteReturnsDeliveryWithoutDeadLetter(t *testing.T) { t.Parallel() store := &stubStore{ delivery: ptrDelivery(validSentDelivery()), } service := newTestService(t, Config{Store: store}) result, err := service.Execute(context.Background(), Input{DeliveryID: store.delivery.DeliveryID}) require.NoError(t, err) require.Equal(t, *store.delivery, result.Delivery) require.Nil(t, result.DeadLetter) } func TestServiceExecuteReturnsDeadLetterEntry(t *testing.T) { t.Parallel() record := validDeadLetterDelivery() entry := validDeadLetterEntry(record.DeliveryID) store := &stubStore{ delivery: &record, deadLetter: &entry, } service := newTestService(t, Config{Store: store}) result, err := service.Execute(context.Background(), Input{DeliveryID: record.DeliveryID}) require.NoError(t, err) require.Equal(t, record, result.Delivery) require.NotNil(t, result.DeadLetter) require.Equal(t, entry, *result.DeadLetter) } func TestServiceExecuteReturnsNotFound(t *testing.T) { t.Parallel() service := newTestService(t, Config{Store: &stubStore{}}) _, err := service.Execute(context.Background(), Input{DeliveryID: common.DeliveryID("missing")}) require.ErrorIs(t, err, ErrNotFound) } type stubStore struct { delivery *deliverydomain.Delivery deadLetter *deliverydomain.DeadLetterEntry getDeliveryErr error getDeadErr error } func (store *stubStore) GetDelivery(context.Context, common.DeliveryID) (deliverydomain.Delivery, bool, error) { if store.getDeliveryErr != nil { return deliverydomain.Delivery{}, false, store.getDeliveryErr } if store.delivery == nil { return deliverydomain.Delivery{}, false, nil } return *store.delivery, true, nil } func (store *stubStore) GetDeadLetter(context.Context, common.DeliveryID) (deliverydomain.DeadLetterEntry, bool, error) { if store.getDeadErr != nil { return deliverydomain.DeadLetterEntry{}, false, store.getDeadErr } if store.deadLetter == nil { return deliverydomain.DeadLetterEntry{}, false, nil } return *store.deadLetter, true, nil } func newTestService(t *testing.T, cfg Config) *Service { t.Helper() service, err := New(cfg) require.NoError(t, err) return service } func validSentDelivery() deliverydomain.Delivery { createdAt := time.Unix(1_775_121_700, 0).UTC() updatedAt := createdAt.Add(time.Minute) sentAt := updatedAt.Add(time.Second) record := deliverydomain.Delivery{ DeliveryID: common.DeliveryID("delivery-sent"), Source: deliverydomain.SourceNotification, PayloadMode: deliverydomain.PayloadModeRendered, Envelope: deliverydomain.Envelope{To: []common.Email{common.Email("pilot@example.com")}}, Content: deliverydomain.Content{Subject: "Ready", TextBody: "Turn ready"}, IdempotencyKey: common.IdempotencyKey("notification:delivery-sent"), Status: deliverydomain.StatusSent, AttemptCount: 1, CreatedAt: createdAt, UpdatedAt: updatedAt, SentAt: &sentAt, } if err := record.Validate(); err != nil { panic(err) } return record } func validDeadLetterDelivery() deliverydomain.Delivery { record := validSentDelivery() record.DeliveryID = common.DeliveryID("delivery-dead-letter") record.IdempotencyKey = common.IdempotencyKey("notification:delivery-dead-letter") record.Status = deliverydomain.StatusDeadLetter record.UpdatedAt = record.CreatedAt.Add(2 * time.Minute) record.SentAt = nil deadLetteredAt := record.UpdatedAt record.DeadLetteredAt = &deadLetteredAt if err := record.Validate(); err != nil { panic(err) } return record } func validDeadLetterEntry(deliveryID common.DeliveryID) deliverydomain.DeadLetterEntry { entry := deliverydomain.DeadLetterEntry{ DeliveryID: deliveryID, FinalAttemptNo: 1, FailureClassification: "retry_exhausted", ProviderSummary: "smtp timeout", CreatedAt: time.Unix(1_775_121_900, 0).UTC(), RecoveryHint: "check SMTP connectivity", } if err := entry.Validate(); err != nil { panic(err) } return entry } func ptrDelivery(record deliverydomain.Delivery) *deliverydomain.Delivery { return &record } var _ Store = (*stubStore)(nil) var _ = errors.New