1
0
mirror of synced 2026-10-17 21:06:13 +08:00

: white_check_mark: 启用离线测试门禁并修复解析与测试配置问题

This commit is contained in:
Binary Wang
2026-09-13 12:06:07 +08:00
parent f95fd76b05
commit 1bcb7b3873
33 changed files with 346 additions and 197 deletions

View File

@@ -11,47 +11,23 @@ import static org.testng.Assert.*;
public class WxPayConfigPrivateKeyTest {
@Test
public void testPrivateKeyStringFormat_PemFormat() {
public void testPrivateKeyStringFormat_PemFormat() throws Exception {
java.security.KeyPairGenerator generator = java.security.KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
java.security.KeyPair pair = generator.generateKeyPair();
java.util.Base64.Encoder encoder = java.util.Base64.getMimeEncoder(64, new byte[]{'\n'});
WxPayConfig config = new WxPayConfig();
// Set minimal required configuration
config.setMchId("1234567890");
config.setApiV3Key("test-api-v3-key-32-characters-long");
config.setCertSerialNo("test-serial-number");
// Test with PEM format private key string that would previously fail
String pemKey = "-----BEGIN PRIVATE KEY-----\n" +
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2pK3buBufh8Vo\n" +
"X4sfYbZ5CcPeGMnVQTGmj0b6\n" +
"-----END PRIVATE KEY-----";
config.setPrivateKeyString(pemKey);
// This should not throw a "无效的密钥格式" exception immediately
// The actual key validation will happen during HTTP client initialization
// but at least the format parsing should not fail
try {
// Try to initialize API V3 HTTP client - this might fail for other reasons
// (like invalid key content) but should not fail due to format parsing
config.initApiV3HttpClient();
// If we get here without InvalidKeySpecException, the format detection worked
} catch (WxPayException e) {
// Check that it's not the specific "无效的密钥格式" error from PemUtils
if (e.getCause() != null &&
e.getCause().getMessage() != null &&
e.getCause().getMessage().contains("无效的密钥格式")) {
fail("Private key format detection failed - PEM format was not handled correctly: " + e.getMessage());
}
// Other exceptions are acceptable for this test since we're using a dummy key
} catch (Exception e) {
// Check for the specific InvalidKeySpecException that indicates format problems
if (e.getCause() != null &&
e.getCause().getMessage() != null &&
e.getCause().getMessage().contains("无效的密钥格式")) {
fail("Private key format detection failed - PEM format was not handled correctly: " + e.getMessage());
}
// Other exceptions are acceptable for this test since we're using a dummy key
config.setPrivateKeyString("-----BEGIN PRIVATE KEY-----\n"
+ encoder.encodeToString(pair.getPrivate().getEncoded()) + "\n-----END PRIVATE KEY-----");
config.setFullPublicKeyModel(true);
config.setPublicKeyId("PUB_KEY_ID_TEST");
config.setPublicKeyString("-----BEGIN PUBLIC KEY-----\n"
+ encoder.encodeToString(pair.getPublic().getEncoded()) + "\n-----END PUBLIC KEY-----");
try (org.apache.http.impl.client.CloseableHttpClient client = config.initApiV3HttpClient()) {
assertNotNull(client);
}
}
@@ -113,4 +89,4 @@ public class WxPayConfigPrivateKeyTest {
// Other exceptions are acceptable for this test since we're using a dummy cert
}
}
}
}

View File

@@ -22,16 +22,18 @@ public class AutoUpdateCertificatesVerifierPublicKeyModeTest {
private WxPayCredentials credentials;
@BeforeMethod
public void setUp() {
public void setUp() throws Exception {
// 使用无效的配置,模拟证书下载失败的场景
invalidMchId = "invalid_mch_id";
invalidApiV3Key = "invalid_api_v3_key_must_be_32_b";
invalidCertSerialNo = "invalid_serial_no";
payBaseUrl = "https://api.mch.weixin.qq.com";
java.security.KeyPairGenerator generator = java.security.KeyPairGenerator.getInstance("RSA");
generator.initialize(2048);
credentials = new WxPayCredentials(
invalidMchId,
new PrivateKeySigner(invalidCertSerialNo, null)
new PrivateKeySigner(invalidCertSerialNo, generator.generateKeyPair().getPrivate())
);
}
@@ -48,7 +50,14 @@ public class AutoUpdateCertificatesVerifierPublicKeyModeTest {
60,
payBaseUrl,
null
);
) {
@Override
public void customHttpClientBuilder(com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder builder) {
builder.addInterceptorFirst((org.apache.http.HttpRequestInterceptor) (request, context) -> {
throw new java.io.IOException("simulated certificate download failure");
});
}
};
// 如果没有抛出异常,测试通过
assertNotNull(verifier);
}
@@ -64,7 +73,14 @@ public class AutoUpdateCertificatesVerifierPublicKeyModeTest {
60,
payBaseUrl,
null
);
) {
@Override
public void customHttpClientBuilder(com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder builder) {
builder.addInterceptorFirst((org.apache.http.HttpRequestInterceptor) (request, context) -> {
throw new java.io.IOException("simulated certificate download failure");
});
}
};
// verify 方法应该返回 false,而不是抛出异常
boolean result = verifier.verify("test_serial", "test_message".getBytes(), "test_signature");
@@ -83,7 +99,14 @@ public class AutoUpdateCertificatesVerifierPublicKeyModeTest {
60,
payBaseUrl,
null
);
) {
@Override
public void customHttpClientBuilder(com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder builder) {
builder.addInterceptorFirst((org.apache.http.HttpRequestInterceptor) (request, context) -> {
throw new java.io.IOException("simulated certificate download failure");
});
}
};
// 应该抛出有意义的异常
X509Certificate certificate = verifier.getValidCertificate();

