104 lines
3.1 KiB
Go
104 lines
3.1 KiB
Go
|
|
package email
|
||
|
|
|
||
|
|
import (
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"go.uber.org/zap"
|
||
|
|
"go.uber.org/zap/zapcore"
|
||
|
|
"go.uber.org/zap/zaptest/observer"
|
||
|
|
)
|
||
|
|
|
||
|
|
// clearAllSMTPEnv zeroes every SMTP-related env var (canonical + deprecated)
|
||
|
|
// so each test starts from a known blank slate. t.Setenv guarantees restore.
|
||
|
|
func clearAllSMTPEnv(t *testing.T) {
|
||
|
|
t.Helper()
|
||
|
|
for _, k := range []string{
|
||
|
|
"SMTP_HOST", "SMTP_PORT", "SMTP_PASSWORD",
|
||
|
|
"SMTP_USERNAME", "SMTP_FROM", "SMTP_FROM_NAME",
|
||
|
|
"SMTP_USER", "FROM_EMAIL", "FROM_NAME",
|
||
|
|
} {
|
||
|
|
t.Setenv(k, "")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLoadSMTPConfig_EmptyWhenNothingSet(t *testing.T) {
|
||
|
|
clearAllSMTPEnv(t)
|
||
|
|
cfg := LoadSMTPConfigFromEnv()
|
||
|
|
assert.Empty(t, cfg.Host, "Host must stay empty so callers can log-only")
|
||
|
|
assert.Empty(t, cfg.Port)
|
||
|
|
assert.Empty(t, cfg.Username)
|
||
|
|
assert.Empty(t, cfg.From)
|
||
|
|
assert.Empty(t, cfg.FromName)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLoadSMTPConfig_CanonicalNamesReadDirectly(t *testing.T) {
|
||
|
|
clearAllSMTPEnv(t)
|
||
|
|
t.Setenv("SMTP_HOST", "mailhog")
|
||
|
|
t.Setenv("SMTP_PORT", "1025")
|
||
|
|
t.Setenv("SMTP_USERNAME", "veza-api")
|
||
|
|
t.Setenv("SMTP_PASSWORD", "supersecret")
|
||
|
|
t.Setenv("SMTP_FROM", "no-reply@veza.fm")
|
||
|
|
t.Setenv("SMTP_FROM_NAME", "Veza")
|
||
|
|
|
||
|
|
cfg := LoadSMTPConfigFromEnv()
|
||
|
|
assert.Equal(t, "mailhog", cfg.Host)
|
||
|
|
assert.Equal(t, "1025", cfg.Port)
|
||
|
|
assert.Equal(t, "veza-api", cfg.Username)
|
||
|
|
assert.Equal(t, "supersecret", cfg.Password)
|
||
|
|
assert.Equal(t, "no-reply@veza.fm", cfg.From)
|
||
|
|
assert.Equal(t, "Veza", cfg.FromName)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLoadSMTPConfig_DeprecatedNamesFallBack(t *testing.T) {
|
||
|
|
clearAllSMTPEnv(t)
|
||
|
|
// Only the pre-v1.0.6 env vars are set.
|
||
|
|
t.Setenv("SMTP_USER", "legacy-user")
|
||
|
|
t.Setenv("FROM_EMAIL", "legacy@veza.fm")
|
||
|
|
t.Setenv("FROM_NAME", "Legacy Veza")
|
||
|
|
|
||
|
|
core, observed := observer.New(zapcore.WarnLevel)
|
||
|
|
cfg := LoadSMTPConfigFromEnvWithLogger(zap.New(core))
|
||
|
|
|
||
|
|
assert.Equal(t, "legacy-user", cfg.Username, "fallback must pick up SMTP_USER when SMTP_USERNAME is empty")
|
||
|
|
assert.Equal(t, "legacy@veza.fm", cfg.From)
|
||
|
|
assert.Equal(t, "Legacy Veza", cfg.FromName)
|
||
|
|
|
||
|
|
entries := observed.All()
|
||
|
|
assert.Len(t, entries, 3, "one warning per deprecated var in use")
|
||
|
|
seen := map[string]bool{}
|
||
|
|
for _, e := range entries {
|
||
|
|
for _, f := range e.Context {
|
||
|
|
if f.Key == "deprecated" {
|
||
|
|
seen[f.String] = true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assert.True(t, seen["SMTP_USER"])
|
||
|
|
assert.True(t, seen["FROM_EMAIL"])
|
||
|
|
assert.True(t, seen["FROM_NAME"])
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLoadSMTPConfig_CanonicalWinsOverDeprecated(t *testing.T) {
|
||
|
|
clearAllSMTPEnv(t)
|
||
|
|
t.Setenv("SMTP_USERNAME", "canonical-user")
|
||
|
|
t.Setenv("SMTP_USER", "legacy-user-ignored")
|
||
|
|
t.Setenv("SMTP_FROM", "canonical@veza.fm")
|
||
|
|
t.Setenv("FROM_EMAIL", "legacy@veza.fm")
|
||
|
|
|
||
|
|
core, observed := observer.New(zapcore.WarnLevel)
|
||
|
|
cfg := LoadSMTPConfigFromEnvWithLogger(zap.New(core))
|
||
|
|
assert.Equal(t, "canonical-user", cfg.Username)
|
||
|
|
assert.Equal(t, "canonical@veza.fm", cfg.From)
|
||
|
|
assert.Equal(t, 0, observed.Len(),
|
||
|
|
"no warning should fire when canonical is set — deprecated vars are ignored silently")
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLoadSMTPConfig_NilLoggerIsAllowed(t *testing.T) {
|
||
|
|
clearAllSMTPEnv(t)
|
||
|
|
t.Setenv("SMTP_USER", "legacy")
|
||
|
|
assert.NotPanics(t, func() { _ = LoadSMTPConfigFromEnv() })
|
||
|
|
cfg := LoadSMTPConfigFromEnv()
|
||
|
|
assert.Equal(t, "legacy", cfg.Username)
|
||
|
|
}
|