diff --git a/.gitignore b/.gitignore
index 6b8802547..34150b7b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,3 +55,6 @@ sonar-project.properties
.factorypath
*.zip
.worktrees
+
+# Local Superpowers working documents; do not commit.
+/docs/superpowers/
diff --git a/weixin-java-channel/pom.xml b/weixin-java-channel/pom.xml
index 86d398b17..10417674f 100644
--- a/weixin-java-channel/pom.xml
+++ b/weixin-java-channel/pom.xml
@@ -84,6 +84,11 @@
testng
test
+
+ org.mockito
+ mockito-core
+ test
+
ch.qos.logback
logback-classic
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
index b8d1156b6..89d3c169b 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
@@ -199,4 +199,76 @@ WxChannelBaseResponse addComplaintEvidence(String complaintId, String content, L
* @throws WxErrorException 异常
*/
WxChannelBaseResponse merchantUpdateAfterSale(AfterSaleMerchantUpdateParam param) throws WxErrorException;
+
+ /**
+ * 获取保障单列表。
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/channels-shop-aftersale/guarantee/api_searchguaranteeorder
+ *
+ * @param param 查询参数
+ * @return 保障单列表
+ * @throws WxErrorException 异常
+ */
+ default GuaranteeOrderListResponse listGuaranteeOrder(GuaranteeOrderListParam param) throws WxErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 获取保障单详情。
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/channels-shop-aftersale/guarantee/api_getguaranteeorder
+ *
+ * @param guaranteeOrderId 保障单号
+ * @return 保障单详情
+ * @throws WxErrorException 异常
+ */
+ default GuaranteeOrderInfoResponse getGuaranteeOrder(String guaranteeOrderId) throws WxErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 同意保障单申请。
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/channels-shop-aftersale/guarantee/api_merchantacceptguarantee
+ *
+ * @param guaranteeOrderId 保障单号
+ * @return 响应结果
+ * @throws WxErrorException 异常
+ */
+ default WxChannelBaseResponse acceptGuarantee(String guaranteeOrderId) throws WxErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 商家协商保障单。
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/channels-shop-aftersale/guarantee/api_merchantmodifyguarantee
+ *
+ * @param request 协商参数
+ * @return 响应结果
+ * @throws WxErrorException 异常
+ */
+ default WxChannelBaseResponse modifyGuarantee(GuaranteeModifyRequest request) throws WxErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 商家举证保障单。
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/channels-shop-aftersale/guarantee/api_merchantproofguarantee
+ *
+ * @param request 举证参数
+ * @return 响应结果
+ * @throws WxErrorException 异常
+ */
+ default WxChannelBaseResponse proofGuarantee(GuaranteeProofRequest request) throws WxErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 拒绝保障单申请。
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/channels-shop-aftersale/guarantee/api_merchantrefuseguarantee
+ *
+ * @param request 拒绝参数
+ * @return 响应结果
+ * @throws WxErrorException 异常
+ */
+ default WxChannelBaseResponse refuseGuarantee(GuaranteeRefuseRequest request) throws WxErrorException {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
index c7cdf9167..5f8c73874 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
@@ -136,4 +136,42 @@ public WxChannelBaseResponse merchantUpdateAfterSale(AfterSaleMerchantUpdatePara
return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
}
+ @Override
+ public GuaranteeOrderListResponse listGuaranteeOrder(GuaranteeOrderListParam param) throws WxErrorException {
+ String resJson = shopService.post(GUARANTEE_ORDER_LIST_URL, param);
+ return ResponseUtils.decode(resJson, GuaranteeOrderListResponse.class);
+ }
+
+ @Override
+ public GuaranteeOrderInfoResponse getGuaranteeOrder(String guaranteeOrderId) throws WxErrorException {
+ GuaranteeOrderIdParam param = new GuaranteeOrderIdParam(guaranteeOrderId);
+ String resJson = shopService.post(GUARANTEE_ORDER_GET_URL, param);
+ return ResponseUtils.decode(resJson, GuaranteeOrderInfoResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse acceptGuarantee(String guaranteeOrderId) throws WxErrorException {
+ GuaranteeOrderIdParam param = new GuaranteeOrderIdParam(guaranteeOrderId);
+ String resJson = shopService.post(GUARANTEE_ORDER_ACCEPT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse modifyGuarantee(GuaranteeModifyRequest request) throws WxErrorException {
+ String resJson = shopService.post(GUARANTEE_ORDER_MODIFY_URL, request);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse proofGuarantee(GuaranteeProofRequest request) throws WxErrorException {
+ String resJson = shopService.post(GUARANTEE_ORDER_PROOF_URL, request);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse refuseGuarantee(GuaranteeRefuseRequest request) throws WxErrorException {
+ String resJson = shopService.post(GUARANTEE_ORDER_REFUSE_URL, request);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeModifyRequest.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeModifyRequest.java
new file mode 100644
index 000000000..0141ac05d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeModifyRequest.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商家协商保障单请求参数。
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class GuaranteeModifyRequest extends GuaranteeOrderIdParam {
+
+ private static final long serialVersionUID = 4268864541609439068L;
+
+ /** 商品破损程度。 */
+ @JsonProperty("bad_level")
+ private Integer badLevel;
+
+ /** 商家协商备注。 */
+ @JsonProperty("merchant_remark")
+ private String merchantRemark;
+
+ public GuaranteeModifyRequest(String guaranteeOrderId, Integer badLevel, String merchantRemark) {
+ super(guaranteeOrderId);
+ this.badLevel = badLevel;
+ this.merchantRemark = merchantRemark;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderIdParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderIdParam.java
new file mode 100644
index 000000000..930e82422
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderIdParam.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 保障单号参数。
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class GuaranteeOrderIdParam implements Serializable {
+
+ private static final long serialVersionUID = -6638498743123537413L;
+
+ /** 保障单号。 */
+ @JsonProperty("guarantee_order_id")
+ private String guaranteeOrderId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderInfoResponse.java
new file mode 100644
index 000000000..7b286807a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderInfoResponse.java
@@ -0,0 +1,59 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 保障单详情响应。
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class GuaranteeOrderInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7354122991247317485L;
+
+ /** 保障单详情。 */
+ @JsonProperty("guarantee_order")
+ private GuaranteeOrder guaranteeOrder;
+
+ /**
+ * 保障单详情。
+ */
+ @Data
+ @NoArgsConstructor
+ public static class GuaranteeOrder implements Serializable {
+
+ private static final long serialVersionUID = -2398976447575813507L;
+
+ /** 保障单号。 */
+ @JsonProperty("guarantee_order_id")
+ private String guaranteeOrderId;
+
+ /** 保障单状态。 */
+ @JsonProperty("status")
+ private String status;
+
+ /** 商品信息。 */
+ @JsonProperty("product_info")
+ private ProductInfo productInfo;
+ }
+
+ /**
+ * 详情商品信息。
+ */
+ @Data
+ @NoArgsConstructor
+ public static class ProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -2455740986246085934L;
+
+ /** 商品 SPU ID。 */
+ @JsonProperty("product_id")
+ private String productId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderListParam.java
new file mode 100644
index 000000000..fbe11f91e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderListParam.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 保障单列表请求参数。
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class GuaranteeOrderListParam implements Serializable {
+
+ private static final long serialVersionUID = 1622570776364341988L;
+
+ @JsonProperty("guarantee_order_id_list")
+ private List guaranteeOrderIdList;
+
+ @JsonProperty("order_id_list")
+ private List orderIdList;
+
+ @JsonProperty("type")
+ private Integer type;
+
+ @JsonProperty("begin_time")
+ private Long beginTime;
+
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ @JsonProperty("status_list")
+ private String statusList;
+
+ @JsonProperty("offset")
+ private Integer offset;
+
+ @JsonProperty("limit")
+ private Integer limit;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderListResponse.java
new file mode 100644
index 000000000..90daa0cc1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeOrderListResponse.java
@@ -0,0 +1,64 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 保障单列表响应。
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class GuaranteeOrderListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 9105476087203713187L;
+
+ /** 保障单总数。 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+
+ /** 保障单列表。 */
+ @JsonProperty("guarantee_order_list")
+ private List guaranteeOrderList;
+
+ /**
+ * 保障单列表项。
+ */
+ @Data
+ @NoArgsConstructor
+ public static class GuaranteeOrder implements Serializable {
+
+ private static final long serialVersionUID = 7151952524213202281L;
+
+ /** 保障单号。 */
+ @JsonProperty("guarantee_order_id")
+ private String guaranteeOrderId;
+
+ /** 保障单状态。 */
+ @JsonProperty("status")
+ private String status;
+
+ /** 商品信息列表。 */
+ @JsonProperty("product_info")
+ private List productInfo;
+ }
+
+ /**
+ * 列表商品信息。
+ */
+ @Data
+ @NoArgsConstructor
+ public static class ProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -2565763879505631638L;
+
+ /** 商品 SPU ID。 */
+ @JsonProperty("product_id")
+ private String productId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeProofRequest.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeProofRequest.java
new file mode 100644
index 000000000..7bd1a95f3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeProofRequest.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商家举证保障单请求参数。
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class GuaranteeProofRequest extends GuaranteeOrderIdParam {
+
+ private static final long serialVersionUID = 6599721896742974275L;
+
+ /** 举证内容。 */
+ @JsonProperty("content")
+ private String content;
+
+ /** 举证图片 media_id 列表。 */
+ @JsonProperty("pic_list")
+ private List picList;
+
+ public GuaranteeProofRequest(String guaranteeOrderId, String content, List picList) {
+ super(guaranteeOrderId);
+ this.content = content;
+ this.picList = picList;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeRefuseRequest.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeRefuseRequest.java
new file mode 100644
index 000000000..be967ebff
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/GuaranteeRefuseRequest.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商家拒绝保障单请求参数。
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(Include.NON_NULL)
+public class GuaranteeRefuseRequest extends GuaranteeOrderIdParam {
+
+ private static final long serialVersionUID = -6905594717805091393L;
+
+ /** 拒绝原因。 */
+ @JsonProperty("reason")
+ private String reason;
+
+ /** 拒绝凭证图片 media_id 列表。 */
+ @JsonProperty("pic_list")
+ private List picList;
+
+ public GuaranteeRefuseRequest(String guaranteeOrderId, String reason, List picList) {
+ super(guaranteeOrderId);
+ this.reason = reason;
+ this.picList = picList;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java
index 0b62bf59d..8aa4fec11 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java
@@ -302,6 +302,18 @@ public interface AfterSale {
String AFTER_SALE_REJECT_EXCHANGE_RESHIP_URL = "https://api.weixin.qq.com/channels/ec/aftersale/rejectexchangereship";
/** 商家协商*/
String AFTER_SALE_MERCHANT_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantupdateaftersale";
+ /** 获取保障单列表 */
+ String GUARANTEE_ORDER_LIST_URL = "https://api.weixin.qq.com/channels/ec/aftersale/searchguaranteeorder";
+ /** 获取保障单详情 */
+ String GUARANTEE_ORDER_GET_URL = "https://api.weixin.qq.com/channels/ec/aftersale/getguaranteeorder";
+ /** 同意保障单申请 */
+ String GUARANTEE_ORDER_ACCEPT_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantacceptguarantee";
+ /** 商家协商保障单 */
+ String GUARANTEE_ORDER_MODIFY_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantmodifyguarantee";
+ /** 商家举证保障单 */
+ String GUARANTEE_ORDER_PROOF_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantproofguarantee";
+ /** 拒绝保障单申请 */
+ String GUARANTEE_ORDER_REFUSE_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantrefuseguarantee";
}
/** 纠纷相关接口 */
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplGuaranteeTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplGuaranteeTest.java
new file mode 100644
index 000000000..e8eaee0fc
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplGuaranteeTest.java
@@ -0,0 +1,163 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Answers.CALLS_REAL_METHODS;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.GUARANTEE_ORDER_ACCEPT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.GUARANTEE_ORDER_GET_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.GUARANTEE_ORDER_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.GUARANTEE_ORDER_MODIFY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.GUARANTEE_ORDER_PROOF_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.GUARANTEE_ORDER_REFUSE_URL;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.Arrays;
+import me.chanjar.weixin.channel.api.WxChannelAfterSaleService;
+import me.chanjar.weixin.channel.bean.after.GuaranteeModifyRequest;
+import me.chanjar.weixin.channel.bean.after.GuaranteeOrderIdParam;
+import me.chanjar.weixin.channel.bean.after.GuaranteeOrderInfoResponse;
+import me.chanjar.weixin.channel.bean.after.GuaranteeOrderListParam;
+import me.chanjar.weixin.channel.bean.after.GuaranteeOrderListResponse;
+import me.chanjar.weixin.channel.bean.after.GuaranteeProofRequest;
+import me.chanjar.weixin.channel.bean.after.GuaranteeRefuseRequest;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import org.testng.annotations.Test;
+
+
+/**
+ * 保障单模型 JSON 映射测试。
+ */
+public class WxChannelAfterSaleServiceImplGuaranteeTest {
+
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+ @Test
+ public void shouldSerializeGuaranteeOperationRequestsWithOfficialFieldNames() throws Exception {
+ JsonNode modify = OBJECT_MAPPER.readTree(OBJECT_MAPPER.writeValueAsString(
+ new GuaranteeModifyRequest("2000001077270153", 50, "协商说明")));
+ assertEquals(modify.get("guarantee_order_id").asText(), "2000001077270153");
+ assertEquals(modify.get("bad_level").asInt(), 50);
+ assertEquals(modify.get("merchant_remark").asText(), "协商说明");
+
+ JsonNode proof = OBJECT_MAPPER.readTree(OBJECT_MAPPER.writeValueAsString(
+ new GuaranteeProofRequest("2000001077270153", "举证说明", Arrays.asList("media-1"))));
+ assertEquals(proof.get("content").asText(), "举证说明");
+ assertEquals(proof.get("pic_list").get(0).asText(), "media-1");
+
+ JsonNode refuse = OBJECT_MAPPER.readTree(OBJECT_MAPPER.writeValueAsString(
+ new GuaranteeRefuseRequest("2000001077270153", "拒绝原因", Arrays.asList("media-2"))));
+ assertEquals(refuse.get("reason").asText(), "拒绝原因");
+ assertEquals(refuse.get("pic_list").get(0).asText(), "media-2");
+ }
+
+ @Test
+ public void shouldDeserializeGuaranteeOrderListAndDetail() throws Exception {
+ String listJson = "{\"errcode\":0,\"total_num\":1,\"guarantee_order_list\":[{"
+ + "\"guarantee_order_id\":\"2000001077270153\",\"status\":\"PENDING\","
+ + "\"product_info\":[{\"product_id\":\"123\"}]}]}";
+ GuaranteeOrderListResponse listResponse = OBJECT_MAPPER.readValue(
+ listJson, GuaranteeOrderListResponse.class);
+ assertEquals(listResponse.getTotalNum(), Integer.valueOf(1));
+ assertEquals(listResponse.getGuaranteeOrderList().get(0).getGuaranteeOrderId(), "2000001077270153");
+ assertEquals(listResponse.getGuaranteeOrderList().get(0).getStatus(), "PENDING");
+ assertEquals(listResponse.getGuaranteeOrderList().get(0).getProductInfo().get(0).getProductId(), "123");
+
+ String detailJson = "{\"errcode\":0,\"guarantee_order\":{"
+ + "\"guarantee_order_id\":\"2000001077270153\",\"status\":\"PENDING\","
+ + "\"product_info\":{\"product_id\":\"123\"}}}";
+ GuaranteeOrderInfoResponse detailResponse = OBJECT_MAPPER.readValue(
+ detailJson, GuaranteeOrderInfoResponse.class);
+ assertEquals(detailResponse.getGuaranteeOrder().getGuaranteeOrderId(), "2000001077270153");
+ assertEquals(detailResponse.getGuaranteeOrder().getStatus(), "PENDING");
+ assertEquals(detailResponse.getGuaranteeOrder().getProductInfo().getProductId(), "123");
+ }
+
+ @Test
+ public void shouldSerializeGuaranteeOrderListParamWithOfficialFieldNames() throws Exception {
+ GuaranteeOrderListParam param = OBJECT_MAPPER.readValue(
+ "{\"guarantee_order_id_list\":[\"g-1\"],\"order_id_list\":[\"o-1\"],\"type\":2,"
+ + "\"begin_time\":1,\"end_time\":2,\"status_list\":\"PENDING\",\"offset\":3,\"limit\":10}", GuaranteeOrderListParam.class);
+
+ JsonNode json = OBJECT_MAPPER.readTree(OBJECT_MAPPER.writeValueAsString(param));
+ assertEquals(json.get("guarantee_order_id_list").get(0).asText(), "g-1");
+ assertEquals(json.get("order_id_list").get(0).asText(), "o-1");
+ assertEquals(json.get("type").asInt(), 2);
+ assertEquals(json.get("begin_time").asLong(), 1L);
+ assertEquals(json.get("end_time").asLong(), 2L);
+ assertEquals(json.get("status_list").asText(), "PENDING");
+ assertEquals(json.get("offset").asInt(), 3);
+ assertEquals(json.get("limit").asInt(), 10);
+ }
+
+ @Test
+ public void shouldExposeGuaranteeMethodsAsDefaultMethods() throws Exception {
+ assertTrue(WxChannelAfterSaleService.class.getMethod("listGuaranteeOrder", GuaranteeOrderListParam.class)
+ .isDefault());
+ assertTrue(WxChannelAfterSaleService.class.getMethod("getGuaranteeOrder", String.class).isDefault());
+ assertTrue(WxChannelAfterSaleService.class.getMethod("acceptGuarantee", String.class).isDefault());
+ assertTrue(WxChannelAfterSaleService.class.getMethod("modifyGuarantee", GuaranteeModifyRequest.class).isDefault());
+ assertTrue(WxChannelAfterSaleService.class.getMethod("proofGuarantee", GuaranteeProofRequest.class).isDefault());
+ assertTrue(WxChannelAfterSaleService.class.getMethod("refuseGuarantee", GuaranteeRefuseRequest.class).isDefault());
+
+ WxChannelAfterSaleService service = mock(WxChannelAfterSaleService.class, CALLS_REAL_METHODS);
+ try {
+ service.acceptGuarantee("guarantee-1");
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException ignored) {
+ // Expected from the compatibility default method.
+ }
+ }
+
+ @Test
+ public void shouldDelegateGuaranteeOrderEndpointsAndDecodeResponses() throws Exception {
+ BaseWxChannelServiceImpl, ?> shopService = mock(BaseWxChannelServiceImpl.class);
+ WxChannelAfterSaleServiceImpl service = new WxChannelAfterSaleServiceImpl(shopService);
+ GuaranteeOrderListParam listParam = new GuaranteeOrderListParam();
+ listParam.setLimit(10);
+ GuaranteeModifyRequest modifyRequest = new GuaranteeModifyRequest("guarantee-1", 50, "协商说明");
+ GuaranteeProofRequest proofRequest = new GuaranteeProofRequest("guarantee-1", "举证说明",
+ Arrays.asList("media-1"));
+ GuaranteeRefuseRequest refuseRequest = new GuaranteeRefuseRequest("guarantee-1", "拒绝原因",
+ Arrays.asList("media-2"));
+
+ when(shopService.post(eq(GUARANTEE_ORDER_LIST_URL), eq(listParam))).thenReturn(
+ "{\"errcode\":0,\"total_num\":1,\"guarantee_order_list\":[{\"guarantee_order_id\":\"guarantee-1\"}]}" );
+ when(shopService.post(eq(GUARANTEE_ORDER_GET_URL), eq(new GuaranteeOrderIdParam("guarantee-1")))).thenReturn(
+ "{\"errcode\":0,\"guarantee_order\":{\"guarantee_order_id\":\"guarantee-1\"}}" );
+ when(shopService.post(eq(GUARANTEE_ORDER_ACCEPT_URL), eq(new GuaranteeOrderIdParam("guarantee-1"))))
+ .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}");
+ when(shopService.post(eq(GUARANTEE_ORDER_MODIFY_URL), eq(modifyRequest)))
+ .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}");
+ when(shopService.post(eq(GUARANTEE_ORDER_PROOF_URL), eq(proofRequest)))
+ .thenReturn("{\"errcode\":0,\"errmsg\":\"ok\"}");
+ when(shopService.post(eq(GUARANTEE_ORDER_REFUSE_URL), eq(refuseRequest)))
+ .thenReturn("{\"errcode\":40001,\"errmsg\":\"invalid credential\"}");
+
+ GuaranteeOrderListResponse listResponse = service.listGuaranteeOrder(listParam);
+ GuaranteeOrderInfoResponse detailResponse = service.getGuaranteeOrder("guarantee-1");
+ WxChannelBaseResponse acceptResponse = service.acceptGuarantee("guarantee-1");
+ WxChannelBaseResponse modifyResponse = service.modifyGuarantee(modifyRequest);
+ WxChannelBaseResponse proofResponse = service.proofGuarantee(proofRequest);
+ WxChannelBaseResponse refuseResponse = service.refuseGuarantee(refuseRequest);
+
+ assertEquals(listResponse.getGuaranteeOrderList().get(0).getGuaranteeOrderId(), "guarantee-1");
+ assertEquals(detailResponse.getGuaranteeOrder().getGuaranteeOrderId(), "guarantee-1");
+ assertTrue(acceptResponse.isSuccess());
+ assertTrue(modifyResponse.isSuccess());
+ assertTrue(proofResponse.isSuccess());
+ assertFalse(refuseResponse.isSuccess());
+ verify(shopService).post(GUARANTEE_ORDER_LIST_URL, listParam);
+ verify(shopService).post(GUARANTEE_ORDER_GET_URL, new GuaranteeOrderIdParam("guarantee-1"));
+ verify(shopService).post(GUARANTEE_ORDER_ACCEPT_URL, new GuaranteeOrderIdParam("guarantee-1"));
+ verify(shopService).post(GUARANTEE_ORDER_MODIFY_URL, modifyRequest);
+ verify(shopService).post(GUARANTEE_ORDER_PROOF_URL, proofRequest);
+ verify(shopService).post(GUARANTEE_ORDER_REFUSE_URL, refuseRequest);
+ }
+}