From 4b60768784404f27cc26371bb18d488f21f97658 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 03:27:31 +0000 Subject: [PATCH 1/3] Initial plan From 41a694c49e60613327e82f726da7199ff45d4a5e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 6 Jan 2026 03:35:22 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20WxSignQueryResult=20?= =?UTF-8?q?=E4=B8=AD=20contract=5Fexpired=5Ftime=20=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wxpay/bean/result/WxSignQueryResult.java | 2 +- .../bean/result/WxSignQueryResultTest.java | 110 ++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java index 524159719..af19aec60 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java @@ -112,7 +112,7 @@ protected void loadXml(Document d) { contractDisplayAccount = readXmlString(d, "contract_display_account"); contractState = readXmlInteger(d, "contract_state"); contractSignedTime = readXmlString(d, "contract_signed_time"); - contractExpiredTime = readXmlString(d, "contrace_Expired_time"); + contractExpiredTime = readXmlString(d, "contract_expired_time"); contractTerminatedTime = readXmlString(d, "contract_terminated_time"); contractTerminatedMode = readXmlInteger(d, "contract_termination_mode"); contractTerminationRemark = readXmlString(d, "contract_termination_remark"); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java new file mode 100644 index 000000000..2391c0c92 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java @@ -0,0 +1,110 @@ +package com.github.binarywang.wxpay.bean.result; + +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * WxSignQueryResult 单元测试 + * + * @author Binary Wang + */ +public class WxSignQueryResultTest { + + /** + * 测试 XML 解析,特别是 contract_expired_time 字段 + */ + @Test + public void testFromXML() { + /* + * xml样例字符串来自于官方文档 + * https://pay.weixin.qq.com/doc/v2/merchant/4011987640 + */ + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 203\n" + + " 66\n" + + " \n" + + " 123\n" + + " \n" + + " \n" + + " 1\n" + + " 2015-07-01 10:00:00\n" + + " 2015-07-01 10:00:00\n" + + " 2015-07-01 10:00:00\n" + + " 3\n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + ""; + + WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); + + // 验证基本字段 + Assert.assertEquals(result.getReturnCode(), "SUCCESS"); + Assert.assertEquals(result.getResultCode(), "SUCCESS"); + Assert.assertEquals(result.getMchId(), "80000000"); + Assert.assertEquals(result.getAppid(), "wx426b3015555b46be"); + + // 验证签约相关字段 + Assert.assertEquals(result.getContractId(), "203"); + Assert.assertEquals(result.getPlanId(), "66"); + Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs"); + Assert.assertEquals(result.getRequestSerial().longValue(), 123L); + Assert.assertEquals(result.getContractCode(), "1005"); + Assert.assertEquals(result.getContractDisplayAccount(), "test"); + Assert.assertEquals(result.getContractState().intValue(), 1); + + // 重点测试时间字段,特别是 contract_expired_time + Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00"); + Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00"); + Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00"); + + // 验证其他字段 + Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3); + Assert.assertEquals(result.getContractTerminationRemark(), "delete ...."); + } + + /** + * 测试 XML 解析 - 只包含必填字段 + */ + @Test + public void testFromXML_RequiredFieldsOnly() { + String xmlString = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Wx15463511252015071056489715\n" + + " 123\n" + + " 1695\n" + + " \n" + + " \n" + + " 0\n" + + " 2015-07-01 10:00:00\n" + + " 2016-07-01 10:00:00\n" + + " \n" + + " \n" + + ""; + + WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); + + // 验证必填字段 + Assert.assertEquals(result.getReturnCode(), "SUCCESS"); + Assert.assertEquals(result.getResultCode(), "SUCCESS"); + Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715"); + Assert.assertEquals(result.getPlanId(), "123"); + Assert.assertEquals(result.getContractState().intValue(), 0); + + // 验证 contract_expired_time 字段能正确解析 + Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00"); + + // 验证非必填字段为 null + Assert.assertNull(result.getContractTerminatedTime()); + Assert.assertNull(result.getContractTerminatedMode()); + Assert.assertNull(result.getContractTerminationRemark()); + } +} From 0b03dc260a79253555d8f9f9fe6cd9da9bc99d3f Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 6 Jan 2026 12:59:06 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=EF=BC=9A=E5=90=AF=E7=94=A8=20fastMode=20=E4=BB=A5=E8=A6=86?= =?UTF-8?q?=E7=9B=96=20WxSignQueryResult#loadXml=20=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 testFromXML 和 testFromXML_RequiredFieldsOnly 测试方法中显式设置 XmlConfig.fastMode = true - 使用 try-finally 块确保在测试后恢复 fastMode 的默认值 - 这样可以确保测试覆盖到 WxSignQueryResult#loadXml 方法中修复的 contract_expired_time 字段解析逻辑 --- .../bean/result/WxSignQueryResultTest.java | 87 +++++++++++-------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java index 2391c0c92..52df2b6e2 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java @@ -1,5 +1,6 @@ package com.github.binarywang.wxpay.bean.result; +import com.github.binarywang.wxpay.util.XmlConfig; import org.testng.Assert; import org.testng.annotations.Test; @@ -41,31 +42,38 @@ public void testFromXML() { " \n" + ""; - WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); + // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支 + XmlConfig.fastMode = true; + try { + WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); - // 验证基本字段 - Assert.assertEquals(result.getReturnCode(), "SUCCESS"); - Assert.assertEquals(result.getResultCode(), "SUCCESS"); - Assert.assertEquals(result.getMchId(), "80000000"); - Assert.assertEquals(result.getAppid(), "wx426b3015555b46be"); + // 验证基本字段 + Assert.assertEquals(result.getReturnCode(), "SUCCESS"); + Assert.assertEquals(result.getResultCode(), "SUCCESS"); + Assert.assertEquals(result.getMchId(), "80000000"); + Assert.assertEquals(result.getAppid(), "wx426b3015555b46be"); - // 验证签约相关字段 - Assert.assertEquals(result.getContractId(), "203"); - Assert.assertEquals(result.getPlanId(), "66"); - Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs"); - Assert.assertEquals(result.getRequestSerial().longValue(), 123L); - Assert.assertEquals(result.getContractCode(), "1005"); - Assert.assertEquals(result.getContractDisplayAccount(), "test"); - Assert.assertEquals(result.getContractState().intValue(), 1); + // 验证签约相关字段 + Assert.assertEquals(result.getContractId(), "203"); + Assert.assertEquals(result.getPlanId(), "66"); + Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs"); + Assert.assertEquals(result.getRequestSerial().longValue(), 123L); + Assert.assertEquals(result.getContractCode(), "1005"); + Assert.assertEquals(result.getContractDisplayAccount(), "test"); + Assert.assertEquals(result.getContractState().intValue(), 1); - // 重点测试时间字段,特别是 contract_expired_time - Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00"); - Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00"); - Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00"); + // 重点测试时间字段,特别是 contract_expired_time + Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00"); + Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00"); + Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00"); - // 验证其他字段 - Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3); - Assert.assertEquals(result.getContractTerminationRemark(), "delete ...."); + // 验证其他字段 + Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3); + Assert.assertEquals(result.getContractTerminationRemark(), "delete ...."); + } finally { + // 恢复默认值 + XmlConfig.fastMode = false; + } } /** @@ -90,21 +98,28 @@ public void testFromXML_RequiredFieldsOnly() { " \n" + ""; - WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); + // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支 + XmlConfig.fastMode = true; + try { + WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class); - // 验证必填字段 - Assert.assertEquals(result.getReturnCode(), "SUCCESS"); - Assert.assertEquals(result.getResultCode(), "SUCCESS"); - Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715"); - Assert.assertEquals(result.getPlanId(), "123"); - Assert.assertEquals(result.getContractState().intValue(), 0); - - // 验证 contract_expired_time 字段能正确解析 - Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00"); - - // 验证非必填字段为 null - Assert.assertNull(result.getContractTerminatedTime()); - Assert.assertNull(result.getContractTerminatedMode()); - Assert.assertNull(result.getContractTerminationRemark()); + // 验证必填字段 + Assert.assertEquals(result.getReturnCode(), "SUCCESS"); + Assert.assertEquals(result.getResultCode(), "SUCCESS"); + Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715"); + Assert.assertEquals(result.getPlanId(), "123"); + Assert.assertEquals(result.getContractState().intValue(), 0); + + // 验证 contract_expired_time 字段能正确解析 + Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00"); + + // 验证非必填字段为 null + Assert.assertNull(result.getContractTerminatedTime()); + Assert.assertNull(result.getContractTerminatedMode()); + Assert.assertNull(result.getContractTerminationRemark()); + } finally { + // 恢复默认值 + XmlConfig.fastMode = false; + } } }