View File

@@ -0,0 +1,59 @@
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="WxPay-Offline-Tests" verbose="1">
<!-- Credential-dependent tests remain runnable explicitly with -Dtest. -->
<test name="Unit_Tests">
<classes>
<class name="com.github.binarywang.wxpay.bean.applyment.WxPayApplyment4SubCreateRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.entpay.EntPayRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.invoice.GeneralInvoiceRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.marketing.FavorStocksGetResultTest"/>
<class name="com.github.binarywang.wxpay.bean.marketing.transfer.BatchDetailsResultTest"/>
<class name="com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponseTest"/>
<class name="com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResultTest"/>
<class name="com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyUnknownFieldTest"/>
<class name="com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3ResultTest"/>
<class name="com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResultTest"/>
<class name="com.github.binarywang.wxpay.bean.payscore.WxPartnerPayScoreRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.payscore.WxPayScoreRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingQueryResultTest"/>
<class name="com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingV3ResultTest"/>
<class name="com.github.binarywang.wxpay.bean.request.CombineCloseRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.request.WxMaEntrustRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.request.WxPayPartnerRefundV3RequestTest"/>
<class name="com.github.binarywang.wxpay.bean.request.WxPayRefundRequestTest"/>
<class name="com.github.binarywang.wxpay.bean.request.WxPayRefundV3RequestTest"/>
<class name="com.github.binarywang.wxpay.bean.result.BaseWxPayResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPayBillResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPayRefundResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3ResultTest"/>
<class name="com.github.binarywang.wxpay.bean.result.WxSignQueryResultTest"/>
<class name="com.github.binarywang.wxpay.config.WxPayConfigPrivateKeyTest"/>
<class name="com.github.binarywang.wxpay.config.WxPayConfigTest">
<methods>
<!-- These examples require a merchant certificate or external URL. -->
<exclude name="testInitSSLContext.*"/>
</methods>
</class>
<class name="com.github.binarywang.wxpay.service.BusinessOperationTransferServiceTest"/>
<class name="com.github.binarywang.wxpay.service.LegacyEcommerceApiCompatibilityTest"/>
<class name="com.github.binarywang.wxpay.service.impl.BaseWxPayServiceGlobalImplTest"/>
<class name="com.github.binarywang.wxpay.service.impl.ConnectionPoolUsageExampleTest"/>
<class name="com.github.binarywang.wxpay.service.impl.MultiAppIdSwitchoverTest"/>
<class name="com.github.binarywang.wxpay.service.impl.PartnerInvoiceServiceImplTest"/>
<class name="com.github.binarywang.wxpay.service.impl.TransferAuthorizationApiCompatibilityTest"/>
<class name="com.github.binarywang.wxpay.service.impl.TransferReceiptApiCompatibilityTest"/>
<class name="com.github.binarywang.wxpay.service.impl.TransferUserAuthorizationApiCompatibilityTest"/>
<class name="com.github.binarywang.wxpay.service.impl.WxPayServiceApacheHttpImplConnectionPoolTest"/>
<class name="com.github.binarywang.wxpay.service.impl.WxPayServiceSandboxTest"/>
<class name="com.github.binarywang.wxpay.util.SignUtilsTest"/>
<class name="com.github.binarywang.wxpay.v3.SignatureExecTrustedHostTest"/>
<class name="com.github.binarywang.wxpay.v3.auth.AutoUpdateCertificatesVerifierPublicKeyModeTest"/>
<class name="com.github.binarywang.wxpay.v3.util.RsaCryptoUtilTest"/>
</classes>
</test>
</suite>