package jwtx import ( "fmt" "qnc-server/app/main/model" "testing" "time" "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" ) func TestParseJwtToken(t *testing.T) { secret := "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA" tokenStr, err := GenerateJwtToken(JwtClaims{ UserId: 123, AgentId: 0, Platform: "wxh5", UserType: 0, IsAgent: 0, }, secret, 3600) assert.NoError(t, err) tests := []struct { name string tokenStr string secret string expectError bool expectClaims *JwtClaims }{ { name: "无效的token字符串", tokenStr: "invalid-token", secret: secret, expectError: true, }, { name: "空token字符串", tokenStr: "", secret: secret, expectError: true, }, { name: "错误的密钥", tokenStr: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHRyYSI6eyJ1c2VySWQiOjEyMywiYWdlbnRJZCI6NDU2LCJwbGF0Zm9ybSI6InRlc3QiLCJ1c2VyVHlwZSI6MSwiaXNBZ2VudCI6MH0sImV4cCI6MTczNTY4MDAwMCwiaWF0IjoxNzM1Njc5OTAwfQ.invalid-signature", secret: "wrong-secret", expectError: true, }, { name: "缺少extra字段", tokenStr: createTokenWithoutExtra(secret), secret: secret, expectError: true, }, { name: "正常解析token", tokenStr: tokenStr, secret: secret, expectError: false, expectClaims: &JwtClaims{ UserId: 123, AgentId: 456, Platform: "test", UserType: 1, IsAgent: 0, }, }, { name: "解析临时用户token", tokenStr: createTempUserToken(secret), secret: secret, expectError: false, expectClaims: &JwtClaims{ UserId: 789, AgentId: 0, Platform: "mobile", UserType: 0, IsAgent: 0, }, }, { name: "解析代理用户token", tokenStr: createAgentUserToken(secret), secret: secret, expectError: false, expectClaims: &JwtClaims{ UserId: 999, AgentId: 888, Platform: "web", UserType: 1, IsAgent: 1, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { claims, err := ParseJwtToken(tt.tokenStr, tt.secret) fmt.Printf("name: %s\n", tt.name) fmt.Printf("claims: %+v\n", claims) if tt.name == "正常解析token" { fmt.Printf("claims.UserType bool: %v\n", claims.UserType == model.UserTypeTemp) } if tt.expectError { assert.Error(t, err) assert.Nil(t, claims) } else { assert.NoError(t, err) assert.NotNil(t, claims) assert.Equal(t, tt.expectClaims.UserId, claims.UserId) assert.Equal(t, tt.expectClaims.AgentId, claims.AgentId) assert.Equal(t, tt.expectClaims.Platform, claims.Platform) assert.Equal(t, tt.expectClaims.UserType, claims.UserType) assert.Equal(t, tt.expectClaims.IsAgent, claims.IsAgent) } }) } } func TestParseJwtToken_Integration(t *testing.T) { secret := "integration-test-secret" // 测试生成和解析的集成 originalClaims := JwtClaims{ UserId: 12345, AgentId: 67890, Platform: "integration-test", UserType: 1, IsAgent: 1, } // 生成token tokenStr, err := GenerateJwtToken(originalClaims, secret, 3600) assert.NoError(t, err) assert.NotEmpty(t, tokenStr) // 解析token parsedClaims, err := ParseJwtToken(tokenStr, secret) assert.NoError(t, err) assert.NotNil(t, parsedClaims) // 验证解析结果 assert.Equal(t, originalClaims.UserId, parsedClaims.UserId) assert.Equal(t, originalClaims.AgentId, parsedClaims.AgentId) assert.Equal(t, originalClaims.Platform, parsedClaims.Platform) assert.Equal(t, originalClaims.UserType, parsedClaims.UserType) assert.Equal(t, originalClaims.IsAgent, parsedClaims.IsAgent) } func TestParseJwtToken_EdgeCases(t *testing.T) { secret := "edge-case-secret" t.Run("过期的token", func(t *testing.T) { // 创建一个已过期的token expiredToken := createExpiredToken(secret) claims, err := ParseJwtToken(expiredToken, secret) assert.Error(t, err) assert.Nil(t, claims) }) t.Run("extra字段为nil", func(t *testing.T) { // 创建一个extra字段为nil的token nilExtraToken := createTokenWithNilExtra(secret) claims, err := ParseJwtToken(nilExtraToken, secret) assert.Error(t, err) assert.Nil(t, claims) }) t.Run("extra字段类型错误", func(t *testing.T) { // 创建一个extra字段类型错误的token wrongTypeToken := createTokenWithWrongExtraType(secret) claims, err := ParseJwtToken(wrongTypeToken, secret) assert.Error(t, err) assert.Nil(t, claims) }) } // 辅助函数:创建有效的token func createValidToken(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now + 3600, "iat": now, "userId": 123, ExtraKey: map[string]interface{}{ "userId": 123, "agentId": 456, "platform": "test", "userType": 1, "isAgent": 0, }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr } // 辅助函数:创建临时用户token func createTempUserToken(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now + 3600, "iat": now, "userId": 789, ExtraKey: map[string]interface{}{ "userId": 789, "agentId": 0, "platform": "mobile", "userType": 0, "isAgent": 0, }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr } // 辅助函数:创建代理用户token func createAgentUserToken(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now + 3600, "iat": now, "userId": 999, ExtraKey: map[string]interface{}{ "userId": 999, "agentId": 888, "platform": "web", "userType": 1, "isAgent": 1, }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr } // 辅助函数:创建缺少extra字段的token func createTokenWithoutExtra(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now + 3600, "iat": now, "userId": 123, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr } // 辅助函数:创建已过期的token func createExpiredToken(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now - 3600, // 已过期 "iat": now - 7200, "userId": 123, ExtraKey: map[string]interface{}{ "userId": 123, "agentId": 456, "platform": "test", "userType": 1, "isAgent": 0, }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr } // 辅助函数:创建extra字段为nil的token func createTokenWithNilExtra(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now + 3600, "iat": now, "userId": 123, ExtraKey: nil, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr } // 辅助函数:创建extra字段类型错误的token func createTokenWithWrongExtraType(secret string) string { now := time.Now().Unix() claims := jwt.MapClaims{ "exp": now + 3600, "iat": now, "userId": 123, ExtraKey: "wrong-type", // 应该是map[string]interface{} } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenStr, _ := token.SignedString([]byte(secret)) return tokenStr }