Commit 97fc4027de96dcf05c6c9fc4d5509c55a2b6c2da
Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
# Conflicts: # yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImplTest.java
Showing
2 changed files
with
136 additions
and
7 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
| @@ -148,7 +148,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa | @@ -148,7 +148,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa | ||
| 148 | // 2.1 执行请求 | 148 | // 2.1 执行请求 |
| 149 | AlipayTradeRefundResponse response = client.execute(request); | 149 | AlipayTradeRefundResponse response = client.execute(request); |
| 150 | if (!response.isSuccess()) { | 150 | if (!response.isSuccess()) { |
| 151 | - return PayRefundRespDTO.failureOf(reqDTO.getOutRefundNo(), response); | 151 | + return PayRefundRespDTO.failureOf(response.getSubCode(), response.getSubMsg(), reqDTO.getOutRefundNo(), response); |
| 152 | } | 152 | } |
| 153 | // 2.2 创建返回结果 | 153 | // 2.2 创建返回结果 |
| 154 | // 支付宝只要退款调用返回 success,就认为退款成功,不需要回调。具体可见 parseNotify 方法的说明。 | 154 | // 支付宝只要退款调用返回 success,就认为退款成功,不需要回调。具体可见 parseNotify 方法的说明。 |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java
| 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; | 1 | package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.date.LocalDateTimeUtil; | ||
| 3 | import cn.hutool.core.util.RandomUtil; | 4 | import cn.hutool.core.util.RandomUtil; |
| 4 | import cn.hutool.core.util.ReflectUtil; | 5 | import cn.hutool.core.util.ReflectUtil; |
| 5 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 6 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| @@ -7,19 +8,27 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant | @@ -7,19 +8,27 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant | ||
| 7 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | 8 | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| 8 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; | 9 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; |
| 9 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | 10 | import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; |
| 11 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; | ||
| 12 | +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; | ||
| 10 | import cn.iocoder.yudao.framework.pay.core.client.exception.PayException; | 13 | import cn.iocoder.yudao.framework.pay.core.client.exception.PayException; |
| 11 | import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; | 14 | import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; |
| 15 | +import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; | ||
| 12 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | 16 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; |
| 13 | import com.alipay.api.AlipayApiException; | 17 | import com.alipay.api.AlipayApiException; |
| 14 | import com.alipay.api.DefaultAlipayClient; | 18 | import com.alipay.api.DefaultAlipayClient; |
| 19 | +import com.alipay.api.domain.AlipayTradeRefundModel; | ||
| 15 | import com.alipay.api.request.AlipayTradePrecreateRequest; | 20 | import com.alipay.api.request.AlipayTradePrecreateRequest; |
| 21 | +import com.alipay.api.request.AlipayTradeRefundRequest; | ||
| 16 | import com.alipay.api.response.AlipayTradePrecreateResponse; | 22 | import com.alipay.api.response.AlipayTradePrecreateResponse; |
| 23 | +import com.alipay.api.response.AlipayTradeRefundResponse; | ||
| 24 | +import org.junit.jupiter.api.DisplayName; | ||
| 17 | import org.junit.jupiter.api.Test; | 25 | import org.junit.jupiter.api.Test; |
| 18 | import org.mockito.ArgumentMatcher; | 26 | import org.mockito.ArgumentMatcher; |
| 19 | import org.mockito.InjectMocks; | 27 | import org.mockito.InjectMocks; |
| 20 | import org.mockito.Mock; | 28 | import org.mockito.Mock; |
| 21 | 29 | ||
| 22 | import javax.validation.ConstraintViolationException; | 30 | import javax.validation.ConstraintViolationException; |
| 31 | +import java.util.Date; | ||
| 23 | 32 | ||
| 24 | import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY; | 33 | import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_PUBLIC_KEY; |
| 25 | import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED; | 34 | import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED; |
| @@ -51,13 +60,14 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | @@ -51,13 +60,14 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | ||
| 51 | private DefaultAlipayClient defaultAlipayClient; | 60 | private DefaultAlipayClient defaultAlipayClient; |
| 52 | 61 | ||
| 53 | @Test | 62 | @Test |
| 54 | - public void testDoInit() { | 63 | + public void test_do_init() { |
| 55 | client.doInit(); | 64 | client.doInit(); |
| 56 | assertNotSame(defaultAlipayClient, ReflectUtil.getFieldValue(client, "defaultAlipayClient")); | 65 | assertNotSame(defaultAlipayClient, ReflectUtil.getFieldValue(client, "defaultAlipayClient")); |
| 57 | } | 66 | } |
| 58 | 67 | ||
| 59 | @Test | 68 | @Test |
| 60 | - public void testUnifiedOrderSuccess() throws AlipayApiException { | 69 | + @DisplayName("支付包扫描支付下单成功") |
| 70 | + public void test_unified_order_success() throws AlipayApiException { | ||
| 61 | // 准备返回对象 | 71 | // 准备返回对象 |
| 62 | String notifyUrl = randomURL(); | 72 | String notifyUrl = randomURL(); |
| 63 | String qrCode = randomString(); | 73 | String qrCode = randomString(); |
| @@ -84,7 +94,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | @@ -84,7 +94,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | ||
| 84 | } | 94 | } |
| 85 | 95 | ||
| 86 | @Test | 96 | @Test |
| 87 | - public void testUnifiedOrderChannelFailed() throws AlipayApiException { | 97 | + @DisplayName("支付包扫描支付,渠道返回失败") |
| 98 | + public void test_unified_order_channel_failed() throws AlipayApiException { | ||
| 88 | String notifyUrl = randomURL(); | 99 | String notifyUrl = randomURL(); |
| 89 | String subCode = randomString(); | 100 | String subCode = randomString(); |
| 90 | String subMsg = randomString(); | 101 | String subMsg = randomString(); |
| @@ -110,7 +121,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | @@ -110,7 +121,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | ||
| 110 | } | 121 | } |
| 111 | 122 | ||
| 112 | @Test | 123 | @Test |
| 113 | - public void test_unifiedOrder_throw_pay_exception() throws AlipayApiException { | 124 | + @DisplayName("支付包扫描支付,抛出系统异常") |
| 125 | + public void test_unified_order_throw_pay_exception() throws AlipayApiException { | ||
| 114 | // 准备请求参数 | 126 | // 准备请求参数 |
| 115 | String outTradeNo = randomString(); | 127 | String outTradeNo = randomString(); |
| 116 | String notifyUrl = randomURL(); | 128 | String notifyUrl = randomURL(); |
| @@ -126,7 +138,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | @@ -126,7 +138,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | ||
| 126 | } | 138 | } |
| 127 | 139 | ||
| 128 | @Test | 140 | @Test |
| 129 | - public void test_unifiedOrder_throw_service_exception() throws AlipayApiException { | 141 | + @DisplayName("支付包扫描支付,抛出业务异常") |
| 142 | + public void test_unified_order_throw_service_exception() throws AlipayApiException { | ||
| 130 | // 准备请求参数 | 143 | // 准备请求参数 |
| 131 | String outTradeNo = randomString(); | 144 | String outTradeNo = randomString(); |
| 132 | String notifyUrl = randomURL(); | 145 | String notifyUrl = randomURL(); |
| @@ -142,7 +155,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | @@ -142,7 +155,8 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | ||
| 142 | } | 155 | } |
| 143 | 156 | ||
| 144 | @Test | 157 | @Test |
| 145 | - public void test_unifiedOrder_param_validate() { | 158 | + @DisplayName("支付包扫描支付,参数校验不通过") |
| 159 | + public void test_unified_order_param_validate() { | ||
| 146 | // 准备请求参数 | 160 | // 准备请求参数 |
| 147 | String outTradeNo = randomString(); | 161 | String outTradeNo = randomString(); |
| 148 | String notifyUrl = randomURL(); | 162 | String notifyUrl = randomURL(); |
| @@ -162,4 +176,119 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | @@ -162,4 +176,119 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { | ||
| 162 | o.setBody(RandomUtil.randomString(32)); | 176 | o.setBody(RandomUtil.randomString(32)); |
| 163 | }); | 177 | }); |
| 164 | } | 178 | } |
| 179 | + | ||
| 180 | + @Test | ||
| 181 | + @DisplayName("支付包扫描退款成功") | ||
| 182 | + public void test_unified_refund_success() throws AlipayApiException { | ||
| 183 | + // 准备返回对象 | ||
| 184 | + String notifyUrl = randomURL(); | ||
| 185 | + Date refundTime = randomDate(); | ||
| 186 | + String outRefundNo = randomString(); | ||
| 187 | + String outTradeNo = randomString(); | ||
| 188 | + Integer refundAmount = randomInteger(); | ||
| 189 | + AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> { | ||
| 190 | + o.setSubCode(""); | ||
| 191 | + o.setGmtRefundPay(refundTime); | ||
| 192 | + }); | ||
| 193 | + // mock | ||
| 194 | + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> { | ||
| 195 | + assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel()); | ||
| 196 | + AlipayTradeRefundModel bizModel = (AlipayTradeRefundModel) request.getBizModel(); | ||
| 197 | + assertEquals(outRefundNo, bizModel.getOutRequestNo()); | ||
| 198 | + assertEquals(outTradeNo, bizModel.getOutTradeNo()); | ||
| 199 | + assertEquals(String.valueOf(refundAmount / 100.0), bizModel.getRefundAmount()); | ||
| 200 | + return true; | ||
| 201 | + }))).thenReturn(response); | ||
| 202 | + // 准备请求参数 | ||
| 203 | + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> { | ||
| 204 | + o.setOutRefundNo(outRefundNo); | ||
| 205 | + o.setOutTradeNo(outTradeNo); | ||
| 206 | + o.setNotifyUrl(notifyUrl); | ||
| 207 | + o.setRefundPrice(refundAmount); | ||
| 208 | + }); | ||
| 209 | + PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO); | ||
| 210 | + // 断言 | ||
| 211 | + assertEquals(PayRefundStatusRespEnum.SUCCESS.getStatus(), resp.getStatus()); | ||
| 212 | + assertNull(resp.getChannelRefundNo()); | ||
| 213 | + assertEquals(LocalDateTimeUtil.of(refundTime), resp.getSuccessTime()); | ||
| 214 | + assertEquals(outRefundNo, resp.getOutRefundNo()); | ||
| 215 | + assertSame(response, resp.getRawData()); | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + @Test | ||
| 219 | + @DisplayName("支付包扫描退款,渠道返回失败") | ||
| 220 | + public void test_unified_refund_channel_failed() throws AlipayApiException { | ||
| 221 | + // 准备返回对象 | ||
| 222 | + String notifyUrl = randomURL(); | ||
| 223 | + String subCode = randomString(); | ||
| 224 | + String subMsg = randomString(); | ||
| 225 | + AlipayTradeRefundResponse response = randomPojo(AlipayTradeRefundResponse.class, o -> { | ||
| 226 | + o.setSubCode(subCode); | ||
| 227 | + o.setSubMsg(subMsg); | ||
| 228 | + }); | ||
| 229 | + // mock | ||
| 230 | + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> { | ||
| 231 | + assertInstanceOf(AlipayTradeRefundModel.class, request.getBizModel()); | ||
| 232 | + return true; | ||
| 233 | + }))).thenReturn(response); | ||
| 234 | + // 准备请求参数 | ||
| 235 | + String outRefundNo = randomString(); | ||
| 236 | + String outTradeNo = randomString(); | ||
| 237 | + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> { | ||
| 238 | + o.setOutRefundNo(outRefundNo); | ||
| 239 | + o.setOutTradeNo(outTradeNo); | ||
| 240 | + o.setNotifyUrl(notifyUrl); | ||
| 241 | + }); | ||
| 242 | + PayRefundRespDTO resp = client.unifiedRefund(refundReqDTO); | ||
| 243 | + // 断言 | ||
| 244 | + assertEquals(PayRefundStatusRespEnum.FAILURE.getStatus(), resp.getStatus()); | ||
| 245 | + assertNull(resp.getChannelRefundNo()); | ||
| 246 | + assertEquals(subCode, resp.getChannelErrorCode()); | ||
| 247 | + assertEquals(subMsg, resp.getChannelErrorMsg()); | ||
| 248 | + assertNull(resp.getSuccessTime()); | ||
| 249 | + assertEquals(outRefundNo, resp.getOutRefundNo()); | ||
| 250 | + assertSame(response, resp.getRawData()); | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + @Test | ||
| 254 | + @DisplayName("支付包扫描退款,参数校验不通过") | ||
| 255 | + public void test_unified_refund_param_validate() { | ||
| 256 | + // 准备请求参数 | ||
| 257 | + String notifyUrl = randomURL(); | ||
| 258 | + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> { | ||
| 259 | + o.setOutTradeNo(""); | ||
| 260 | + o.setNotifyUrl(notifyUrl); | ||
| 261 | + }); | ||
| 262 | + // 断言 | ||
| 263 | + assertThrows(ConstraintViolationException.class, () -> client.unifiedRefund(refundReqDTO)); | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + @Test | ||
| 267 | + @DisplayName("支付包扫描退款,抛出业务异常") | ||
| 268 | + public void test_unified_refund_throw_service_exception() throws AlipayApiException { | ||
| 269 | + // mock | ||
| 270 | + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true))) | ||
| 271 | + .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); | ||
| 272 | + // 准备请求参数 | ||
| 273 | + String notifyUrl = randomURL(); | ||
| 274 | + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> { | ||
| 275 | + o.setNotifyUrl(notifyUrl); | ||
| 276 | + }); | ||
| 277 | + // 断言 | ||
| 278 | + assertThrows(ServiceException.class, () -> client.unifiedRefund(refundReqDTO)); | ||
| 279 | + } | ||
| 280 | + @Test | ||
| 281 | + @DisplayName("支付包扫描退款,抛出系统异常") | ||
| 282 | + public void test_unified_refund_throw_pay_exception() throws AlipayApiException { | ||
| 283 | + // mock | ||
| 284 | + when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeRefundRequest>) request -> true))) | ||
| 285 | + .thenThrow(new RuntimeException("系统异常")); | ||
| 286 | + // 准备请求参数 | ||
| 287 | + String notifyUrl = randomURL(); | ||
| 288 | + PayRefundUnifiedReqDTO refundReqDTO = randomPojo(PayRefundUnifiedReqDTO.class, o -> { | ||
| 289 | + o.setNotifyUrl(notifyUrl); | ||
| 290 | + }); | ||
| 291 | + // 断言 | ||
| 292 | + assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO)); | ||
| 293 | + } | ||
| 165 | } | 294 | } |