package email import ( "context" "net/mail" "strings" "testing" "time" ) func testFrom() mail.Address { return mail.Address{Address: "no-reply@example.com"} } func TestLoginAuthChallengeResponse(t *testing.T) { a := &loginAuth{username: "user", password: "pass"} mech, initial, err := a.Start(nil) if err != nil { t.Fatalf("Start: %v", err) } if mech != "LOGIN" || initial != nil { t.Fatalf("unexpected Start result: %q %v", mech, initial) } resp, err := a.Next([]byte("Username:"), true) if err != nil || string(resp) != "user" { t.Fatalf("username challenge: %q %v", resp, err) } resp, err = a.Next([]byte("Password"), true) if err != nil || string(resp) != "pass" { t.Fatalf("password challenge: %q %v", resp, err) } if _, err := a.Next([]byte("Bogus"), true); err == nil { t.Fatal("expected error on unexpected challenge") } } func TestPlainAuthSendsCredentialsInClear(t *testing.T) { // Internal relays advertise only PLAIN over an unencrypted connection; // stdlib smtp.PlainAuth refuses that (ErrUnencryptedConnection), so the // sender uses the cleartext-capable plainAuth instead. a := &plainAuth{username: "user", password: "pass"} mech, initial, err := a.Start(nil) if err != nil { t.Fatalf("Start: %v", err) } if mech != "PLAIN" { t.Fatalf("mechanism = %q, want PLAIN", mech) } want := "\x00user\x00pass" if string(initial) != want { t.Fatalf("initial response = %q, want %q", initial, want) } if resp, err := a.Next(nil, false); err != nil || resp != nil { t.Fatalf("Next(done) = %q %v, want nil nil", resp, err) } if _, err := a.Next(nil, true); err == nil { t.Fatal("expected error on unexpected challenge") } } func TestNewSMTPValidation(t *testing.T) { if _, err := NewSMTP(SMTPConfig{Port: 587}); err == nil || !strings.Contains(err.Error(), "missing host") { t.Fatalf("want missing-host error, got %v", err) } if _, err := NewSMTP(SMTPConfig{Host: "relay.internal", Port: 0, DefaultFrom: testFrom()}); err == nil || !strings.Contains(err.Error(), "port") { t.Fatalf("want invalid-port error, got %v", err) } s, err := NewSMTP(SMTPConfig{ Host: "relay.internal", Port: 25, SSL: false, DefaultFrom: testFrom(), Timeout: time.Second, }) if err != nil { t.Fatalf("NewSMTP: %v", err) } smtpS, ok := s.(*smtpSender) if !ok { t.Fatalf("unexpected sender type %T", s) } if smtpS.ssl || smtpS.addr != "relay.internal:25" { t.Fatalf("unexpected config: %+v", smtpS) } } func TestBuildMessageMultipartAlternative(t *testing.T) { msg := Message{ From: mail.Address{Name: "go-auth", Address: "no-reply@example.com"}, To: []mail.Address{{Name: "Ada", Address: "ada@example.com"}}, Subject: "Reset your password — Åke & Östen", TextBody: "Hello Ada,\nreset link: https://auth.example/reset?token=abc\n", HTMLBody: "
Hello Ada,
reset link: https://auth.example/reset?token=abc
", Headers: map[string]string{"List-Unsubscribe": "