From 227766c431cd2dc95d07b9d94083aa97467cb99a Mon Sep 17 00:00:00 2001 From: liangzai <2440983361@qq.com> Date: Sun, 13 Jul 2025 21:41:49 +0800 Subject: [PATCH] add --- apps/api/internal/logic/YYSY/yysybe08logic.go | 6 +- pkg/jwt/jwtx_test.go | 217 ++++++++++++++++++ 2 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 pkg/jwt/jwtx_test.go diff --git a/apps/api/internal/logic/YYSY/yysybe08logic.go b/apps/api/internal/logic/YYSY/yysybe08logic.go index 473479e..4362745 100644 --- a/apps/api/internal/logic/YYSY/yysybe08logic.go +++ b/apps/api/internal/logic/YYSY/yysybe08logic.go @@ -90,9 +90,9 @@ func (l *YYSYBE08Logic) YYSYBE08(req *types.Request) (resp string, err *errs.App // 4、发送请求到西部 logx.Infof("交易号:%s", transactionID) - apiRequest := common.MapStructToAPIRequest(encryptedFields, westmodel.YYSYBE08FieldMapping, "") - apiRequest["customerNumber"] = l.svcCtx.Config.WestConfig.SecretId - apiRequest["timeStamp"] = fmt.Sprintf("%d", time.Now().UnixNano()/int64(time.Millisecond)) + apiRequest := common.MapStructToAPIRequest(encryptedFields, westmodel.YYSYBE08FieldMapping, "data") + apiRequest["data"].(map[string]interface{})["customerNumber"] = l.svcCtx.Config.WestConfig.SecretId + apiRequest["data"].(map[string]interface{})["timeStamp"] = fmt.Sprintf("%d", time.Now().UnixNano()/int64(time.Millisecond)) westResp, callAPIErr := l.svcCtx.WestDexService.CallAPI("layoutIdcard", apiRequest, l.svcCtx.Config.WestConfig.SecretId) if callAPIErr != nil { if callAPIErr.Code == errs.ErrDataSource.Code { diff --git a/pkg/jwt/jwtx_test.go b/pkg/jwt/jwtx_test.go new file mode 100644 index 0000000..bcc1f92 --- /dev/null +++ b/pkg/jwt/jwtx_test.go @@ -0,0 +1,217 @@ +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() + } + } +} \ No newline at end of file