package ymt_v3 import ( "encoding/json" "fmt" "testing" ) // 测试参数(请替换为实际值) const ( testAppID = "your_app_id" testPrivateKey = `-----BEGIN PRIVATE KEY----- your_private_key_here -----END PRIVATE KEY-----` testPublicKey = `-----BEGIN PUBLIC KEY----- your_public_key_here -----END PUBLIC KEY-----` testKey = "your_encryption_key_16" testActivityNo = "your_activity_no" ) func ExampleClient_KeyOrder() { // 创建客户端 client, err := NewClient(&ClientConfig{ AppID: testAppID, PrivateKey: testPrivateKey, PublicKey: testPublicKey, Key: testKey, EncryptType: EncryptTypeAES, Env: EnvTest, }) if err != nil { fmt.Printf("创建客户端失败: %v\n", err) return } // 获取券码 resp, err := client.KeyOrder(&KeyOrderRequest{ OutBizNo: "order_001", ActivityNo: testActivityNo, Account: "18666666666", NotifyURL: "https://notify.example.com/openapi", }) if err != nil { fmt.Printf("获取券码失败: %v\n", err) return } fmt.Printf("交易号: %s\n", resp.TradeNo) fmt.Printf("卡密: %s\n", resp.Key) fmt.Printf("状态: %d\n", resp.Status) // Output: // 交易号: 7251449503000383488 // 卡密: aZKdU9BymzR6qGRzJM // 状态: 1 } func ExampleClient_KeyQuery() { client, _ := NewClient(&ClientConfig{ AppID: testAppID, PrivateKey: testPrivateKey, PublicKey: testPublicKey, Key: testKey, EncryptType: EncryptTypeAES, Env: EnvTest, }) // 按外部业务号查询 resp, err := client.KeyQuery(&KeyQueryRequest{ OutBizNo: "order_001", }) if err != nil { fmt.Printf("查询失败: %v\n", err) return } fmt.Printf("交易号: %s\n", resp.TradeNo) fmt.Printf("状态: %d\n", resp.Status) } func ExampleClient_KeyDiscard() { client, _ := NewClient(&ClientConfig{ AppID: testAppID, PrivateKey: testPrivateKey, PublicKey: testPublicKey, Key: testKey, EncryptType: EncryptTypeAES, Env: EnvTest, }) // 按交易号作废 resp, err := client.KeyDiscard(&KeyDiscardRequest{ TradeNo: "7251449503000383488", }) if err != nil { fmt.Printf("作废失败: %v\n", err) return } fmt.Printf("交易号: %s\n", resp.TradeNo) fmt.Printf("状态: %d\n", resp.Status) } func ExampleClient_BatchOrder() { client, _ := NewClient(&ClientConfig{ AppID: testAppID, PrivateKey: testPrivateKey, PublicKey: testPublicKey, Key: testKey, EncryptType: EncryptTypeAES, Env: EnvTest, }) // 批量发卡 resp, err := client.BatchOrder(&BatchOrderRequest{ OutBizNo: "batch_001", ActivityNo: testActivityNo, Number: 100, NotifyURL: "https://notify.example.com/openapi", }) if err != nil { fmt.Printf("批量发卡失败: %v\n", err) return } fmt.Printf("交易号: %s\n", resp.TradeNo) fmt.Printf("状态: %s\n", resp.Status) } func ExampleClient_BatchQuery() { client, _ := NewClient(&ClientConfig{ AppID: testAppID, PrivateKey: testPrivateKey, PublicKey: testPublicKey, Key: testKey, EncryptType: EncryptTypeAES, Env: EnvTest, }) // 查询批量任务 resp, err := client.BatchQuery(&BatchQueryRequest{ TradeNo: "7251449503000383499", }) if err != nil { fmt.Printf("查询失败: %v\n", err) return } fmt.Printf("状态: %s\n", resp.Status) if resp.DownloadURL != "" { fmt.Printf("下载地址: %s\n", resp.DownloadURL) } } func TestMarshalWithoutZero(t *testing.T) { req := KeyOrderRequest{ OutBizNo: "order_001", ActivityNo: "ACT20260622001", // Account和NotifyURL为空,应该被去掉 } result, err := marshalWithoutZero(req) if err != nil { t.Fatalf("marshalWithoutZero失败: %v", err) } expected := `{"activity_no":"ACT20260622001","out_biz_no":"order_001"}` if result != expected { t.Errorf("期望 %s, 得到 %s", expected, result) } } func TestBuildSignStr(t *testing.T) { appID := "123456" timestamp := "2026-06-22 15:30:00" ciphertext := "encrypted_data" signStr := BuildSignStr(appID, timestamp, ciphertext) expected := "1234562026-06-22 15:30:00encrypted_data" if signStr != expected { t.Errorf("期望 %s, 得到 %s", expected, signStr) } } func TestGenerateTimestamp(t *testing.T) { ts := GenerateTimestamp() // 验证格式 yyyy-MM-dd HH:mm:ss if len(ts) != 19 { t.Errorf("时间戳格式错误: %s", ts) } } func TestEncryptDecryptAES(t *testing.T) { key := []byte("1234567890123456") // 16字节 plaintext := `{"out_biz_no":"order_001","activity_no":"ACT001"}` ciphertext, err := AESECBEncrypt([]byte(plaintext), key) if err != nil { t.Fatalf("加密失败: %v", err) } decrypted, err := AESECBDecrypt(ciphertext, key) if err != nil { t.Fatalf("解密失败: %v", err) } if string(decrypted) != plaintext { t.Errorf("解密结果不匹配: 期望 %s, 得到 %s", plaintext, string(decrypted)) } } func TestEncryptDecryptSM4(t *testing.T) { key := []byte("1234567890123456") // 16字节 plaintext := `{"out_biz_no":"order_001","activity_no":"ACT001"}` ciphertext, err := SM4CBCEncrypt([]byte(plaintext), key) if err != nil { t.Fatalf("SM4加密失败: %v", err) } decrypted, err := SM4CBCDecrypt(ciphertext, key) if err != nil { t.Fatalf("SM4解密失败: %v", err) } if string(decrypted) != plaintext { t.Errorf("SM4解密结果不匹配: 期望 %s, 得到 %s", plaintext, string(decrypted)) } } func TestEncryptBizParams(t *testing.T) { key := []byte("1234567890123456") req := KeyOrderRequest{ OutBizNo: "order_001", ActivityNo: "ACT20260622001", } ciphertext, err := EncryptBizParams(req, key, EncryptTypeAES) if err != nil { t.Fatalf("加密业务参数失败: %v", err) } if ciphertext == "" { t.Fatal("加密结果为空") } // 验证可以解密 decrypted, err := DecryptBizParams(ciphertext, key, EncryptTypeAES) if err != nil { t.Fatalf("解密失败: %v", err) } var result KeyOrderRequest if err := json.Unmarshal(decrypted, &result); err != nil { t.Fatalf("解析失败: %v", err) } if result.OutBizNo != "order_001" { t.Errorf("OutBizNo不匹配: 期望 order_001, 得到 %s", result.OutBizNo) } } func TestNewClient(t *testing.T) { _, err := NewClient(&ClientConfig{ AppID: testAppID, PrivateKey: testPrivateKey, PublicKey: testPublicKey, Key: testKey, EncryptType: EncryptTypeAES, Env: EnvTest, }) if err != nil { t.Fatalf("创建客户端失败: %v", err) } } func TestNewClientMissingFields(t *testing.T) { tests := []struct { name string config *ClientConfig wantErr bool }{ {"空AppID", &ClientConfig{PrivateKey: "pk", PublicKey: "pub", Key: "key"}, true}, {"空PrivateKey", &ClientConfig{AppID: "app", PublicKey: "pub", Key: "key"}, true}, {"空PublicKey", &ClientConfig{AppID: "app", PrivateKey: "pk", Key: "key"}, true}, {"空Key", &ClientConfig{AppID: "app", PrivateKey: "pk", PublicKey: "pub"}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := NewClient(tt.config) if (err != nil) != tt.wantErr { t.Errorf("NewClient() error = %v, wantErr = %v", err, tt.wantErr) } }) } } func TestAPIError(t *testing.T) { err := NewAPIError(401, "Signature verification failed", "INVALID_SIGNATURE") if err.Code != 401 { t.Errorf("Code不匹配: 期望 401, 得到 %d", err.Code) } if err.Message != "Signature verification failed" { t.Errorf("Message不匹配") } if err.Reason != "INVALID_SIGNATURE" { t.Errorf("Reason不匹配") } if err.Error() != "API error: code=401, message=Signature verification failed, reason=INVALID_SIGNATURE" { t.Errorf("Error()不匹配: %s", err.Error()) } if err.IsSuccess() { t.Error("401应该不是成功") } } func TestSDKError(t *testing.T) { err := NewSDKError("测试错误", nil) if err.Error() != "SDK error: 测试错误" { t.Errorf("Error()不匹配: %s", err.Error()) } }