155 lines
4.3 KiB
Go
155 lines
4.3 KiB
Go
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
|