refactor: project structure
This commit is contained in:
210
pkg/email/email_test.go
Executable file
210
pkg/email/email_test.go
Executable file
@@ -0,0 +1,210 @@
|
||||
package email
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"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
|
||||
}
|
||||
|
||||
type mockWriter struct{}
|
||||
|
||||
func (w *mockWriter) Close() error {
|
||||
return nil
|
||||
}
|
||||
func (w *mockWriter) Write(p []byte) (n int, err error) {
|
||||
return 10, nil
|
||||
}
|
||||
|
||||
// Mock SMTP Client
|
||||
type mockSMTP struct{}
|
||||
|
||||
func (m *mockSMTP) StartTLS(*tls.Config) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockSMTP) Auth(a smtp.Auth) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockSMTP) Close() error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockSMTP) Data() (io.WriteCloser, error) {
|
||||
return &mockWriter{}, nil
|
||||
}
|
||||
func (m *mockSMTP) Mail(from string) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockSMTP) Quit() error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockSMTP) Rcpt(to string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestNewConfig_MissingEnvFile(t *testing.T) {
|
||||
assert.Panics(t, func() { newConfig(".missing_env_file") })
|
||||
}
|
||||
|
||||
func TestMockSendEmail(t *testing.T) {
|
||||
service := &EmailService{
|
||||
auth: smtp.PlainAuth("", "", "", ""),
|
||||
host: "",
|
||||
port: "",
|
||||
from: "",
|
||||
tlsconfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: "",
|
||||
},
|
||||
dial: func(hostPort string) (SMTPClientIface, error) {
|
||||
return &mockSMTP{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
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 TestSendEmail(t *testing.T) {
|
||||
cfg := newConfig(".env.test")
|
||||
|
||||
mailSrv := NewMailService(MailServiceConfig{
|
||||
Auth: smtp.PlainAuth("", cfg.MailUser, cfg.MailPassword, cfg.MailHost),
|
||||
Host: cfg.MailHost,
|
||||
Port: cfg.MailPort,
|
||||
From: cfg.MailFrom,
|
||||
})
|
||||
|
||||
data := EmailMessage{
|
||||
To: cfg.MailTo,
|
||||
Subject: "Mail Sender",
|
||||
Body: "Hello this is a test email",
|
||||
}
|
||||
require.NoError(t, mailSrv.SendEmail(data))
|
||||
}
|
||||
|
||||
func TestSendEmail_FailedAuthentication(t *testing.T) {
|
||||
cfg := newConfig(".env.test")
|
||||
// set up authentication to fail
|
||||
mailSrv := NewMailService(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 TestSendEmail_InvalidRecipient(t *testing.T) {
|
||||
cfg := newConfig(".env.test")
|
||||
mailSrv := NewMailService(MailServiceConfig{
|
||||
Auth: smtp.PlainAuth("", cfg.MailUser, cfg.MailPassword, cfg.MailHost),
|
||||
Host: cfg.MailHost,
|
||||
Port: cfg.MailPort,
|
||||
From: cfg.MailFrom,
|
||||
})
|
||||
data := EmailMessage{
|
||||
To: "invalid_email",
|
||||
Subject: "Test Email",
|
||||
Body: "This is a test email.",
|
||||
}
|
||||
err := mailSrv.SendEmail(data)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestSendEmailWithAttachments(t *testing.T) {
|
||||
cfg := newConfig(".env.test")
|
||||
|
||||
mailSrv := NewMailService(MailServiceConfig{
|
||||
Auth: smtp.PlainAuth("", cfg.MailUser, cfg.MailPassword, cfg.MailHost),
|
||||
Host: cfg.MailHost,
|
||||
Port: cfg.MailPort,
|
||||
From: cfg.MailFrom,
|
||||
})
|
||||
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)
|
||||
}
|
||||
|
||||
func TestWithAttachments(t *testing.T) {
|
||||
msg := newMessage("from", "to", "subject")
|
||||
content, err := msg.withAttachments("body", nil)
|
||||
require.NoError(t, err)
|
||||
assert.Greater(t, len(content), 0)
|
||||
}
|
||||
Reference in New Issue
Block a user