add core lib
This commit is contained in:
126
smtp/smtp_mailer_additional_test.go
Normal file
126
smtp/smtp_mailer_additional_test.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSendReturnsConfigurationErrorWhenSMTPMissing(t *testing.T) {
|
||||
mailer := NewSMTPMailer(SMTPConfig{Host: "", Port: 587, From: "noreply@example.com", Mode: SMTPModeTLS})
|
||||
|
||||
err := mailer.Send(context.Background(), "to@example.com", "subject", "<p>body</p>", "body")
|
||||
if err == nil {
|
||||
t.Fatal("expected configuration error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "smtp is not configured") {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendReturnsDeadlineExceededForExpiredContext(t *testing.T) {
|
||||
mailer := NewSMTPMailer(SMTPConfig{Host: "smtp.example.com", Port: 587, From: "noreply@example.com", Mode: SMTPModeTLS})
|
||||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Second))
|
||||
defer cancel()
|
||||
|
||||
err := mailer.Send(ctx, "to@example.com", "subject", "<p>body</p>", "body")
|
||||
if err == nil {
|
||||
t.Fatal("expected context deadline exceeded")
|
||||
}
|
||||
if err != context.DeadlineExceeded {
|
||||
t.Fatalf("expected context deadline exceeded, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginAuthNextHandlesChallenges(t *testing.T) {
|
||||
auth := loginAuth{username: "alice", password: "s3cret"}
|
||||
|
||||
proto, initial, err := auth.Start(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected start error: %v", err)
|
||||
}
|
||||
if proto != "LOGIN" {
|
||||
t.Fatalf("expected LOGIN auth proto, got %q", proto)
|
||||
}
|
||||
if len(initial) != 0 {
|
||||
t.Fatalf("expected empty initial response, got %q", string(initial))
|
||||
}
|
||||
|
||||
value, err := auth.Next([]byte("Username:"), true)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected username challenge error: %v", err)
|
||||
}
|
||||
if string(value) != "alice" {
|
||||
t.Fatalf("expected username response alice, got %q", string(value))
|
||||
}
|
||||
|
||||
value, err = auth.Next([]byte("UGFzc3dvcmQ6"), true)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected password challenge error: %v", err)
|
||||
}
|
||||
if string(value) != "s3cret" {
|
||||
t.Fatalf("expected password response s3cret, got %q", string(value))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginAuthNextHandlesTerminalAndUnexpectedChallenge(t *testing.T) {
|
||||
auth := loginAuth{username: "alice", password: "s3cret"}
|
||||
|
||||
value, err := auth.Next([]byte("ignored"), false)
|
||||
if err != nil {
|
||||
t.Fatalf("expected nil error when more=false, got %v", err)
|
||||
}
|
||||
if value != nil {
|
||||
t.Fatalf("expected nil value when more=false, got %q", string(value))
|
||||
}
|
||||
|
||||
if _, err := auth.Next([]byte("realm"), true); err == nil {
|
||||
t.Fatal("expected error for unexpected login challenge")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMIMEMessageContainsMultipartSections(t *testing.T) {
|
||||
msg := buildMIMEMessage("from@example.com", "to@example.com", "Subject", "plain body", "<p>html body</p>")
|
||||
|
||||
checks := []string{
|
||||
"From: from@example.com",
|
||||
"To: to@example.com",
|
||||
"Subject: Subject",
|
||||
"MIME-Version: 1.0",
|
||||
"Content-Type: text/plain; charset=UTF-8",
|
||||
"plain body",
|
||||
"Content-Type: text/html; charset=UTF-8",
|
||||
"<p>html body</p>",
|
||||
}
|
||||
for _, snippet := range checks {
|
||||
if !strings.Contains(msg, snippet) {
|
||||
t.Fatalf("expected MIME message to contain %q", snippet)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(msg, "\r\n") {
|
||||
t.Fatal("expected CRLF separators in MIME message")
|
||||
}
|
||||
|
||||
if !strings.Contains(msg, "Content-Type: multipart/alternative; boundary=mime-boundary-") {
|
||||
t.Fatalf("expected random mime boundary header, got %q", msg)
|
||||
}
|
||||
if !strings.Contains(msg, "--mime-boundary-") {
|
||||
t.Fatalf("expected mime boundary delimiters in message, got %q", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDialHelpersReturnDeadlineExceededWhenDeadlineHasPassed(t *testing.T) {
|
||||
deadline := time.Now().Add(-time.Second)
|
||||
ctx := context.Background()
|
||||
|
||||
if _, err := dialPlain(ctx, "smtp.example.com:25", "smtp.example.com", deadline); err != context.DeadlineExceeded {
|
||||
t.Fatalf("dialPlain expected context deadline exceeded, got %v", err)
|
||||
}
|
||||
if _, err := dialSSL(ctx, "smtp.example.com:465", "smtp.example.com", deadline); err != context.DeadlineExceeded {
|
||||
t.Fatalf("dialSSL expected context deadline exceeded, got %v", err)
|
||||
}
|
||||
if _, err := dialStartTLS(ctx, "smtp.example.com:587", "smtp.example.com", deadline); err != context.DeadlineExceeded {
|
||||
t.Fatalf("dialStartTLS expected context deadline exceeded, got %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user