tianyuan-api-server/pkg/jwt/jwtx_test.go

217 lines
5.1 KiB
Go
Raw Permalink Normal View History

2025-07-13 21:41:49 +08:00
package jwtx
import (
"fmt"
"testing"
)
func TestGenerateJwtToken(t *testing.T) {
tests := []struct {
name string
userId int64
secret string
expireTime int64
wantErr bool
}{
{
name: "正常情况 - 生成有效token",
userId: 144,
secret: "Mf5Xph3PoyKzVpRw0Zy1+X4uR/tM7JvGMEV/5p2M/tU=",
expireTime: 3600, // 1小时
wantErr: false,
},
{
name: "用户ID为0",
userId: 0,
secret: "test-secret-key",
expireTime: 3600,
wantErr: false,
},
{
name: "用户ID为负数",
userId: -1,
secret: "test-secret-key",
expireTime: 3600,
wantErr: false,
},
{
name: "过期时间为0",
userId: 12345,
secret: "test-secret-key",
expireTime: 0,
wantErr: false,
},
{
name: "过期时间为负数",
userId: 12345,
secret: "test-secret-key",
expireTime: -3600,
wantErr: false,
},
{
name: "空密钥",
userId: 12345,
secret: "",
expireTime: 3600,
wantErr: false,
},
{
name: "长密钥",
userId: 12345,
secret: "very-long-secret-key-that-is-more-than-32-characters-long",
expireTime: 3600,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
token, err := GenerateJwtToken(tt.userId, tt.secret, tt.expireTime)
fmt.Printf("tt.userId: %d, token: %s\n", tt.userId, token)
if (err != nil) != tt.wantErr {
t.Errorf("GenerateJwtToken() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr {
// 验证token不为空
if token == "" {
t.Error("GenerateJwtToken() returned empty token")
return
}
// 验证token长度合理
if len(token) < 10 {
t.Errorf("GenerateJwtToken() returned token too short: %s", token)
return
}
// 验证可以解析token对于过期时间为0或负数的情况token会立即过期
if tt.expireTime <= 0 {
// 对于立即过期的token我们只验证生成成功不验证解析
return
}
parsedUserId, parseErr := ParseJwtToken(token, tt.secret)
if parseErr != nil {
t.Errorf("Failed to parse generated token: %v", parseErr)
return
}
if parsedUserId != tt.userId {
t.Errorf("Parsed userId = %v, want %v", parsedUserId, tt.userId)
}
}
})
}
}
func TestGenerateJwtToken_ExpirationTime(t *testing.T) {
userId := int64(12345)
secret := "test-secret-key"
expireTime := int64(3600) // 1小时
token, err := GenerateJwtToken(userId, secret, expireTime)
if err != nil {
t.Fatalf("GenerateJwtToken() failed: %v", err)
}
// 验证token可以立即解析
parsedUserId, err := ParseJwtToken(token, secret)
if err != nil {
t.Fatalf("Failed to parse token immediately: %v", err)
}
if parsedUserId != userId {
t.Errorf("Parsed userId = %v, want %v", parsedUserId, userId)
}
}
func TestGenerateJwtToken_Consistency(t *testing.T) {
userId := int64(12345)
secret := "test-secret-key"
expireTime := int64(3600)
// 生成多个token验证相同参数生成的token是一致的
var firstToken string
for i := 0; i < 5; i++ {
token, err := GenerateJwtToken(userId, secret, expireTime)
if err != nil {
t.Fatalf("GenerateJwtToken() failed on iteration %d: %v", i, err)
}
if i == 0 {
firstToken = token
} else {
// 由于JWT基于相同claims生成相同参数应该产生相同的token
// 但由于时间戳可能略有差异我们验证token长度和格式一致
if len(token) != len(firstToken) {
t.Errorf("Token length inconsistent: got %d, want %d", len(token), len(firstToken))
}
}
}
}
func TestGenerateJwtToken_LargeUserId(t *testing.T) {
// 测试大数值的userId
largeUserId := int64(999999999999999) // 使用一个大的但合理的值
secret := "test-secret-key"
expireTime := int64(3600)
token, err := GenerateJwtToken(largeUserId, secret, expireTime)
if err != nil {
t.Fatalf("GenerateJwtToken() failed with large userId: %v", err)
}
parsedUserId, err := ParseJwtToken(token, secret)
if err != nil {
t.Fatalf("Failed to parse token with large userId: %v", err)
}
if parsedUserId != largeUserId {
t.Errorf("Parsed userId = %v, want %v", parsedUserId, largeUserId)
}
}
func TestGenerateJwtToken_Concurrent(t *testing.T) {
userId := int64(12345)
secret := "test-secret-key"
expireTime := int64(3600)
// 并发测试
done := make(chan bool, 10)
for i := 0; i < 10; i++ {
go func() {
token, err := GenerateJwtToken(userId, secret, expireTime)
if err != nil {
t.Errorf("GenerateJwtToken() failed in goroutine: %v", err)
done <- false
return
}
parsedUserId, err := ParseJwtToken(token, secret)
if err != nil {
t.Errorf("Failed to parse token in goroutine: %v", err)
done <- false
return
}
if parsedUserId != userId {
t.Errorf("Parsed userId = %v, want %v in goroutine", parsedUserId, userId)
done <- false
return
}
done <- true
}()
}
// 等待所有goroutine完成
for i := 0; i < 10; i++ {
if !<-done {
t.Fail()
}
}
}