diff --git a/.gitignore b/.gitignore
index ced52f6..d786d89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,4 +25,6 @@ _testmain.go
*.out
*.iml
-.idea
\ No newline at end of file
+.idea
+
+defaults/smtp_mailer_test.json
diff --git a/defaults/smtp_mailer.go b/defaults/smtp_mailer.go
index 734b3fb..778ae4b 100644
--- a/defaults/smtp_mailer.go
+++ b/defaults/smtp_mailer.go
@@ -10,10 +10,14 @@ import (
"text/template"
"time"
+ "github.com/pkg/errors"
"github.com/volatiletech/authboss"
)
// NewSMTPMailer creates an SMTP Mailer to send emails with.
+// An example usage might be something like:
+//
+// NewSMTPMailer("smtp.gmail.com", smtp.PlainAuth("", "admin@yoursite.com", "password", "smtp.gmail.com"))
func NewSMTPMailer(server string, auth smtp.Auth) *SMTPMailer {
if len(server) == 0 {
panic("SMTP Mailer must be created with a server string.")
@@ -31,6 +35,10 @@ type SMTPMailer struct {
// Send an e-mail
func (s SMTPMailer) Send(ctx context.Context, mail authboss.Email) error {
+ if len(mail.TextBody) == 0 && len(mail.HTMLBody) == 0 {
+ return errors.New("refusing to send mail without text or html body")
+ }
+
buf := &bytes.Buffer{}
data := struct {
@@ -110,15 +118,19 @@ MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="==============={{.Boundary}}=="
Content-Transfer-Encoding: 7bit
+{{if .Mail.TextBody -}}
--==============={{.Boundary}}==
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
{{.Mail.TextBody}}
+{{end -}}
+{{if .Mail.HTMLBody -}}
--==============={{.Boundary}}==
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
{{.Mail.HTMLBody}}
+{{end -}}
--==============={{.Boundary}}==--
`))
diff --git a/defaults/smtp_mailer_test.go b/defaults/smtp_mailer_test.go
index 70d0e6f..16090ce 100644
--- a/defaults/smtp_mailer_test.go
+++ b/defaults/smtp_mailer_test.go
@@ -1,9 +1,77 @@
package defaults
-import "testing"
+import (
+ "context"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "net/smtp"
+ "testing"
+
+ "github.com/volatiletech/authboss"
+)
+
+var (
+ flagTestSMTPMailer = flag.Bool("test-smtp-mailer", false, "Test the smtp mailer")
+)
func TestSMTPMailer(t *testing.T) {
- t.Skip("must implement test against real smtp servers here")
+ t.Parallel()
+
+ if !*flagTestSMTPMailer {
+ t.Skip("SMTP Mailer Testing not enabled (-test-smtp-mailer flag)")
+ }
+
+ creds := struct {
+ Server string `json:"server,omitempty"`
+ Port int `json:"port,omitempty"`
+ Email string `json:"email,omitempty"`
+ Password string `json:"password,omitempty"`
+ }{}
+
+ b, err := ioutil.ReadFile("smtp_mailer_test.json")
+ if err != nil {
+ t.Fatal(`error reading file: "smtp_mailer_test.json`, err)
+ }
+
+ if err = json.Unmarshal(b, &creds); err != nil {
+ t.Fatal(err)
+ }
+
+ server := fmt.Sprintf("%s:%d", creds.Server, creds.Port)
+ mailer := NewSMTPMailer(server, smtp.PlainAuth("", creds.Email, creds.Password, creds.Server))
+
+ mail := authboss.Email{
+ From: creds.Email,
+ To: []string{creds.Email},
+ Subject: "Authboss Test SMTP Mailer",
+ }
+
+ txtOnly := mail
+ txtOnly.Subject += ": Text Content"
+ txtOnly.TextBody = "Authboss\nSMTP\nTest\nWith\nNewlines"
+
+ if err = mailer.Send(context.Background(), txtOnly); err != nil {
+ t.Error(err)
+ }
+
+ htmlOnly := mail
+ htmlOnly.Subject += ": HTML Content"
+ htmlOnly.HTMLBody = "Authboss
Test
\nWith
Newlines\nand
breaks"
+
+ if err = mailer.Send(context.Background(), htmlOnly); err != nil {
+ t.Error(err)
+ }
+
+ mixed := mail
+ mixed.Subject += ": Mixed Content"
+ mixed.HTMLBody = htmlOnly.HTMLBody
+ mixed.TextBody = txtOnly.TextBody
+
+ if err = mailer.Send(context.Background(), mixed); err != nil {
+ t.Error(err)
+ }
}
func TestSMTPMailerPanic(t *testing.T) {