go-mail/client_test.go

371 lines
10 KiB
Go
Raw Normal View History

2022-03-06 15:15:42 +01:00
package mail
import (
"crypto/tls"
2022-03-15 22:37:55 +01:00
"fmt"
2022-03-16 14:09:50 +01:00
"github.com/wneessen/go-mail/auth"
"net/smtp"
2022-03-06 15:15:42 +01:00
"testing"
2022-03-07 16:24:49 +01:00
"time"
2022-03-06 15:15:42 +01:00
)
// DefaultHost is used as default hostname for the Client
const DefaultHost = "localhost"
// TestNewClient tests the NewClient() method with its default options
func TestNewClient(t *testing.T) {
host := "mail.example.com"
2022-03-15 21:48:36 +01:00
tests := []struct {
name string
host string
shouldfail bool
}{
{"Default", "mail.example.com", false},
{"Empty host should fail", "", true},
}
2022-03-15 21:48:36 +01:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(tt.host)
if err != nil && !tt.shouldfail {
t.Errorf("failed to create new client: %s", err)
return
}
2022-03-15 21:50:25 +01:00
if c.host != tt.host {
2022-03-15 21:48:36 +01:00
t.Errorf("failed to create new client. Host expected: %s, got: %s", host, c.host)
}
if c.cto != DefaultTimeout {
t.Errorf("failed to create new client. Timeout expected: %s, got: %s", DefaultTimeout.String(),
c.cto.String())
}
if c.port != DefaultPort {
t.Errorf("failed to create new client. Port expected: %d, got: %d", DefaultPort, c.port)
}
if c.tlspolicy != TLSMandatory {
t.Errorf("failed to create new client. TLS policy expected: %d, got: %d", TLSMandatory, c.tlspolicy)
}
2022-03-15 21:50:25 +01:00
if c.tlsconfig.ServerName != tt.host {
2022-03-15 21:48:36 +01:00
t.Errorf("failed to create new client. TLS config host expected: %s, got: %s",
host, c.tlsconfig.ServerName)
}
if c.tlsconfig.MinVersion != DefaultTLSMinVersion {
t.Errorf("failed to create new client. TLS config min versino expected: %d, got: %d",
DefaultTLSMinVersion, c.tlsconfig.MinVersion)
}
2022-03-15 22:37:55 +01:00
if c.ServerAddr() != fmt.Sprintf("%s:%d", tt.host, c.port) {
t.Errorf("failed to create new client. c.ServerAddr() expected: %s, got: %s",
fmt.Sprintf("%s:%d", tt.host, c.port), c.ServerAddr())
}
2022-03-15 21:48:36 +01:00
})
}
}
// TestNewClient tests the NewClient() method with its custom options
func TestNewClientWithOptions(t *testing.T) {
host := "mail.example.com"
tests := []struct {
name string
option Option
shouldfail bool
}{
{"nil option", nil, true},
{"WithPort()", WithPort(465), false},
{"WithPort(); port is too high", WithPort(100000), true},
{"WithTimeout()", WithTimeout(time.Second * 5), false},
{"WithTimeout()", WithTimeout(-10), true},
{"WithSSL()", WithSSL(), false},
{"WithHELO()", WithHELO(host), false},
2022-03-15 22:37:55 +01:00
{"WithHELO(); helo is empty", WithHELO(""), true},
{"WithTLSPolicy()", WithTLSPolicy(TLSOpportunistic), false},
{"WithTLSConfig()", WithTLSConfig(&tls.Config{}), false},
{"WithTLSConfig(); config is nil", WithTLSConfig(nil), true},
{"WithSMTPAuth()", WithSMTPAuth(SMTPAuthLogin), false},
{"WithSMTPAuthCustom()",
WithSMTPAuthCustom(smtp.PlainAuth("", "", "", "")),
false},
{"WithUsername()", WithUsername("test"), false},
{"WithPassword()", WithPassword("test"), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost, tt.option)
if err != nil && !tt.shouldfail {
t.Errorf("failed to create new client: %s", err)
return
}
_ = c
})
}
}
2022-03-07 16:24:49 +01:00
// TestWithHELO tests the WithHELO() option for the NewClient() method
2022-03-06 15:15:42 +01:00
func TestWithHELO(t *testing.T) {
tests := []struct {
name string
value string
want string
}{
{"HELO test.de", "test.de", "test.de"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost, WithHELO(tt.value))
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
if c.helo != tt.want {
t.Errorf("failed to set custom HELO. Want: %s, got: %s", tt.want, c.helo)
}
})
}
}
2022-03-07 16:24:49 +01:00
// TestWithPort tests the WithPort() option for the NewClient() method
func TestWithPort(t *testing.T) {
tests := []struct {
name string
value int
want int
2022-03-15 22:37:55 +01:00
sf bool
2022-03-07 16:24:49 +01:00
}{
2022-03-15 22:37:55 +01:00
{"set port to 25", 25, 25, false},
{"set port to 465", 465, 465, false},
{"set port to 100000", 100000, 25, true},
{"set port to -10", -10, 25, true},
2022-03-07 16:24:49 +01:00
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost, WithPort(tt.value))
2022-03-15 22:37:55 +01:00
if err != nil && !tt.sf {
2022-03-07 16:24:49 +01:00
t.Errorf("failed to create new client: %s", err)
return
}
if c.port != tt.want {
t.Errorf("failed to set custom port. Want: %d, got: %d", tt.want, c.port)
}
})
}
}
// TestWithTimeout tests the WithTimeout() option for the NewClient() method
func TestWithTimeout(t *testing.T) {
tests := []struct {
name string
value time.Duration
want time.Duration
2022-03-15 22:37:55 +01:00
sf bool
2022-03-07 16:24:49 +01:00
}{
2022-03-15 22:37:55 +01:00
{"set timeout to 5s", time.Second * 5, time.Second * 5, false},
{"set timeout to 30s", time.Second * 30, time.Second * 30, false},
{"set timeout to 1m", time.Minute, time.Minute, false},
{"set timeout to 0", 0, DefaultTimeout, true},
2022-03-07 16:24:49 +01:00
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost, WithTimeout(tt.value))
2022-03-15 22:37:55 +01:00
if err != nil && !tt.sf {
2022-03-07 16:24:49 +01:00
t.Errorf("failed to create new client: %s", err)
return
}
if c.cto != tt.want {
t.Errorf("failed to set custom timeout. Want: %d, got: %d", tt.want, c.cto)
}
})
}
}
2022-03-09 16:52:23 +01:00
// TestWithTLSPolicy tests the WithTLSPolicy() option for the NewClient() method
func TestWithTLSPolicy(t *testing.T) {
tests := []struct {
name string
value TLSPolicy
2022-03-15 22:37:55 +01:00
want string
sf bool
2022-03-09 16:52:23 +01:00
}{
2022-03-15 22:37:55 +01:00
{"Policy: TLSMandatory", TLSMandatory, TLSMandatory.String(), false},
{"Policy: TLSOpportunistic", TLSOpportunistic, TLSOpportunistic.String(), false},
{"Policy: NoTLS", NoTLS, NoTLS.String(), false},
{"Policy: Invalid", -1, "UnknownPolicy", true},
2022-03-09 16:52:23 +01:00
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost, WithTLSPolicy(tt.value))
2022-03-15 22:37:55 +01:00
if err != nil && !tt.sf {
2022-03-09 16:52:23 +01:00
t.Errorf("failed to create new client: %s", err)
return
}
2022-03-15 22:37:55 +01:00
if c.tlspolicy.String() != tt.want {
2022-03-09 16:52:23 +01:00
t.Errorf("failed to set TLSPolicy. Want: %s, got: %s", tt.want, c.tlspolicy)
}
})
}
}
// TestSetTLSPolicy tests the SetTLSPolicy() method for the Client object
func TestSetTLSPolicy(t *testing.T) {
tests := []struct {
name string
value TLSPolicy
2022-03-15 22:37:55 +01:00
want string
sf bool
2022-03-09 16:52:23 +01:00
}{
2022-03-15 22:37:55 +01:00
{"Policy: TLSMandatory", TLSMandatory, TLSMandatory.String(), false},
{"Policy: TLSOpportunistic", TLSOpportunistic, TLSOpportunistic.String(), false},
{"Policy: NoTLS", NoTLS, NoTLS.String(), false},
{"Policy: Invalid", -1, "UnknownPolicy", true},
2022-03-09 16:52:23 +01:00
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost, WithTLSPolicy(NoTLS))
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
c.SetTLSPolicy(tt.value)
2022-03-15 22:37:55 +01:00
if c.tlspolicy.String() != tt.want {
2022-03-09 16:52:23 +01:00
t.Errorf("failed to set TLSPolicy. Want: %s, got: %s", tt.want, c.tlspolicy)
}
})
}
}
2022-03-16 14:09:50 +01:00
// TestSetTLSConfig tests the SetTLSConfig() method for the Client object
func TestSetTLSConfig(t *testing.T) {
tests := []struct {
name string
value *tls.Config
sf bool
}{
{"default config", &tls.Config{}, false},
{"nil config", nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost)
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
if err := c.SetTLSConfig(tt.value); err != nil && !tt.sf {
t.Errorf("failed to set TLSConfig: %s", err)
return
}
})
}
}
// TestSetUsername tests the SetUsername method for the Client object
func TestSetUsername(t *testing.T) {
tests := []struct {
name string
value string
want string
sf bool
}{
{"normal username", "testuser", "testuser", false},
{"empty username", "", "", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost)
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
c.SetUsername(tt.value)
if c.user != tt.want {
t.Errorf("failed to set username. Expected %s, got: %s", tt.want, c.user)
}
})
}
}
// TestSetPassword tests the SetPassword method for the Client object
func TestSetPassword(t *testing.T) {
tests := []struct {
name string
value string
want string
sf bool
}{
{"normal password", "testpass", "testpass", false},
{"empty password", "", "", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost)
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
c.SetPassword(tt.value)
if c.pass != tt.want {
t.Errorf("failed to set password. Expected %s, got: %s", tt.want, c.pass)
}
})
}
}
// TestSetSMTPAuth tests the SetSMTPAuth method for the Client object
func TestSetSMTPAuth(t *testing.T) {
tests := []struct {
name string
value SMTPAuthType
want string
sf bool
}{
{"SMTPAuth: LOGIN", SMTPAuthLogin, "LOGIN", false},
{"SMTPAuth: PLAIN", SMTPAuthPlain, "PLAIN", false},
{"SMTPAuth: CRAM-MD5", SMTPAuthCramMD5, "CRAM-MD5", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost)
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
c.SetSMTPAuth(tt.value)
if string(c.satype) != tt.want {
t.Errorf("failed to set SMTP auth type. Expected %s, got: %s", tt.want, string(c.satype))
}
})
}
}
// TestSetSMTPAuthCustom tests the SetSMTPAuthCustom method for the Client object
func TestSetSMTPAuthCustom(t *testing.T) {
tests := []struct {
name string
value smtp.Auth
want string
sf bool
}{
{"SMTPAuth: PLAIN", smtp.PlainAuth("", "", "", ""), "PLAIN", false},
{"SMTPAuth: CRAM-MD5", smtp.CRAMMD5Auth("", ""), "CRAM-MD5", false},
{"SMTPAuth: LOGIN", auth.LoginAuth("", "", ""), "LOGIN", false},
}
si := smtp.ServerInfo{TLS: true}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := NewClient(DefaultHost)
if err != nil {
t.Errorf("failed to create new client: %s", err)
return
}
c.SetSMTPAuthCustom(tt.value)
if c.sa == nil {
t.Errorf("failed to set custom SMTP auth method. SMTP Auth method is empty")
}
p, _, err := c.sa.Start(&si)
if err != nil {
t.Errorf("SMTP Auth Start() method returned error: %s", err)
}
if p != tt.want {
t.Errorf("SMTP Auth Start() method is returned proto: %s, expected: %s", p, tt.want)
}
})
}
}