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) }) }