diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java index 1ca7a13e9..664a3ce52 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.ReflectUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.exception.PayException; @@ -16,6 +18,7 @@ import com.alipay.api.DefaultSigner; import com.alipay.api.domain.AlipayTradeRefundModel; import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.response.AlipayTradeRefundResponse; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatcher; @@ -52,6 +55,12 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest { private AbstractAlipayPayClient client; + /** + * 子类需要实现该方法. 设置 client 的具体实现 + */ + @BeforeEach + public abstract void setUp(); + public void setClient(AbstractAlipayPayClient client) { this.client = client; } @@ -177,4 +186,28 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest { // 断言 assertThrows(PayException.class, () -> client.unifiedRefund(refundReqDTO)); } + + @Test + @DisplayName("支付宝 Client 统一下单, 参数校验不通过") + public void test_unified_order_param_validate() { + // 准备请求参数 + String outTradeNo = randomString(); + String notifyUrl = randomURL(); + PayOrderUnifiedReqDTO reqDTO = randomPojo(PayOrderUnifiedReqDTO.class, o -> { + o.setOutTradeNo(outTradeNo); + o.setNotifyUrl(notifyUrl); + }); + // 断言 + assertThrows(ConstraintViolationException.class, () -> client.unifiedOrder(reqDTO)); + } + + protected PayOrderUnifiedReqDTO buildOrderUnifiedReqDTO(String notifyUrl, String outTradeNo, Integer price) { + return randomPojo(PayOrderUnifiedReqDTO.class, o -> { + o.setOutTradeNo(outTradeNo); + o.setNotifyUrl(notifyUrl); + o.setPrice(price); + o.setSubject(RandomUtil.randomString(32)); + o.setBody(RandomUtil.randomString(32)); + }); + } } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java index 811bf561b..47497ab23 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; -import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; @@ -17,8 +16,6 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatcher; import org.mockito.InjectMocks; -import javax.validation.ConstraintViolationException; - import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED; import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; @@ -42,11 +39,12 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { } @Test - @DisplayName("支付包扫描支付下单成功") + @DisplayName("支付宝扫描支付下单成功") public void test_unified_order_success() throws AlipayApiException { // 准备返回对象 String notifyUrl = randomURL(); String qrCode = randomString(); + Integer price = randomInteger(); AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> { o.setQrCode(qrCode); o.setSubCode(""); @@ -58,7 +56,7 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { }))).thenReturn(response); // 准备请求参数 String outTradeNo = randomString(); - PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); PayOrderRespDTO resp = client.unifiedOrder(reqDTO); // 断言 @@ -70,11 +68,12 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { } @Test - @DisplayName("支付包扫描支付,渠道返回失败") + @DisplayName("支付宝扫描支付,渠道返回失败") public void test_unified_order_channel_failed() throws AlipayApiException { String notifyUrl = randomURL(); String subCode = randomString(); String subMsg = randomString(); + Integer price = randomInteger(); AlipayTradePrecreateResponse response = randomPojo(AlipayTradePrecreateResponse.class, o -> { o.setSubCode(subCode); o.setSubMsg(subMsg); @@ -86,7 +85,7 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { }))).thenReturn(response); // 准备请求参数 String outTradeNo = randomString(); - PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); PayOrderRespDTO resp = client.unifiedOrder(reqDTO); // 断言 @@ -97,59 +96,38 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { } @Test - @DisplayName("支付包扫描支付,抛出系统异常") + @DisplayName("支付宝扫描支付, 抛出系统异常") public void test_unified_order_throw_pay_exception() throws AlipayApiException { // 准备请求参数 String outTradeNo = randomString(); String notifyUrl = randomURL(); + Integer price = randomInteger(); // mock when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> { assertEquals(notifyUrl, request.getNotifyUrl()); return true; }))).thenThrow(new RuntimeException("系统异常")); // 准备请求参数 - PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo,price); // 断言 assertThrows(PayException.class, () -> client.unifiedOrder(reqDTO)); } @Test - @DisplayName("支付包扫描支付,抛出业务异常") + @DisplayName("支付宝 Client 统一下单,抛出业务异常") public void test_unified_order_throw_service_exception() throws AlipayApiException { // 准备请求参数 String outTradeNo = randomString(); String notifyUrl = randomURL(); + Integer price = randomInteger(); // mock when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> { assertEquals(notifyUrl, request.getNotifyUrl()); return true; }))).thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); // 准备请求参数 - PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); // 断言 assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO)); } - - @Test - @DisplayName("支付包扫描支付,参数校验不通过") - public void test_unified_order_param_validate() { - // 准备请求参数 - String outTradeNo = randomString(); - String notifyUrl = randomURL(); - PayOrderUnifiedReqDTO reqDTO = randomPojo(PayOrderUnifiedReqDTO.class, o -> { - o.setOutTradeNo(outTradeNo); - o.setNotifyUrl(notifyUrl); - }); - // 断言 - assertThrows(ConstraintViolationException.class, () -> client.unifiedOrder(reqDTO)); - } - - private PayOrderUnifiedReqDTO buildOrderUnifiedReqDTO(String notifyUrl, String outTradeNo) { - return randomPojo(PayOrderUnifiedReqDTO.class, o -> { - o.setOutTradeNo(outTradeNo); - o.setNotifyUrl(notifyUrl); - o.setSubject(RandomUtil.randomString(32)); - o.setBody(RandomUtil.randomString(32)); - }); - } } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java new file mode 100644 index 000000000..bad1960ac --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java @@ -0,0 +1,96 @@ +package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; + +import cn.hutool.http.Method; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradeWapPayModel; +import com.alipay.api.request.AlipayTradeWapPayRequest; +import com.alipay.api.response.AlipayTradeWapPayResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentMatcher; +import org.mockito.InjectMocks; + +import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.CLOSED; +import static cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum.WAITING; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * {@link AlipayWapPayClient} 单元测试 + * + * @author jason + */ +public class AlipayWapPayClientTest extends AbstractAlipayClientTest { + + /** + * 支付宝 H5 支付 Client + */ + @InjectMocks + private AlipayWapPayClient client = new AlipayWapPayClient(randomLongId(), config); + + @BeforeEach + public void setUp() { + setClient(client); + } + + @Test + @DisplayName("支付宝 H5 支付下单成功") + public void test_unified_order_success() throws AlipayApiException { + // 准备响应对象 + String h5Body = randomString(); + Integer price = randomInteger(); + AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> { + o.setSubCode(""); + o.setBody(h5Body); + }); + String notifyUrl = randomURL(); + // mock + when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> { + assertInstanceOf(AlipayTradeWapPayModel.class, request.getBizModel()); + AlipayTradeWapPayModel bizModel = (AlipayTradeWapPayModel) request.getBizModel(); + assertEquals(String.valueOf(price / 100.0), bizModel.getTotalAmount()); + assertEquals(notifyUrl, request.getNotifyUrl()); + return true; + }), eq(Method.GET.name()))).thenReturn(response); + + String outTradeNo = randomString(); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); + PayOrderRespDTO resp = client.unifiedOrder(reqDTO); + assertEquals(WAITING.getStatus(), resp.getStatus()); + assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode()); + assertEquals(outTradeNo, resp.getOutTradeNo()); + assertEquals(h5Body, resp.getDisplayContent()); + assertSame(response, resp.getRawData()); + } + + @Test + @DisplayName("支付宝 H5 支付,渠道返回失败") + public void test_unified_order_channel_failed() throws AlipayApiException { + // 准备响应对象 + String subCode = randomString(); + String subMsg = randomString(); + AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> { + o.setSubCode(subCode); + o.setSubMsg(subMsg); + }); + // mock + when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true), + eq(Method.GET.name()))).thenReturn(response); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger()); + + PayOrderRespDTO resp = client.unifiedOrder(reqDTO); + // 断言 + assertEquals(CLOSED.getStatus(), resp.getStatus()); + assertEquals(subCode, resp.getChannelErrorCode()); + assertEquals(subMsg, resp.getChannelErrorMsg()); + assertSame(response, resp.getRawData()); + } +}