682 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			682 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package entities | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"testing" | ||
|  | 	"time" | ||
|  | 
 | ||
|  | 	"github.com/stretchr/testify/assert" | ||
|  | ) | ||
|  | 
 | ||
|  | func TestSMSCode_Validate(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name    string | ||
|  | 		smsCode *SMSCode | ||
|  | 		wantErr bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "有效验证码", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "13800138000", | ||
|  | 				Code:      "123456", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "手机号为空", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "", | ||
|  | 				Code:      "123456", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "验证码为空", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "13800138000", | ||
|  | 				Code:      "", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "场景为空", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "13800138000", | ||
|  | 				Code:      "123456", | ||
|  | 				Scene:     "", | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "过期时间为零", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "13800138000", | ||
|  | 				Code:      "123456", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Time{}, | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "手机号格式无效", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "123", | ||
|  | 				Code:      "123456", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "验证码格式无效-包含字母", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "13800138000", | ||
|  | 				Code:      "12345a", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "验证码长度过短", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Phone:     "13800138000", | ||
|  | 				Code:      "123", | ||
|  | 				Scene:     SMSSceneRegister, | ||
|  | 				ExpiresAt: time.Now().Add(time.Hour), | ||
|  | 			}, | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			err := tt.smsCode.Validate() | ||
|  | 			if tt.wantErr { | ||
|  | 				assert.Error(t, err) | ||
|  | 			} else { | ||
|  | 				assert.NoError(t, err) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_VerifyCode(t *testing.T) { | ||
|  | 	now := time.Now() | ||
|  | 	expiresAt := now.Add(time.Hour) | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name      string | ||
|  | 		smsCode   *SMSCode | ||
|  | 		inputCode string | ||
|  | 		wantErr   bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "验证码正确", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Code:      "123456", | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: expiresAt, | ||
|  | 			}, | ||
|  | 			inputCode: "123456", | ||
|  | 			wantErr:   false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "验证码错误", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Code:      "123456", | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: expiresAt, | ||
|  | 			}, | ||
|  | 			inputCode: "654321", | ||
|  | 			wantErr:   true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "验证码已使用", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Code:      "123456", | ||
|  | 				Used:      true, | ||
|  | 				ExpiresAt: expiresAt, | ||
|  | 			}, | ||
|  | 			inputCode: "123456", | ||
|  | 			wantErr:   true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "验证码已过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Code:      "123456", | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: now.Add(-time.Hour), | ||
|  | 			}, | ||
|  | 			inputCode: "123456", | ||
|  | 			wantErr:   true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			err := tt.smsCode.VerifyCode(tt.inputCode) | ||
|  | 			if tt.wantErr { | ||
|  | 				assert.Error(t, err) | ||
|  | 			} else { | ||
|  | 				assert.NoError(t, err) | ||
|  | 				// 验证码正确时应该被标记为已使用 | ||
|  | 				assert.True(t, tt.smsCode.Used) | ||
|  | 				assert.NotNil(t, tt.smsCode.UsedAt) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_IsExpired(t *testing.T) { | ||
|  | 	now := time.Now() | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		smsCode  *SMSCode | ||
|  | 		expected bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "未过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				ExpiresAt: now.Add(time.Hour), | ||
|  | 			}, | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "已过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				ExpiresAt: now.Add(-time.Hour), | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "刚好过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				ExpiresAt: now, | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := tt.smsCode.IsExpired() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_IsValid(t *testing.T) { | ||
|  | 	now := time.Now() | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		smsCode  *SMSCode | ||
|  | 		expected bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "有效验证码", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: now.Add(time.Hour), | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "已使用", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      true, | ||
|  | 				ExpiresAt: now.Add(time.Hour), | ||
|  | 			}, | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "已过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: now.Add(-time.Hour), | ||
|  | 			}, | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "已使用且已过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      true, | ||
|  | 				ExpiresAt: now.Add(-time.Hour), | ||
|  | 			}, | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := tt.smsCode.IsValid() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_CanResend(t *testing.T) { | ||
|  | 	now := time.Now() | ||
|  | 	minInterval := 60 * time.Second | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		smsCode  *SMSCode | ||
|  | 		expected bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "已使用-可以重发", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      true, | ||
|  | 				CreatedAt: now.Add(-30 * time.Second), | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "已过期-可以重发", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: now.Add(-time.Hour), | ||
|  | 				CreatedAt: now.Add(-30 * time.Second), | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "未过期且未使用-间隔足够-可以重发", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: now.Add(time.Hour), | ||
|  | 				CreatedAt: now.Add(-2 * time.Minute), | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "未过期且未使用-间隔不足-不能重发", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				Used:      false, | ||
|  | 				ExpiresAt: now.Add(time.Hour), | ||
|  | 				CreatedAt: now.Add(-30 * time.Second), | ||
|  | 			}, | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := tt.smsCode.CanResend(minInterval) | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_GetRemainingTime(t *testing.T) { | ||
|  | 	now := time.Now() | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		smsCode  *SMSCode | ||
|  | 		expected time.Duration | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "未过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				ExpiresAt: now.Add(time.Hour), | ||
|  | 			}, | ||
|  | 			expected: time.Hour, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "已过期", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				ExpiresAt: now.Add(-time.Hour), | ||
|  | 			}, | ||
|  | 			expected: 0, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := tt.smsCode.GetRemainingTime() | ||
|  | 			// 由于时间计算可能有微小差异,我们检查是否在合理范围内 | ||
|  | 			if tt.expected > 0 { | ||
|  | 				assert.True(t, result > 0) | ||
|  | 				assert.True(t, result <= tt.expected) | ||
|  | 			} else { | ||
|  | 				assert.Equal(t, tt.expected, result) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_GetMaskedCode(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		code     string | ||
|  | 		expected string | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "6位验证码", | ||
|  | 			code:     "123456", | ||
|  | 			expected: "1***6", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "4位验证码", | ||
|  | 			code:     "1234", | ||
|  | 			expected: "1***4", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "短验证码", | ||
|  | 			code:     "12", | ||
|  | 			expected: "***", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "单字符", | ||
|  | 			code:     "1", | ||
|  | 			expected: "***", | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			smsCode := &SMSCode{Code: tt.code} | ||
|  | 			result := smsCode.GetMaskedCode() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_GetMaskedPhone(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		phone    string | ||
|  | 		expected string | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "标准手机号", | ||
|  | 			phone:    "13800138000", | ||
|  | 			expected: "138****8000", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "短手机号", | ||
|  | 			phone:    "138001", | ||
|  | 			expected: "138001", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "空手机号", | ||
|  | 			phone:    "", | ||
|  | 			expected: "", | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			smsCode := &SMSCode{Phone: tt.phone} | ||
|  | 			result := smsCode.GetMaskedPhone() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_IsSceneValid(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		scene    SMSScene | ||
|  | 		expected bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "注册场景", | ||
|  | 			scene:    SMSSceneRegister, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "登录场景", | ||
|  | 			scene:    SMSSceneLogin, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "无效场景", | ||
|  | 			scene:    "invalid", | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			smsCode := &SMSCode{Scene: tt.scene} | ||
|  | 			result := smsCode.IsSceneValid() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_GetSceneName(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		scene    SMSScene | ||
|  | 		expected string | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "注册场景", | ||
|  | 			scene:    SMSSceneRegister, | ||
|  | 			expected: "用户注册", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "登录场景", | ||
|  | 			scene:    SMSSceneLogin, | ||
|  | 			expected: "用户登录", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "无效场景", | ||
|  | 			scene:    "invalid", | ||
|  | 			expected: "invalid", | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			smsCode := &SMSCode{Scene: tt.scene} | ||
|  | 			result := smsCode.GetSceneName() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_IsSuspicious(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		smsCode  *SMSCode | ||
|  | 		expected bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name: "正常记录", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				IP:        "192.168.1.1", | ||
|  | 				UserAgent: "Mozilla/5.0", | ||
|  | 			}, | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "IP为空-可疑", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				IP:        "", | ||
|  | 				UserAgent: "Mozilla/5.0", | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "UserAgent为空-可疑", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				IP:        "192.168.1.1", | ||
|  | 				UserAgent: "", | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name: "IP和UserAgent都为空-可疑", | ||
|  | 			smsCode: &SMSCode{ | ||
|  | 				IP:        "", | ||
|  | 				UserAgent: "", | ||
|  | 			}, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := tt.smsCode.IsSuspicious() | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestSMSCode_GetSecurityInfo(t *testing.T) { | ||
|  | 	now := time.Now() | ||
|  | 	smsCode := &SMSCode{ | ||
|  | 		IP:        "192.168.1.1", | ||
|  | 		UserAgent: "Mozilla/5.0", | ||
|  | 		Scene:     SMSSceneRegister, | ||
|  | 		CreatedAt: now, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	securityInfo := smsCode.GetSecurityInfo() | ||
|  | 
 | ||
|  | 	assert.Equal(t, "192.168.1.1", securityInfo["ip"]) | ||
|  | 	assert.Equal(t, "Mozilla/5.0", securityInfo["user_agent"]) | ||
|  | 	assert.Equal(t, false, securityInfo["suspicious"]) | ||
|  | 	assert.Equal(t, "用户注册", securityInfo["scene"]) | ||
|  | 	assert.Equal(t, now, securityInfo["created_at"]) | ||
|  | } | ||
|  | 
 | ||
|  | func TestIsValidScene(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		scene    SMSScene | ||
|  | 		expected bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "注册场景", | ||
|  | 			scene:    SMSSceneRegister, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "登录场景", | ||
|  | 			scene:    SMSSceneLogin, | ||
|  | 			expected: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "无效场景", | ||
|  | 			scene:    "invalid", | ||
|  | 			expected: false, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := IsValidScene(tt.scene) | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestGetSceneName(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		scene    SMSScene | ||
|  | 		expected string | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "注册场景", | ||
|  | 			scene:    SMSSceneRegister, | ||
|  | 			expected: "用户注册", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "登录场景", | ||
|  | 			scene:    SMSSceneLogin, | ||
|  | 			expected: "用户登录", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "无效场景", | ||
|  | 			scene:    "invalid", | ||
|  | 			expected: "invalid", | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			result := GetSceneName(tt.scene) | ||
|  | 			assert.Equal(t, tt.expected, result) | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestNewSMSCode(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name        string | ||
|  | 		phone       string | ||
|  | 		code        string | ||
|  | 		scene       SMSScene | ||
|  | 		expireTime  time.Duration | ||
|  | 		clientIP    string | ||
|  | 		userAgent   string | ||
|  | 		expectError bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:        "有效参数", | ||
|  | 			phone:       "13800138000", | ||
|  | 			code:        "123456", | ||
|  | 			scene:       SMSSceneRegister, | ||
|  | 			expireTime:  time.Hour, | ||
|  | 			clientIP:    "192.168.1.1", | ||
|  | 			userAgent:   "Mozilla/5.0", | ||
|  | 			expectError: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:        "无效手机号", | ||
|  | 			phone:       "123", | ||
|  | 			code:        "123456", | ||
|  | 			scene:       SMSSceneRegister, | ||
|  | 			expireTime:  time.Hour, | ||
|  | 			clientIP:    "192.168.1.1", | ||
|  | 			userAgent:   "Mozilla/5.0", | ||
|  | 			expectError: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:        "无效验证码", | ||
|  | 			phone:       "13800138000", | ||
|  | 			code:        "123", | ||
|  | 			scene:       SMSSceneRegister, | ||
|  | 			expireTime:  time.Hour, | ||
|  | 			clientIP:    "192.168.1.1", | ||
|  | 			userAgent:   "Mozilla/5.0", | ||
|  | 			expectError: true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			smsCode, err := NewSMSCode(tt.phone, tt.code, tt.scene, tt.expireTime, tt.clientIP, tt.userAgent) | ||
|  | 			if tt.expectError { | ||
|  | 				assert.Error(t, err) | ||
|  | 				assert.Nil(t, smsCode) | ||
|  | 			} else { | ||
|  | 				assert.NoError(t, err) | ||
|  | 				assert.NotNil(t, smsCode) | ||
|  | 				assert.Equal(t, tt.phone, smsCode.Phone) | ||
|  | 				assert.Equal(t, tt.code, smsCode.Code) | ||
|  | 				assert.Equal(t, tt.scene, smsCode.Scene) | ||
|  | 				assert.Equal(t, tt.clientIP, smsCode.IP) | ||
|  | 				assert.Equal(t, tt.userAgent, smsCode.UserAgent) | ||
|  | 				assert.False(t, smsCode.Used) | ||
|  | 				assert.True(t, smsCode.ExpiresAt.After(time.Now())) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } |