test(04-04): close mail safety and Mailpit SMTP receipt coverage

- Assert memory recipients, HTML safety, and SMTP TLS without credential leaks
- Prove real SMTP delivery through Mailpit HTTP API when Docker is available
- Add scripts/check-phase4.sh as the phase vet, test, race, and SMTP gate

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jakub Zych
2026-09-18 14:12:28 +02:00
parent 918e941e69
commit 9f6fbadce8
5 changed files with 414 additions and 0 deletions

65
postcard/smtp_test.go Normal file
View File

@@ -0,0 +1,65 @@
package postcard
import (
"context"
"strings"
"testing"
"time"
)
func TestSMTPTLSPolicy(t *testing.T) {
t.Parallel()
for _, tls := range []string{"", "mandatory", "tls", "none", "notls", "starttls", "opportunistic"} {
_, err := NewSMTPDriver(SMTPConfig{Host: "127.0.0.1", Port: 1025, TLS: tls, Timeout: time.Second})
if err != nil {
t.Fatalf("tls %q: %v", tls, err)
}
}
_, err := NewSMTPDriver(SMTPConfig{Host: "127.0.0.1", TLS: "maybe"})
if err == nil || !strings.Contains(err.Error(), "mail.smtp.tls") {
t.Fatalf("unknown tls error = %v", err)
}
_, err = NewSMTPDriver(SMTPConfig{TLS: "none"})
if err == nil || !strings.Contains(err.Error(), "mail.smtp.host") {
t.Fatalf("empty host error = %v", err)
}
_, err = NewSMTPDriver(SMTPConfig{Host: " ", TLS: "mandatory"})
if err == nil || !strings.Contains(err.Error(), "mail.smtp.host") {
t.Fatalf("blank host error = %v", err)
}
}
func TestSMTPErrorsOmitCredentialsAndBodies(t *testing.T) {
cat := smokeCatalog(t)
d, err := NewSMTPDriver(SMTPConfig{
Host: "127.0.0.1",
Port: 1,
Username: "user",
Password: "secretpass",
TLS: "none",
Timeout: 80 * time.Millisecond,
})
if err != nil {
t.Fatal(err)
}
mail := NewMailer(cat, d, Options{From: "from@example.test"})
err = mail.Send(context.Background(), Message{
Template: "golem15.hello::mail.hello",
To: []string{"ada@example.test"},
Vars: map[string]any{"Name": "Ada", "URL": "https://example.test"},
})
if err == nil {
t.Fatal("expected smtp failure")
}
msg := err.Error()
if !strings.Contains(msg, "smtp") {
t.Fatalf("error %q should mention smtp", msg)
}
for _, leaked := range []string{"secretpass", "Witaj **Ada**.", "text body"} {
if strings.Contains(msg, leaked) {
t.Fatalf("smtp error leaked %q: %v", leaked, err)
}
}
}