email-sender/pkg/email/email_test.go

185 lines
4.4 KiB
Go
Executable File

package email
import (
"fmt"
"net/smtp"
"os"
"testing"
"github.com/joho/godotenv"
"github.com/kelseyhightower/envconfig"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type config struct {
MailUser string `required:"false" split_words:"true"`
MailPassword string `required:"false" split_words:"true"`
MailHost string `required:"false" split_words:"true"`
MailPort string `required:"false" split_words:"true"`
MailFrom string `required:"false" split_words:"true"`
MailTo string `required:"false" split_words:"true"`
}
func newConfig(envFile string) *config {
if envFile != "" {
err := godotenv.Load(envFile)
if err != nil {
panic(fmt.Errorf("godotenv.Load: %w", err))
}
}
cfg := &config{}
err := envconfig.Process("", cfg)
if err != nil {
panic(fmt.Errorf("envconfig.Process: %w", err))
}
return cfg
}
func TestNewConfig_MissingEnvFile(t *testing.T) {
assert.Panics(t, func() { newConfig(".missing_env_file") })
}
func TestMockSendEmail(t *testing.T) {
service := NewMockMailService(func(params ...interface{}) {})
emailData := EmailMessage{
To: "test@example.com",
Subject: "Test Email",
Body: "This is a test email.",
}
err := service.SendEmail(emailData)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
}
func TestNewInsecure(t *testing.T) {
cfg := newConfig(".env.test")
mailSrv := NewInsecure(MailServiceConfig{
Auth: smtp.PlainAuth("", cfg.MailUser, cfg.MailPassword, cfg.MailHost),
Host: cfg.MailHost,
Port: cfg.MailPort,
From: cfg.MailFrom,
})
t.Run("TestSendEmail", func(t *testing.T) {
data := EmailMessage{
To: cfg.MailTo,
Subject: "Mail Sender",
Body: "Hello this is a test email",
}
require.NoError(t, mailSrv.SendEmail(data))
})
t.Run("TestSendEmailWithAttachments", func(t *testing.T) {
reader, err := os.Open("testdata/attachment1.txt")
require.NoError(t, err)
defer reader.Close()
reader2, err := os.Open("testdata/attachment2.txt")
require.NoError(t, err)
defer reader2.Close()
reader3, err := os.Open("testdata/attachment3.txt")
require.NoError(t, err)
defer reader3.Close()
data := EmailMessage{
To: cfg.MailTo,
Subject: "Mail Sender",
Body: "Hello this is a test email",
Attachments: []EmailAttachment{
{
Title: "attachment1.txt",
File: reader,
},
{
Title: "attachment2.txt",
File: reader2,
},
{
Title: "attachment3.txt",
File: reader3,
},
},
}
err = mailSrv.SendEmail(data)
require.NoError(t, err)
})
t.Run("TestWithAttachments", func(t *testing.T) {
msg := newMessage("from", "to", "subject")
content, err := msg.withAttachments("body", nil)
require.NoError(t, err)
assert.Greater(t, len(content), 0)
})
t.Run("TestSendEmail_InvalidRecipient", func(t *testing.T) {
data := EmailMessage{
To: "invalid_email",
Subject: "Test Email",
Body: "This is a test email.",
}
err := mailSrv.SendEmail(data)
assert.Error(t, err)
})
t.Run("TestSendEmail_FailedAuthentication", func(t *testing.T) {
// set up authentication to fail
mailSrv := NewInsecure(MailServiceConfig{
Auth: smtp.PlainAuth("", "wronguser", "wrongpassword", cfg.MailHost),
Host: cfg.MailHost,
Port: cfg.MailPort,
From: cfg.MailFrom,
})
data := EmailMessage{
To: cfg.MailTo,
Subject: "Test Email",
Body: "This is a test email.",
}
err := mailSrv.SendEmail(data)
assert.Error(t, err)
})
}
func TestSecure(t *testing.T) {
cfg := newConfig(".env.test")
emailService := NewSecure(MailServiceConfig{
Auth: smtp.PlainAuth("", cfg.MailUser, cfg.MailPassword, cfg.MailHost),
Host: cfg.MailHost,
Port: cfg.MailPort,
From: cfg.MailFrom,
})
// Assert that the tls.Config is set up correctly
assert.NotNil(t, emailService.tlsconfig)
assert.True(t, emailService.tlsconfig.InsecureSkipVerify)
assert.Equal(t, cfg.MailHost, emailService.tlsconfig.ServerName)
assert.NotNil(t, emailService.tlsconfig.VerifyConnection)
t.Run("TestSendEmail", func(t *testing.T) {
// Mock the client and test the StartTLS method
var called bool
mockDialFn := func(hostPort string) (SMTPClientIface, error) {
called = true
return &mockSMTP{}, nil
}
emailService.dial = mockDialFn
data := EmailMessage{
To: cfg.MailTo,
Subject: "Mail Sender",
Body: "Hello this is a test email",
}
require.NoError(t, emailService.SendEmail(data))
assert.Equal(t, true, called)
})
}