339 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			339 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package entities | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"testing" | ||
|  | ) | ||
|  | 
 | ||
|  | func TestUser_ChangePassword(t *testing.T) { | ||
|  | 	// 创建测试用户 | ||
|  | 	user, err := NewUser("13800138000", "OldPassword123!") | ||
|  | 	if err != nil { | ||
|  | 		t.Fatalf("创建用户失败: %v", err) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name            string | ||
|  | 		oldPassword     string | ||
|  | 		newPassword     string | ||
|  | 		confirmPassword string | ||
|  | 		wantErr         bool | ||
|  | 		errorContains   string | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:            "正常修改密码", | ||
|  | 			oldPassword:     "OldPassword123!", | ||
|  | 			newPassword:     "NewPassword123!", | ||
|  | 			confirmPassword: "NewPassword123!", | ||
|  | 			wantErr:         false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:            "旧密码错误", | ||
|  | 			oldPassword:     "WrongPassword123!", | ||
|  | 			newPassword:     "NewPassword123!", | ||
|  | 			confirmPassword: "NewPassword123!", | ||
|  | 			wantErr:         true, | ||
|  | 			errorContains:   "当前密码错误", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:            "确认密码不匹配", | ||
|  | 			oldPassword:     "OldPassword123!", | ||
|  | 			newPassword:     "NewPassword123!", | ||
|  | 			confirmPassword: "DifferentPassword123!", | ||
|  | 			wantErr:         true, | ||
|  | 			errorContains:   "新密码和确认新密码不匹配", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:            "新密码与旧密码相同", | ||
|  | 			oldPassword:     "OldPassword123!", | ||
|  | 			newPassword:     "OldPassword123!", | ||
|  | 			confirmPassword: "OldPassword123!", | ||
|  | 			wantErr:         true, | ||
|  | 			errorContains:   "新密码不能与当前密码相同", | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:            "新密码强度不足", | ||
|  | 			oldPassword:     "OldPassword123!", | ||
|  | 			newPassword:     "weak", | ||
|  | 			confirmPassword: "weak", | ||
|  | 			wantErr:         true, | ||
|  | 			errorContains:   "密码长度至少8位", | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			// 重置用户密码为初始状态 | ||
|  | 			user.SetPassword("OldPassword123!") | ||
|  | 
 | ||
|  | 			err := user.ChangePassword(tt.oldPassword, tt.newPassword, tt.confirmPassword) | ||
|  | 			if tt.wantErr { | ||
|  | 				if err == nil { | ||
|  | 					t.Errorf("期望错误但没有得到错误") | ||
|  | 					return | ||
|  | 				} | ||
|  | 				if tt.errorContains != "" && !contains(err.Error(), tt.errorContains) { | ||
|  | 					t.Errorf("错误信息不包含期望的内容,期望包含: %s, 实际: %s", tt.errorContains, err.Error()) | ||
|  | 				} | ||
|  | 			} else { | ||
|  | 				if err != nil { | ||
|  | 					t.Errorf("不期望错误但得到了错误: %v", err) | ||
|  | 				} | ||
|  | 				// 验证密码确实被修改了 | ||
|  | 				if !user.CheckPassword(tt.newPassword) { | ||
|  | 					t.Errorf("密码修改后验证失败") | ||
|  | 				} | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestUser_CheckPassword(t *testing.T) { | ||
|  | 	user, err := NewUser("13800138000", "TestPassword123!") | ||
|  | 	if err != nil { | ||
|  | 		t.Fatalf("创建用户失败: %v", err) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		password string | ||
|  | 		want     bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "正确密码", | ||
|  | 			password: "TestPassword123!", | ||
|  | 			want:     true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "错误密码", | ||
|  | 			password: "WrongPassword123!", | ||
|  | 			want:     false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "空密码", | ||
|  | 			password: "", | ||
|  | 			want:     false, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			got := user.CheckPassword(tt.password) | ||
|  | 			if got != tt.want { | ||
|  | 				t.Errorf("CheckPassword() = %v, want %v", got, tt.want) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestUser_SetPhone(t *testing.T) { | ||
|  | 	user := &User{} | ||
|  | 
 | ||
|  | 	tests := []struct { | ||
|  | 		name    string | ||
|  | 		phone   string | ||
|  | 		wantErr bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:    "有效手机号", | ||
|  | 			phone:   "13800138000", | ||
|  | 			wantErr: false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:    "无效手机号-太短", | ||
|  | 			phone:   "1380013800", | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:    "无效手机号-太长", | ||
|  | 			phone:   "138001380000", | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:    "无效手机号-格式错误", | ||
|  | 			phone:   "1380013800a", | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:    "无效手机号-不以1开头", | ||
|  | 			phone:   "23800138000", | ||
|  | 			wantErr: true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			err := user.SetPhone(tt.phone) | ||
|  | 			if tt.wantErr { | ||
|  | 				if err == nil { | ||
|  | 					t.Errorf("期望错误但没有得到错误") | ||
|  | 				} | ||
|  | 			} else { | ||
|  | 				if err != nil { | ||
|  | 					t.Errorf("不期望错误但得到了错误: %v", err) | ||
|  | 				} | ||
|  | 				if user.Phone != tt.phone { | ||
|  | 					t.Errorf("手机号设置失败,期望: %s, 实际: %s", tt.phone, user.Phone) | ||
|  | 				} | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestUser_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) { | ||
|  | 			user := &User{Phone: tt.phone} | ||
|  | 			got := user.GetMaskedPhone() | ||
|  | 			if got != tt.expected { | ||
|  | 				t.Errorf("GetMaskedPhone() = %v, want %v", got, tt.expected) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestIsValidPhoneFormat(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name  string | ||
|  | 		phone string | ||
|  | 		want  bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:  "有效手机号-13开头", | ||
|  | 			phone: "13800138000", | ||
|  | 			want:  true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "有效手机号-15开头", | ||
|  | 			phone: "15800138000", | ||
|  | 			want:  true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "有效手机号-18开头", | ||
|  | 			phone: "18800138000", | ||
|  | 			want:  true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "无效手机号-12开头", | ||
|  | 			phone: "12800138000", | ||
|  | 			want:  false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "无效手机号-20开头", | ||
|  | 			phone: "20800138000", | ||
|  | 			want:  false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "无效手机号-太短", | ||
|  | 			phone: "1380013800", | ||
|  | 			want:  false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "无效手机号-太长", | ||
|  | 			phone: "138001380000", | ||
|  | 			want:  false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "无效手机号-包含字母", | ||
|  | 			phone: "1380013800a", | ||
|  | 			want:  false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:  "空手机号", | ||
|  | 			phone: "", | ||
|  | 			want:  false, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			got := IsValidPhoneFormat(tt.phone) | ||
|  | 			if got != tt.want { | ||
|  | 				t.Errorf("IsValidPhoneFormat() = %v, want %v", got, tt.want) | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func TestNewUser(t *testing.T) { | ||
|  | 	tests := []struct { | ||
|  | 		name     string | ||
|  | 		phone    string | ||
|  | 		password string | ||
|  | 		wantErr  bool | ||
|  | 	}{ | ||
|  | 		{ | ||
|  | 			name:     "有效用户信息", | ||
|  | 			phone:    "13800138000", | ||
|  | 			password: "TestPassword123!", | ||
|  | 			wantErr:  false, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "无效手机号", | ||
|  | 			phone:    "1380013800", | ||
|  | 			password: "TestPassword123!", | ||
|  | 			wantErr:  true, | ||
|  | 		}, | ||
|  | 		{ | ||
|  | 			name:     "无效密码", | ||
|  | 			phone:    "13800138000", | ||
|  | 			password: "weak", | ||
|  | 			wantErr:  true, | ||
|  | 		}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	for _, tt := range tests { | ||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||
|  | 			user, err := NewUser(tt.phone, tt.password) | ||
|  | 			if tt.wantErr { | ||
|  | 				if err == nil { | ||
|  | 					t.Errorf("期望错误但没有得到错误") | ||
|  | 				} | ||
|  | 			} else { | ||
|  | 				if err != nil { | ||
|  | 					t.Errorf("不期望错误但得到了错误: %v", err) | ||
|  | 				} | ||
|  | 				if user.Phone != tt.phone { | ||
|  | 					t.Errorf("手机号设置失败,期望: %s, 实际: %s", tt.phone, user.Phone) | ||
|  | 				} | ||
|  | 				if !user.CheckPassword(tt.password) { | ||
|  | 					t.Errorf("密码设置失败") | ||
|  | 				} | ||
|  | 			} | ||
|  | 		}) | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // 辅助函数 | ||
|  | func contains(s, substr string) bool { | ||
|  | 	return len(s) >= len(substr) && (s == substr || (len(s) > len(substr) && (s[:len(substr)] == substr || s[len(s)-len(substr):] == substr || func() bool { | ||
|  | 		for i := 1; i <= len(s)-len(substr); i++ { | ||
|  | 			if s[i:i+len(substr)] == substr { | ||
|  | 				return true | ||
|  | 			} | ||
|  | 		} | ||
|  | 		return false | ||
|  | 	}()))) | ||
|  | } |