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); + } +}