33import static org .testng .Assert .assertEquals ;
44import static org .testng .Assert .assertFalse ;
55
6+ import org .testng .annotations .DataProvider ;
67import org .testng .annotations .Test ;
78
89/**
9- * 验证同城配送 API 签名 payload 格式的单元测试。
10+ * 验证小程序 API 签名 payload 格式的单元测试。
1011 *
1112 * <p>直接测试 {@link BaseWxMaServiceImpl#buildSignaturePayload} 生产方法,
1213 * 确保待签名串格式符合微信官方规范:<br>
1314 * {@code urlpath\nappid\ntimestamp\npostdata}<br>
1415 * 共 4 个字段,字段间以换行符 {@code \n} 分隔,末尾无额外回车符。
1516 *
17+ * <p>修复说明:4.8.0 版本在计算签名时错误地将 rsaKeySn 添加到签名串(5 个字段),
18+ * 导致微信服务端返回 40234(invalid signature)。此测试验证修复后签名串格式正确(4 个字段,
19+ * 不含 rsaKeySn),适用于所有走加密访问路径的接口(包括 getPhoneNumber、同城配送等)。
20+ *
1621 * @author GitHub Copilot
1722 * @see <a
1823 * href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html">
@@ -22,39 +27,43 @@ public class WxMaSignaturePayloadTest {
2227
2328 private static final String URL_PATH =
2429 "https://api.weixin.qq.com/cgi-bin/express/intracity/createstore" ;
30+ private static final String GET_PHONE_NUMBER_URL_PATH =
31+ "https://api.weixin.qq.com/wxa/business/getuserphonenumber" ;
2532 private static final String APP_ID = "wx1234567890abcdef" ;
2633 private static final long TIMESTAMP = 1700000000L ;
2734 private static final String POST_DATA = "{\" iv\" :\" abc\" ,\" data\" :\" xyz\" ,\" authtag\" :\" tag\" }" ;
2835 private static final String RSA_KEY_SN = "some_serial_number" ;
2936
3037 /**
31- * 验证 buildSignaturePayload 返回的待签名串恰好包含 4 个字段,
32- * 格式为:urlpath\nappid\ntimestamp\npostdata
38+ * 提供不同 API 接口 URL 作为测试数据,用于验证签名串格式在各接口中均符合规范。
3339 */
34- @ Test
35- public void testPayloadHasExactlyFourFields () {
36- String payload =
37- BaseWxMaServiceImpl .buildSignaturePayload (URL_PATH , APP_ID , TIMESTAMP , POST_DATA );
38-
39- String [] parts = payload .split ("\n " , -1 );
40- assertEquals (parts .length , 4 , "待签名串应恰好包含 4 个字段(urlpath、appid、timestamp、postdata)" );
41- assertEquals (parts [0 ], URL_PATH , "第 1 段应为 urlpath" );
42- assertEquals (parts [1 ], APP_ID , "第 2 段应为 appid" );
43- assertEquals (parts [2 ], String .valueOf (TIMESTAMP ), "第 3 段应为 timestamp" );
44- assertEquals (parts [3 ], POST_DATA , "第 4 段应为 postdata" );
40+ @ DataProvider (name = "apiUrlPaths" )
41+ public Object [][] apiUrlPaths () {
42+ return new Object [][] {
43+ {URL_PATH , "同城配送 createstore" },
44+ {GET_PHONE_NUMBER_URL_PATH , "getPhoneNumber" }
45+ };
4546 }
4647
4748 /**
48- * 验证 buildSignaturePayload 返回的待签名串不包含 rsaKeySn。
49- * rsaKeySn 应通过请求头 Wechatmp-Serial 传递,而不应出现在签名 payload 中。
49+ * 验证 buildSignaturePayload 返回的待签名串恰好包含 4 个字段,
50+ * 格式为:urlpath\nappid\ntimestamp\npostdata。
51+ * 使用多个 URL 验证,覆盖同城配送及 getPhoneNumber 等接口(issue 4.8.0 升级后 40234 错误)。
5052 */
51- @ Test
52- public void testPayloadDoesNotContainRsaKeySn ( ) {
53+ @ Test ( dataProvider = "apiUrlPaths" )
54+ public void testPayloadHasExactlyFourFields ( String urlPath , String description ) {
5355 String payload =
54- BaseWxMaServiceImpl .buildSignaturePayload (URL_PATH , APP_ID , TIMESTAMP , POST_DATA );
56+ BaseWxMaServiceImpl .buildSignaturePayload (urlPath , APP_ID , TIMESTAMP , POST_DATA );
5557
58+ String [] parts = payload .split ("\n " , -1 );
59+ assertEquals (parts .length , 4 ,
60+ description + " 签名串应恰好包含 4 个字段(urlpath、appid、timestamp、postdata)" );
61+ assertEquals (parts [0 ], urlPath , description + " 第 1 段应为 urlpath" );
62+ assertEquals (parts [1 ], APP_ID , description + " 第 2 段应为 appid" );
63+ assertEquals (parts [2 ], String .valueOf (TIMESTAMP ), description + " 第 3 段应为 timestamp" );
64+ assertEquals (parts [3 ], POST_DATA , description + " 第 4 段应为 postdata" );
5665 assertFalse (payload .contains (RSA_KEY_SN ),
57- "待签名串不应包含 rsaKeySn,rsaKeySn 应通过请求头 Wechatmp-Serial 传递" );
66+ description + " 签名串不应包含 rsaKeySn,rsaKeySn 应通过请求头 Wechatmp-Serial 传递" );
5867 }
5968
6069 /**
0 commit comments