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() } } }