- Updated main.go to initialize email service and include it in the dependency injection container. - Refactored handlers to utilize context in service method calls, improving consistency and error handling. - Introduced new service options for upload, security, and captcha services, enhancing modularity and testability. - Removed unused repository implementations to streamline the codebase. This commit continues the effort to improve the architecture by ensuring all services are properly injected and utilized across the application.
124 lines
2.8 KiB
Go
124 lines
2.8 KiB
Go
package service
|
||
|
||
import (
|
||
"testing"
|
||
"time"
|
||
)
|
||
|
||
// TestGenerateVerificationCode 测试生成验证码函数
|
||
func TestGenerateVerificationCode(t *testing.T) {
|
||
// 创建服务实例(使用 nil,因为这个测试不需要依赖)
|
||
svc := &verificationService{}
|
||
|
||
tests := []struct {
|
||
name string
|
||
wantLen int
|
||
wantErr bool
|
||
}{
|
||
{
|
||
name: "生成6位验证码",
|
||
wantLen: CodeLength,
|
||
wantErr: false,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
code, err := svc.generateCode()
|
||
if (err != nil) != tt.wantErr {
|
||
t.Errorf("generateCode() error = %v, wantErr %v", err, tt.wantErr)
|
||
return
|
||
}
|
||
if !tt.wantErr && len(code) != tt.wantLen {
|
||
t.Errorf("generateCode() code length = %v, want %v", len(code), tt.wantLen)
|
||
}
|
||
// 验证验证码只包含数字
|
||
for _, c := range code {
|
||
if c < '0' || c > '9' {
|
||
t.Errorf("generateCode() code contains non-digit: %c", c)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 测试多次生成,验证码应该不同(概率上)
|
||
codes := make(map[string]bool)
|
||
for i := 0; i < 100; i++ {
|
||
code, err := svc.generateCode()
|
||
if err != nil {
|
||
t.Fatalf("generateCode() failed: %v", err)
|
||
}
|
||
if codes[code] {
|
||
t.Logf("发现重复验证码(这是正常的,因为只有6位数字): %s", code)
|
||
}
|
||
codes[code] = true
|
||
}
|
||
}
|
||
|
||
// TestVerificationConstants 测试验证码相关常量
|
||
func TestVerificationConstants(t *testing.T) {
|
||
if CodeLength != 6 {
|
||
t.Errorf("CodeLength = %d, want 6", CodeLength)
|
||
}
|
||
|
||
if CodeExpiration != 10*time.Minute {
|
||
t.Errorf("CodeExpiration = %v, want 10 minutes", CodeExpiration)
|
||
}
|
||
|
||
if CodeRateLimit != 1*time.Minute {
|
||
t.Errorf("CodeRateLimit = %v, want 1 minute", CodeRateLimit)
|
||
}
|
||
|
||
// 验证验证码类型常量
|
||
types := []string{
|
||
VerificationTypeRegister,
|
||
VerificationTypeResetPassword,
|
||
VerificationTypeChangeEmail,
|
||
}
|
||
|
||
for _, vType := range types {
|
||
if vType == "" {
|
||
t.Error("验证码类型不能为空")
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestVerificationCodeFormat 测试验证码格式
|
||
func TestVerificationCodeFormat(t *testing.T) {
|
||
svc := &verificationService{}
|
||
code, err := svc.generateCode()
|
||
if err != nil {
|
||
t.Fatalf("generateCode() failed: %v", err)
|
||
}
|
||
|
||
// 验证长度
|
||
if len(code) != 6 {
|
||
t.Errorf("验证码长度应为6位,实际为%d位", len(code))
|
||
}
|
||
|
||
// 验证只包含数字
|
||
for i, c := range code {
|
||
if c < '0' || c > '9' {
|
||
t.Errorf("验证码第%d位包含非数字字符: %c", i+1, c)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestVerificationTypes 测试验证码类型
|
||
func TestVerificationTypes(t *testing.T) {
|
||
validTypes := map[string]bool{
|
||
VerificationTypeRegister: true,
|
||
VerificationTypeResetPassword: true,
|
||
VerificationTypeChangeEmail: true,
|
||
}
|
||
|
||
for vType, isValid := range validTypes {
|
||
if !isValid {
|
||
t.Errorf("验证码类型 %s 应该是有效的", vType)
|
||
}
|
||
if vType == "" {
|
||
t.Error("验证码类型不能为空字符串")
|
||
}
|
||
}
|
||
}
|