Skip to content
This repository has been archived by the owner on May 19, 2020. It is now read-only.

mail: allow sending a text version of mail #1281

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion controllers/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func InitApp(envVars *env.VarSet, app *cfenv.App) (*web.Router, *helpers.Setting
if err := settings.InitSettings(envVars, app); err != nil {
return nil, nil, err
}
mailer, err := mailer.InitSMTPMailer(settings)
mailer, err := mailer.NewSMTPMailer(settings)
if err != nil {
return nil, nil, err
}
Expand Down
10 changes: 7 additions & 3 deletions controllers/uaa.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,13 @@ func (c *UAAContext) TriggerInvite(inviteReq inviteEmailRequest) *UaaError {
if tplErr != nil {
return newUaaError(http.StatusInternalServerError, tplErr.Error())
}
emailErr := c.mailer.SendEmail(inviteReq.Email, "Invitation to join cloud.gov", emailHTML.Bytes())
if emailErr != nil {
return newUaaError(http.StatusInternalServerError, emailErr.Error())
if err := c.mailer.SendEmail(
inviteReq.Email,
"Invitation to join cloud.gov",
emailHTML.Bytes(),
nil,
); err != nil {
return newUaaError(http.StatusInternalServerError, err.Error())
}
return nil
}
Expand Down
11 changes: 6 additions & 5 deletions helpers/testhelpers/mocks/Mailer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ type Mailer struct {
mock.Mock
}

// SendEmail provides a mock function with given fields: emailAddress, subject, body
func (_m *Mailer) SendEmail(emailAddress string, subject string, body []byte) error {
ret := _m.Called(emailAddress, subject, body)
// SendEmail provides a mock function with given fields:
// emailAddress, subject, html, text.
func (_m *Mailer) SendEmail(emailAddress string, subject string, html, text []byte) error {
ret := _m.Called(emailAddress, subject, html, text)

var r0 error
if rf, ok := ret.Get(0).(func(string, string, []byte) error); ok {
r0 = rf(emailAddress, subject, body)
if rf, ok := ret.Get(0).(func(string, string, []byte, []byte) error); ok {
r0 = rf(emailAddress, subject, html, text)
} else {
r0 = ret.Error(0)
}
Expand Down
2 changes: 1 addition & 1 deletion helpers/testhelpers/testhelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func CreateRouterWithMockSession(sessionData map[string]interface{}, envVars map
// mockery converts []byte to []uint8 thus having to check for that in the
// argument.
mockMailer.On("SendEmail", mock.AnythingOfType("string"),
mock.AnythingOfType("string"), mock.AnythingOfType("[]uint8")).Return(nil)
mock.AnythingOfType("string"), mock.AnythingOfType("[]uint8"), mock.AnythingOfType("[]uint8")).Return(nil)
router := controllers.InitRouter(&settings, templates, mockMailer)

return router, &store
Expand Down
21 changes: 14 additions & 7 deletions mailer/mailer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mailer

import (
"fmt"
"net/smtp"

"github.com/18F/cg-dashboard/helpers"
Expand All @@ -9,11 +10,11 @@ import (

// Mailer is a interface that any mailer should implement.
type Mailer interface {
SendEmail(emailAddress string, subject string, body []byte) error
SendEmail(emailAddress string, subject string, html, text []byte) error
}

// InitSMTPMailer creates a new SMTP Mailer
func InitSMTPMailer(settings helpers.Settings) (Mailer, error) {
// NewSMTPMailer creates a new SMTP Mailer
func NewSMTPMailer(settings helpers.Settings) (Mailer, error) {
return &smtpMailer{
smtpHost: settings.SMTPHost,
smtpPort: settings.SMTPPort,
Expand All @@ -31,11 +32,17 @@ type smtpMailer struct {
smtpFrom string
}

func (s *smtpMailer) SendEmail(emailAddress, subject string, body []byte) error {
// SendEmail implements Mailer.
func (s *smtpMailer) SendEmail(emailAddress, subject string, html, text []byte) error {
e := email.NewEmail()
e.From = s.smtpFrom
e.To = []string{" <" + emailAddress + ">"}
e.HTML = body
e.To = []string{fmt.Sprintf("<%s>", emailAddress)}
e.HTML = html
e.Text = text
e.Subject = subject
return e.Send(s.smtpHost+":"+s.smtpPort, smtp.PlainAuth("", s.smtpUser, s.smtpPass, s.smtpHost))

return e.Send(
fmt.Sprintf("%s:%s", s.smtpHost, s.smtpPort),
smtp.PlainAuth("", s.smtpUser, s.smtpPass, s.smtpHost),
)
}
55 changes: 25 additions & 30 deletions mailer/mailer_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package mailer

import (
"bytes"
"fmt"
"strings"
"testing"

Expand All @@ -11,56 +11,51 @@ import (

func TestSendEmail(t *testing.T) {
hostname, smtpPort, apiPort, cleanup := CreateTestMailCatcher(t)
// Test InitSMTPMailer with valid path for templates.
settings := helpers.Settings{
SMTPHost: hostname,
SMTPPort: smtpPort,
SMTPFrom: "[email protected]",
}
mailer, err := InitSMTPMailer(settings)
if mailer == nil {
t.Error("Expected non nil mailer.")
}
mailer, err := NewSMTPMailer(settings)
if err != nil {
t.Errorf("Expected nil error, found %s", err.Error())
t.Fatal(err)
}
body := bytes.NewBufferString("test html here")
err = mailer.SendEmail("[email protected]", "sample subject", body.Bytes())
if err != nil {
t.Errorf("Expected nil error, found %s", err.Error())
html := []byte("<strong>html</strong>")
text := []byte("text")
if err := mailer.SendEmail("[email protected]", "subject", html, text); err != nil {
t.Errorf("SendEmail() err = %v, want none", err)
}
receivedData, err := GetLatestMailMessageData(hostname, apiPort)
b, err := GetLatestMailMessageData(hostname, apiPort)
if err != nil {
t.Errorf("Expected nil error, found %s", err.Error())
t.Fatal(err)
}
if !strings.Contains(string(receivedData), `"sender":"<[email protected]>"`) {
t.Error("Expected to find sender metadata")
message := string(b)
if want := "[email protected]"; !strings.Contains(message, fmt.Sprintf(`"sender":"<%s>"`, want)) {
t.Errorf("sender was wrong, want %q", want)
}
if !strings.Contains(string(receivedData), `"recipients":["<[email protected]>"]`) {
t.Error("Expected to find receipient metadata")
if want := "[email protected]"; !strings.Contains(message, fmt.Sprintf(`"recipients":["<%s>"]`, want)) {
t.Errorf("recipient was wrong, want %q", want)
}
if !strings.Contains(string(receivedData), `"subject":"sample subject"`) {
t.Error("Expected to find receipient metadata")
if want := "subject"; !strings.Contains(message, fmt.Sprintf(`"subject":"%s"`, want)) {
t.Errorf("subject was wrong, want %q", want)
}
// Useful for generating test data. Undo to learn more about the data.
// log.Println(string(receivedData))

cleanup() // Destroy the mail server.
cleanup()

// Try sending mail to bad server.
err = mailer.SendEmail("test@receiver.com", "sample subject", body.Bytes())
err = mailer.SendEmail("recipient@example.com", "sample subject", html, text)
if err == nil {
t.Error("Expected non nil error")
t.Error("got nil error, want something")
}
}

func TestInitSMTPMailer(t *testing.T) {
func TestNewSMTPMailer(t *testing.T) {
settings := helpers.Settings{}
mailer, err := InitSMTPMailer(settings)
if mailer == nil {
t.Error("Expected non nil mailer.")
}
mailer, err := NewSMTPMailer(settings)
if err != nil {
t.Errorf("Expected nil error, found %s", err.Error())
t.Errorf("error = %v, want nil", err)
}
if mailer == nil {
t.Error("mailer = nil, want something")
}
}