Skip to content

Commit b3e6b6a

Browse files
Add support for multiple to email addresses in single recepient (#226)
* Add support for multiple to comma seperated email addresses in single recepient Signed-off-by: gokulav137 <[email protected]> * Refactor emailService to make Send testable and Add Testcases - emailService now consist of client and html - NewEmailService creates the client from opts and store html seperately - Send now directly calls the client instead of creating the client and calling Signed-off-by: gokulav137 <[email protected]> * Add trim while parsing recepient for emailService - seperate out parsing logic - add test for parseTo method Signed-off-by: gokulav137 <[email protected]> --------- Signed-off-by: gokulav137 <[email protected]> Signed-off-by: gokulav137 <[email protected]> Co-authored-by: pasha-codefresh <[email protected]>
1 parent 8ba938e commit b3e6b6a

File tree

2 files changed

+102
-13
lines changed

2 files changed

+102
-13
lines changed

pkg/services/email.go

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package services
22

33
import (
44
"bytes"
5+
"strings"
56
texttemplate "text/template"
67

8+
"gomodules.xyz/notify"
79
"gomodules.xyz/notify/smtp"
810

911
"github.com/argoproj/notifications-engine/pkg/util/text"
@@ -60,32 +62,46 @@ type EmailOptions struct {
6062
}
6163

6264
type emailService struct {
63-
opts EmailOptions
65+
client notify.ByEmail
66+
html bool
6467
}
6568

66-
func NewEmailService(opts EmailOptions) NotificationService {
67-
return &emailService{opts: opts}
69+
func NewEmailService(opts EmailOptions) *emailService {
70+
return &emailService{
71+
client: smtp.New(smtp.Options{
72+
From: opts.From,
73+
Host: opts.Host,
74+
Port: opts.Port,
75+
InsecureSkipVerify: opts.InsecureSkipVerify,
76+
Password: opts.Password,
77+
Username: opts.Username,
78+
}),
79+
html: opts.Html,
80+
}
6881
}
6982

7083
func (s *emailService) Send(notification Notification, dest Destination) error {
7184
subject := ""
7285
body := notification.Message
86+
to := s.parseTo(dest.Recipient)
7387
if notification.Email != nil {
7488
subject = notification.Email.Subject
7589
body = text.Coalesce(notification.Email.Body, body)
7690
}
77-
email := smtp.New(smtp.Options{
78-
From: s.opts.From,
79-
Host: s.opts.Host,
80-
Port: s.opts.Port,
81-
InsecureSkipVerify: s.opts.InsecureSkipVerify,
82-
Password: s.opts.Password,
83-
Username: s.opts.Username,
84-
}).WithSubject(subject).WithBody(body).To(dest.Recipient)
85-
86-
if s.opts.Html {
91+
92+
email := s.client.WithSubject(subject).WithBody(body).To(to[0], to[1:]...)
93+
94+
if s.html {
8795
return email.SendHtml()
8896
} else {
8997
return email.Send()
9098
}
9199
}
100+
101+
func (s *emailService) parseTo(recipient string) []string {
102+
to := strings.Split(recipient, ",")
103+
for i, email := range to {
104+
to[i] = strings.Trim(email, " ")
105+
}
106+
return to
107+
}

pkg/services/email_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"text/template"
66

77
"github.com/stretchr/testify/assert"
8+
"gomodules.xyz/notify"
9+
"k8s.io/utils/strings/slices"
810
)
911

1012
func TestGetTemplater_Email(t *testing.T) {
@@ -33,3 +35,74 @@ func TestGetTemplater_Email(t *testing.T) {
3335
assert.Equal(t, "hello", notification.Email.Subject)
3436
assert.Equal(t, "world", notification.Email.Body)
3537
}
38+
39+
type mockClient struct {
40+
notify.ByEmail
41+
}
42+
43+
func (c *mockClient) Send() error {
44+
return nil
45+
}
46+
47+
func (c *mockClient) SendHtml() error {
48+
return nil
49+
}
50+
51+
func (c *mockClient) WithSubject(string) notify.ByEmail {
52+
return c
53+
}
54+
55+
func (c *mockClient) WithBody(string) notify.ByEmail {
56+
return c
57+
}
58+
59+
func (c *mockClient) To(string, ...string) notify.ByEmail {
60+
return c
61+
}
62+
63+
func TestSend_SingleRecepient(t *testing.T) {
64+
es := emailService{&mockClient{}, false}
65+
err := es.Send(Notification{}, Destination{Recipient: "[email protected]"})
66+
if err != nil {
67+
t.Error("Error while sending email")
68+
}
69+
}
70+
71+
func TestSend_MultipleRecepient(t *testing.T) {
72+
es := emailService{&mockClient{}, true}
73+
// two email addresses
74+
err := es.Send(Notification{}, Destination{Recipient: "[email protected],[email protected]"})
75+
if err != nil {
76+
t.Error("Error while sending email")
77+
}
78+
// three email addresses
79+
err = es.Send(Notification{}, Destination{Recipient: "[email protected],[email protected],[email protected]"})
80+
if err != nil {
81+
t.Error("Error while sending email")
82+
}
83+
}
84+
85+
func TestNewEmailService(t *testing.T) {
86+
es := NewEmailService(EmailOptions{Html: true})
87+
if es.html != true {
88+
t.Error("Html set incorrectly")
89+
}
90+
}
91+
92+
func TestParseTo(t *testing.T) {
93+
es := emailService{}
94+
testCases := []struct {
95+
recepient string
96+
want []string
97+
}{
98+
99+
100+
101+
}
102+
for _, testCase := range testCases {
103+
got := es.parseTo(testCase.recepient)
104+
if !slices.Equal(testCase.want, got) {
105+
t.Errorf("Failed to parse \"%v\", got: %v", testCase.recepient, got)
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)