Files

106 lines
3.7 KiB
Go

package email
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"git.sendico.io/tech/sxchnge/notifications/model"
)
func TestDriversRenderWirePayload(t *testing.T) {
for _, driver := range []Driver{SendGrid, Resend} {
t.Run(string(driver), func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer test-secret" {
t.Error("missing authorization")
}
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
t.Error(err)
}
if body["subject"] != "Completed" {
t.Errorf("subject: %v", body)
}
if driver == SendGrid {
if body["template_id"] != nil {
t.Error("provider-managed templates must not be used")
}
p := body["personalizations"].([]any)[0].(map[string]any)
if p["to"].([]any)[0].(map[string]any)["email"] != "user@example.com" {
t.Error("wrong recipient")
}
content := body["content"].([]any)
if len(content) != 2 || content[1].(map[string]any)["value"] != "<p>A &amp; B</p>" {
t.Error("wrong body")
}
} else {
if r.Header.Get("Idempotency-Key") != "delivery-id" {
t.Error("missing idempotency key")
}
if body["html"] != "<p>A &amp; B</p>" || body["text"] != "A & B" {
t.Error("wrong body")
}
}
w.WriteHeader(http.StatusAccepted)
}))
defer server.Close()
c := client{http: server.Client(), key: "test-secret", endpoint: server.URL, settings: Settings{SenderAddress: "sender@example.com", SenderName: "SXCHNGE"}}
var sender Sender = &sendgrid{c}
if driver == Resend {
sender = &resend{c}
}
outcome := sender.Send(context.Background(), "delivery-id", model.Email{Address: "user@example.com", Subject: "Completed", HTML: "<p>A &amp; B</p>", Text: "A & B"})
if outcome.State != model.Accepted {
t.Fatal(outcome)
}
})
}
}
func TestProviderFailures(t *testing.T) {
for _, tc := range []struct {
code int
state model.State
}{{429, model.RetryWait}, {400, model.Failed}, {401, model.Failed}, {403, model.Failed}, {500, model.Unknown}, {408, model.Unknown}, {302, model.Failed}} {
t.Run(http.StatusText(tc.code), func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Retry-After", "120")
w.WriteHeader(tc.code)
_, _ = w.Write([]byte("secret provider response"))
}))
defer server.Close()
c := client{http: server.Client(), endpoint: server.URL}
out := c.post(context.Background(), "", struct{}{})
if out.State != tc.state || strings.Contains(out.Code, "secret") {
t.Fatal(out)
}
if tc.code == 429 && out.RetryAfter != 2*time.Minute {
t.Fatal(out)
}
})
}
ctx, cancel := context.WithCancel(context.Background())
cancel()
c := client{http: http.DefaultClient, endpoint: "http://127.0.0.1:1"}
if out := c.post(ctx, "", struct{}{}); out.State != model.Unknown {
t.Fatal(out)
}
}
func TestDriverConfig(t *testing.T) {
t.Setenv("EMAIL_TEST_KEY", "secret")
for _, driver := range []Driver{SendGrid, Resend} {
if _, err := New(Config{Driver: driver, Settings: map[string]any{"api_key_env": "EMAIL_TEST_KEY", "sender_address": "sender@example.com"}}); err != nil {
t.Fatal(err)
}
}
for _, settings := range []map[string]any{{"api_key_env": "MISSING_KEY", "sender_address": "sender@example.com"}, {"api_key_env": "EMAIL_TEST_KEY", "sender_address": "bad"}, {"api_key_env": "EMAIL_TEST_KEY", "sender_address": "sender@example.com", "typo": true}} {
if _, err := New(Config{Driver: Resend, Settings: settings}); err == nil {
t.Fatal("accepted invalid driver config")
}
}
}