146 lines
3.3 KiB
Go
146 lines
3.3 KiB
Go
|
|
package auth
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"testing"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// TestHashPassword 测试密码加密
|
|||
|
|
func TestHashPassword(t *testing.T) {
|
|||
|
|
tests := []struct {
|
|||
|
|
name string
|
|||
|
|
password string
|
|||
|
|
wantError bool
|
|||
|
|
}{
|
|||
|
|
{
|
|||
|
|
name: "正常密码",
|
|||
|
|
password: "testpassword123",
|
|||
|
|
wantError: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "空密码",
|
|||
|
|
password: "",
|
|||
|
|
wantError: false, // bcrypt允许空密码
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "长密码",
|
|||
|
|
password: "thisisaverylongpasswordthatexceedsnormallength",
|
|||
|
|
wantError: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "包含特殊字符的密码",
|
|||
|
|
password: "P@ssw0rd!#$%",
|
|||
|
|
wantError: false,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for _, tt := range tests {
|
|||
|
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
|
hashed, err := HashPassword(tt.password)
|
|||
|
|
if (err != nil) != tt.wantError {
|
|||
|
|
t.Errorf("HashPassword() error = %v, wantError %v", err, tt.wantError)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if !tt.wantError {
|
|||
|
|
// 验证哈希值不为空
|
|||
|
|
if hashed == "" {
|
|||
|
|
t.Error("HashPassword() 返回的哈希值不应为空")
|
|||
|
|
}
|
|||
|
|
// 验证哈希值与原密码不同
|
|||
|
|
if hashed == tt.password {
|
|||
|
|
t.Error("HashPassword() 返回的哈希值不应与原密码相同")
|
|||
|
|
}
|
|||
|
|
// 验证哈希值长度合理(bcrypt哈希通常是60个字符)
|
|||
|
|
if len(hashed) < 50 {
|
|||
|
|
t.Errorf("HashPassword() 返回的哈希值长度异常: %d", len(hashed))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestCheckPassword 测试密码验证
|
|||
|
|
func TestCheckPassword(t *testing.T) {
|
|||
|
|
// 先加密一个密码
|
|||
|
|
password := "testpassword123"
|
|||
|
|
hashed, err := HashPassword(password)
|
|||
|
|
if err != nil {
|
|||
|
|
t.Fatalf("HashPassword() 失败: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
tests := []struct {
|
|||
|
|
name string
|
|||
|
|
hashedPassword string
|
|||
|
|
password string
|
|||
|
|
wantMatch bool
|
|||
|
|
}{
|
|||
|
|
{
|
|||
|
|
name: "密码匹配",
|
|||
|
|
hashedPassword: hashed,
|
|||
|
|
password: password,
|
|||
|
|
wantMatch: true,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "密码不匹配",
|
|||
|
|
hashedPassword: hashed,
|
|||
|
|
password: "wrongpassword",
|
|||
|
|
wantMatch: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: "空密码与空哈希",
|
|||
|
|
hashedPassword: "",
|
|||
|
|
password: "",
|
|||
|
|
wantMatch: false, // 空哈希无法验证
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for _, tt := range tests {
|
|||
|
|
t.Run(tt.name, func(t *testing.T) {
|
|||
|
|
result := CheckPassword(tt.hashedPassword, tt.password)
|
|||
|
|
if result != tt.wantMatch {
|
|||
|
|
t.Errorf("CheckPassword() = %v, want %v", result, tt.wantMatch)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestHashPassword_Uniqueness 测试每次加密结果不同
|
|||
|
|
func TestHashPassword_Uniqueness(t *testing.T) {
|
|||
|
|
password := "testpassword123"
|
|||
|
|
|
|||
|
|
// 多次加密同一密码
|
|||
|
|
hashes := make(map[string]bool)
|
|||
|
|
for i := 0; i < 10; i++ {
|
|||
|
|
hashed, err := HashPassword(password)
|
|||
|
|
if err != nil {
|
|||
|
|
t.Fatalf("HashPassword() 失败: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证每次加密的结果都不同(由于salt)
|
|||
|
|
if hashes[hashed] {
|
|||
|
|
t.Errorf("第%d次加密的结果与之前重复", i+1)
|
|||
|
|
}
|
|||
|
|
hashes[hashed] = true
|
|||
|
|
|
|||
|
|
// 但都能验证通过
|
|||
|
|
if !CheckPassword(hashed, password) {
|
|||
|
|
t.Errorf("第%d次加密的哈希无法验证原密码", i+1)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestCheckPassword_Consistency 测试密码验证的一致性
|
|||
|
|
func TestCheckPassword_Consistency(t *testing.T) {
|
|||
|
|
password := "testpassword123"
|
|||
|
|
hashed, err := HashPassword(password)
|
|||
|
|
if err != nil {
|
|||
|
|
t.Fatalf("HashPassword() 失败: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 多次验证应该结果一致
|
|||
|
|
for i := 0; i < 10; i++ {
|
|||
|
|
if !CheckPassword(hashed, password) {
|
|||
|
|
t.Errorf("第%d次验证失败", i+1)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|