package payment import ( "os" "strings" "testing" ) // TestMain 固定测试用加密主密钥(masterKey 只会解析一次) // Logan.Li func TestMain(m *testing.M) { os.Setenv(EnvPaymentMasterKey, "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") os.Setenv("PAYMENT_CERT_DIR", os.TempDir()+"/opsx-licence-test-certs") os.Exit(m.Run()) } // TestEncryptDecryptRoundTrip 验证 AES-GCM 加解密与密文格式 // Logan.Li func TestEncryptDecryptRoundTrip(t *testing.T) { plain := "wx-api-v3-key-32-bytes-example!!" enc, err := EncryptSecret(plain) if err != nil { t.Fatalf("加密失败: %v", err) } if !strings.HasPrefix(enc, cipherPrefix) { t.Fatalf("密文缺少前缀: %s", enc) } if strings.Contains(enc, plain) { t.Fatalf("密文中出现了明文") } got, err := DecryptSecret(enc) if err != nil { t.Fatalf("解密失败: %v", err) } if got != plain { t.Fatalf("解密结果不一致: %q", got) } // 同一明文两次加密应产生不同密文(随机 nonce) // Logan.Li enc2, _ := EncryptSecret(plain) if enc == enc2 { t.Fatalf("两次加密结果相同,nonce 未随机化") } } // TestEncryptSecretEmpty 空值不应产生密文 // Logan.Li func TestEncryptSecretEmpty(t *testing.T) { enc, err := EncryptSecret(" ") if err != nil || enc != "" { t.Fatalf("空值加密应返回空串,得到 %q err=%v", enc, err) } if v, err := DecryptSecret(""); err != nil || v != "" { t.Fatalf("空密文应返回空串,得到 %q err=%v", v, err) } } // TestDecryptTampered 篡改密文必须解密失败 // Logan.Li func TestDecryptTampered(t *testing.T) { enc, _ := EncryptSecret("secret-value") tampered := enc[:len(enc)-4] + "AAAA" if _, err := DecryptSecret(tampered); err == nil { t.Fatalf("篡改后的密文不应解密成功") } } // TestMaskTail 脱敏仅保留末位 // Logan.Li func TestMaskTail(t *testing.T) { masked := MaskTail("0123456789abcdef0123456789abcdef", 4, 32) if !strings.HasSuffix(masked, "cdef") { t.Fatalf("脱敏结果应保留后 4 位: %s", masked) } if len([]rune(masked)) != 32 { t.Fatalf("脱敏长度应为 32: %d", len([]rune(masked))) } if MaskTail("", 4, 32) != "" { t.Fatalf("空值脱敏应为空串") } } // TestPayMethods 支付方式校验/去重与展示解析 // Logan.Li func TestPayMethods(t *testing.T) { got, err := normalizePayMethods([]string{"native", " h5 ", "native", "JSAPI"}) if err != nil { t.Fatalf("合法支付方式不应报错: %v", err) } want := []string{"native", "h5", "jsapi"} if len(got) != len(want) { t.Fatalf("解析结果数量不符: %v", got) } for i := range want { if got[i] != want[i] { t.Fatalf("解析结果不符: %v", got) } } if _, err := normalizePayMethods([]string{"alipay"}); err == nil { t.Fatalf("非法支付方式应报错") } if _, err := normalizePayMethods(nil); err == nil { t.Fatalf("空支付方式应报错") } if def := splitPayMethods(""); len(def) != 1 || def[0] != "native" { t.Fatalf("空串展示应回退 native: %v", def) } } // TestNormalizePEM 裸 base64 自动补 PEM 头 // Logan.Li func TestNormalizePEM(t *testing.T) { out := NormalizePEM("QUJDREVGRw==", "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----") if !strings.HasPrefix(out, "-----BEGIN PUBLIC KEY-----") || !strings.Contains(out, "QUJDREVGRw==") { t.Fatalf("PEM 补全失败: %s", out) } }