81 lines
2.3 KiB
Go
81 lines
2.3 KiB
Go
|
|
package email_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"gateway/internal/model/notification/provider/email"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
)
|
||
|
|
|
||
|
|
const testRecipientEmail = "x@test.com"
|
||
|
|
|
||
|
|
func TestChain_Send_FailoverToSecondProvider(t *testing.T) {
|
||
|
|
primary := email.NewMockSender(
|
||
|
|
email.WithMockName("primary"),
|
||
|
|
email.WithMockSort(1),
|
||
|
|
email.WithMockError(fmt.Errorf("primary down")),
|
||
|
|
)
|
||
|
|
backup := email.NewMockSender(
|
||
|
|
email.WithMockName("backup"),
|
||
|
|
email.WithMockSort(2),
|
||
|
|
email.WithMockMessageID("backup-123"),
|
||
|
|
)
|
||
|
|
|
||
|
|
chain := email.NewChain(primary, backup)
|
||
|
|
provider, id, err := chain.Send(context.Background(), &email.Message{
|
||
|
|
From: "noreply@test.com",
|
||
|
|
To: []string{"user@test.com"},
|
||
|
|
Subject: "verify",
|
||
|
|
Body: "<p>code</p>",
|
||
|
|
})
|
||
|
|
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.Equal(t, "backup", provider)
|
||
|
|
assert.Equal(t, "backup-123", id)
|
||
|
|
assert.Len(t, primary.Calls(), 1)
|
||
|
|
assert.Len(t, backup.Calls(), 1)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestChain_Send_TriesLowerSortFirst(t *testing.T) {
|
||
|
|
var order []string
|
||
|
|
mk := func(name string, sort int, fail bool) *email.MockSender {
|
||
|
|
m := email.NewMockSender(email.WithMockName(name), email.WithMockSort(sort))
|
||
|
|
m.SendHook = func(context.Context, *email.Message) (string, error) {
|
||
|
|
order = append(order, name)
|
||
|
|
if fail {
|
||
|
|
return "", fmt.Errorf("%s failed", name)
|
||
|
|
}
|
||
|
|
return name + "-id", nil
|
||
|
|
}
|
||
|
|
return m
|
||
|
|
}
|
||
|
|
|
||
|
|
// Unsorted registration; chain must try a(1) → b(2) succeed, never c(3).
|
||
|
|
chain := email.NewChain(mk("c", 3, true), mk("a", 1, true), mk("b", 2, false))
|
||
|
|
provider, _, err := chain.Send(context.Background(), &email.Message{To: []string{testRecipientEmail}})
|
||
|
|
require.NoError(t, err)
|
||
|
|
assert.Equal(t, "b", provider)
|
||
|
|
assert.Equal(t, []string{"a", "b"}, order)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestChain_Send_AllProvidersFail(t *testing.T) {
|
||
|
|
chain := email.NewChain(
|
||
|
|
email.ErrSender("a", 1, fmt.Errorf("a fail")),
|
||
|
|
email.ErrSender("b", 2, fmt.Errorf("b fail")),
|
||
|
|
)
|
||
|
|
_, _, err := chain.Send(context.Background(), &email.Message{To: []string{testRecipientEmail}})
|
||
|
|
require.Error(t, err)
|
||
|
|
assert.Contains(t, err.Error(), "all providers failed")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestChain_Send_NoSenders(t *testing.T) {
|
||
|
|
chain := email.NewChain()
|
||
|
|
_, _, err := chain.Send(context.Background(), &email.Message{To: []string{testRecipientEmail}})
|
||
|
|
require.Error(t, err)
|
||
|
|
assert.Contains(t, err.Error(), "no senders")
|
||
|
|
}
|