backend/pkg/notification/config/config_test.go

315 lines
6.4 KiB
Go

package config
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestSMTPConfig_Validate(t *testing.T) {
tests := []struct {
name string
config SMTPConfig
wantErr bool
errMsg string
}{
{
name: "有效的 SMTP 配置",
config: SMTPConfig{
Enable: true,
Sort: 1,
Host: "smtp.gmail.com",
Port: 587,
Username: "test@gmail.com",
Password: "password",
},
wantErr: false,
},
{
name: "未啟用的配置(不驗證)",
config: SMTPConfig{
Enable: false,
},
wantErr: false,
},
{
name: "缺少 Host",
config: SMTPConfig{
Enable: true,
Port: 587,
Username: "test@gmail.com",
Password: "password",
},
wantErr: true,
errMsg: "smtp host is required",
},
{
name: "無效的 Port",
config: SMTPConfig{
Enable: true,
Host: "smtp.gmail.com",
Port: 99999,
Username: "test@gmail.com",
Password: "password",
},
wantErr: true,
errMsg: "smtp port must be between 1 and 65535",
},
{
name: "缺少 Username",
config: SMTPConfig{
Enable: true,
Host: "smtp.gmail.com",
Port: 587,
Password: "password",
},
wantErr: true,
errMsg: "smtp username is required",
},
{
name: "負數的 Sort",
config: SMTPConfig{
Enable: true,
Sort: -1,
Host: "smtp.gmail.com",
Port: 587,
Username: "test@gmail.com",
Password: "password",
},
wantErr: true,
errMsg: "smtp sort must be >= 0",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.config.Validate()
if tt.wantErr {
assert.Error(t, err)
if tt.errMsg != "" {
assert.Contains(t, err.Error(), tt.errMsg)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestAmazonSesSettings_Validate(t *testing.T) {
tests := []struct {
name string
config AmazonSesSettings
wantErr bool
errMsg string
}{
{
name: "有效的 AWS SES 配置",
config: AmazonSesSettings{
Enable: true,
Sort: 1,
PoolSize: 10,
Region: "us-west-2",
Sender: "noreply@example.com",
AccessKey: "AKIAIOSFODNN7EXAMPLE",
SecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
wantErr: false,
},
{
name: "未啟用的配置",
config: AmazonSesSettings{
Enable: false,
},
wantErr: false,
},
{
name: "缺少 Region",
config: AmazonSesSettings{
Enable: true,
Sender: "noreply@example.com",
AccessKey: "AKIAIOSFODNN7EXAMPLE",
SecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
wantErr: true,
errMsg: "aws ses region is required",
},
{
name: "缺少 AccessKey",
config: AmazonSesSettings{
Enable: true,
Region: "us-west-2",
Sender: "noreply@example.com",
SecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
wantErr: true,
errMsg: "aws ses access key is required",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.config.Validate()
if tt.wantErr {
assert.Error(t, err)
if tt.errMsg != "" {
assert.Contains(t, err.Error(), tt.errMsg)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestMitakeSMSSender_Validate(t *testing.T) {
tests := []struct {
name string
config MitakeSMSSender
wantErr bool
errMsg string
}{
{
name: "有效的 Mitake 配置",
config: MitakeSMSSender{
Enable: true,
Sort: 1,
PoolSize: 5,
User: "testuser",
Password: "testpass",
},
wantErr: false,
},
{
name: "缺少 User",
config: MitakeSMSSender{
Enable: true,
Password: "testpass",
},
wantErr: true,
errMsg: "mitake user is required",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.config.Validate()
if tt.wantErr {
assert.Error(t, err)
if tt.errMsg != "" {
assert.Contains(t, err.Error(), tt.errMsg)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestDeliveryConfig_Validate(t *testing.T) {
tests := []struct {
name string
config DeliveryConfig
wantErr bool
errMsg string
}{
{
name: "有效的配置",
config: DeliveryConfig{
MaxRetries: 3,
InitialDelay: 100 * time.Millisecond,
BackoffFactor: 2.0,
MaxDelay: 30 * time.Second,
Timeout: 30 * time.Second,
},
wantErr: false,
},
{
name: "MaxRetries 為負數",
config: DeliveryConfig{
MaxRetries: -1,
Timeout: 30 * time.Second,
},
wantErr: true,
errMsg: "max_retries must be >= 0",
},
{
name: "MaxRetries 過大",
config: DeliveryConfig{
MaxRetries: 20,
Timeout: 30 * time.Second,
},
wantErr: true,
errMsg: "max_retries should not exceed 10",
},
{
name: "BackoffFactor 小於 1.0",
config: DeliveryConfig{
MaxRetries: 3,
BackoffFactor: 0.5,
Timeout: 30 * time.Second,
},
wantErr: true,
errMsg: "backoff_factor must be >= 1.0",
},
{
name: "Timeout 為 0",
config: DeliveryConfig{
MaxRetries: 3,
BackoffFactor: 2.0,
Timeout: 0,
},
wantErr: true,
errMsg: "timeout must be > 0",
},
{
name: "InitialDelay 大於 MaxDelay",
config: DeliveryConfig{
MaxRetries: 3,
InitialDelay: 1 * time.Minute,
MaxDelay: 10 * time.Second,
Timeout: 30 * time.Second,
},
wantErr: true,
errMsg: "initial_delay",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.config.Validate()
if tt.wantErr {
assert.Error(t, err)
if tt.errMsg != "" {
assert.Contains(t, err.Error(), tt.errMsg)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestDeliveryConfig_SetDefaults(t *testing.T) {
config := DeliveryConfig{}
config.SetDefaults()
assert.Equal(t, 3, config.MaxRetries)
assert.Equal(t, 100*time.Millisecond, config.InitialDelay)
assert.Equal(t, 2.0, config.BackoffFactor)
assert.Equal(t, 30*time.Second, config.MaxDelay)
assert.Equal(t, 30*time.Second, config.Timeout)
// 測試不覆蓋已設置的值
config2 := DeliveryConfig{
MaxRetries: 5,
Timeout: 60 * time.Second,
}
config2.SetDefaults()
assert.Equal(t, 5, config2.MaxRetries) // 保持原值
assert.Equal(t, 60*time.Second, config2.Timeout) // 保持原值
assert.Equal(t, 100*time.Millisecond, config2.InitialDelay) // 設置默認值
}