65 lines
2.0 KiB
Go
65 lines
2.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.sendico.io/tech/sxchnge/notifications/email"
|
|
"git.sendico.io/tech/sxchnge/notifications/model"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type workerRepo struct {
|
|
Repository
|
|
job model.Notification
|
|
saved *model.Notification
|
|
}
|
|
|
|
func (r *workerRepo) Recover(context.Context, time.Time) error { return nil }
|
|
func (r *workerRepo) Claim(context.Context, string, time.Time) (*model.Notification, error) {
|
|
n := r.job
|
|
return &n, nil
|
|
}
|
|
func (r *workerRepo) Finish(_ context.Context, n *model.Notification) error { r.saved = n; return nil }
|
|
|
|
type workerSender struct {
|
|
calls int
|
|
outcome email.Outcome
|
|
}
|
|
|
|
func (s *workerSender) Send(context.Context, string, model.Email) email.Outcome {
|
|
s.calls++
|
|
return s.outcome
|
|
}
|
|
func TestWorkerTerminalAndRetryOutcomes(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
expiry time.Time
|
|
driver string
|
|
attempts uint32
|
|
outcome model.State
|
|
want model.State
|
|
calls int
|
|
}{
|
|
{"expired", time.Now().Add(-time.Minute), "resend", 1, model.Accepted, model.Expired, 0},
|
|
{"driver changed", time.Now().Add(time.Hour), "sendgrid", 1, model.Accepted, model.Failed, 0},
|
|
{"retry exhausted", time.Now().Add(time.Hour), "resend", 5, model.RetryWait, model.Failed, 1},
|
|
{"retry expiry", time.Now().Add(time.Second), "resend", 1, model.RetryWait, model.Expired, 1},
|
|
{"ambiguous", time.Now().Add(time.Hour), "resend", 1, model.Unknown, model.Unknown, 1},
|
|
{"invalid driver outcome", time.Now().Add(time.Hour), "resend", 1, model.Queued, model.Unknown, 1},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
repo := &workerRepo{job: model.Notification{Driver: tc.driver, ExpiresAt: tc.expiry, Attempts: tc.attempts}}
|
|
sender := &workerSender{outcome: email.Outcome{State: tc.outcome}}
|
|
svc := New(repo, nil, sender, "resend", zap.NewNop())
|
|
if _, err := svc.Dispatch(context.Background(), "id"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if repo.saved == nil || repo.saved.State != tc.want || sender.calls != tc.calls {
|
|
t.Fatal(repo.saved, sender.calls)
|
|
}
|
|
})
|
|
}
|
|
}
|