|
|
@@ -0,0 +1,80 @@
|
|
|
+package com.ruoyi.app.omgpay;
|
|
|
+
|
|
|
+import com.ruoyi.app.omgpay.dto.OmgPaymentErrorResponse;
|
|
|
+import com.ruoyi.app.omgpay.dto.OmgRefundPaymentRequest;
|
|
|
+import com.ruoyi.common.core.domain.AjaxResult;
|
|
|
+import com.ruoyi.common.utils.MessageUtils;
|
|
|
+import com.ruoyi.system.omgpay.service.OmgIpnAuditService;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+import org.mockito.MockedStatic;
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestBody;
|
|
|
+import org.springframework.web.bind.annotation.RequestHeader;
|
|
|
+
|
|
|
+import java.lang.reflect.Method;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import static org.junit.jupiter.api.Assertions.*;
|
|
|
+import static org.mockito.ArgumentMatchers.anyString;
|
|
|
+import static org.mockito.Mockito.*;
|
|
|
+
|
|
|
+class OmgPaymentRefundControllerTest {
|
|
|
+ @Test
|
|
|
+ void exposesAuthenticatedOrderIdOnlyRefundContract() throws Exception {
|
|
|
+ Method method = OmgPaymentController.class.getDeclaredMethod(
|
|
|
+ "refund", String.class, OmgRefundPaymentRequest.class);
|
|
|
+
|
|
|
+ assertArrayEquals(new String[]{"/refund"}, method.getAnnotation(PostMapping.class).value());
|
|
|
+ assertEquals("token", method.getParameters()[0].getAnnotation(RequestHeader.class).name());
|
|
|
+ assertNotNull(method.getParameters()[1].getAnnotation(RequestBody.class));
|
|
|
+ assertEquals(1, OmgRefundPaymentRequest.class.getDeclaredFields().length);
|
|
|
+ assertEquals("orderId", OmgRefundPaymentRequest.class.getDeclaredFields()[0].getName());
|
|
|
+ assertTrue(java.util.Arrays.stream(method.getParameterTypes())
|
|
|
+ .noneMatch(Map.class::isAssignableFrom));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void returnsStableLocalizedTestEnvironmentRejection() {
|
|
|
+ try (MockedStatic<MessageUtils> messages = mockStatic(MessageUtils.class)) {
|
|
|
+ messages.when(() -> MessageUtils.message(anyString())).thenAnswer(call -> call.getArgument(0));
|
|
|
+ OmgPaymentTokenUserResolver resolver = mock(OmgPaymentTokenUserResolver.class);
|
|
|
+ OmgPaymentRefundService refundService = mock(OmgPaymentRefundService.class);
|
|
|
+ when(resolver.requireUserId("token")).thenReturn(5L);
|
|
|
+ when(refundService.refund(5L, "DD-1")).thenThrow(new OmgPaymentBusinessException(
|
|
|
+ OmgPaymentErrorCode.PAYMENT_REFUND_UNAVAILABLE_IN_TEST_ENVIRONMENT));
|
|
|
+ OmgRefundPaymentRequest request = new OmgRefundPaymentRequest();
|
|
|
+ request.setOrderId("DD-1");
|
|
|
+
|
|
|
+ AjaxResult result = controller(resolver, refundService).refund("token", request);
|
|
|
+
|
|
|
+ assertEquals("omg.pay.refund.unavailable.test.environment", result.get("msg"));
|
|
|
+ assertEquals("PAYMENT_REFUND_UNAVAILABLE_IN_TEST_ENVIRONMENT",
|
|
|
+ ((OmgPaymentErrorResponse) result.get("data")).status());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void unexpectedFailureUsesStableRefundFailureWithoutLeakingToken() {
|
|
|
+ try (MockedStatic<MessageUtils> messages = mockStatic(MessageUtils.class)) {
|
|
|
+ messages.when(() -> MessageUtils.message(anyString())).thenAnswer(call -> call.getArgument(0));
|
|
|
+ OmgPaymentTokenUserResolver resolver = mock(OmgPaymentTokenUserResolver.class);
|
|
|
+ OmgPaymentRefundService refundService = mock(OmgPaymentRefundService.class);
|
|
|
+ when(resolver.requireUserId("NEVER_LOG")).thenReturn(5L);
|
|
|
+ when(refundService.refund(5L, "DD-1")).thenThrow(new IllegalStateException("unexpected"));
|
|
|
+ OmgRefundPaymentRequest request = new OmgRefundPaymentRequest();
|
|
|
+ request.setOrderId("DD-1");
|
|
|
+
|
|
|
+ AjaxResult result = controller(resolver, refundService).refund("NEVER_LOG", request);
|
|
|
+
|
|
|
+ assertEquals("PAYMENT_REFUND_FAILED",
|
|
|
+ ((OmgPaymentErrorResponse) result.get("data")).status());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static OmgPaymentController controller(OmgPaymentTokenUserResolver resolver,
|
|
|
+ OmgPaymentRefundService refundService) {
|
|
|
+ return new OmgPaymentController(resolver, mock(OmgPaymentCreateService.class),
|
|
|
+ mock(OmgPaymentNotifyService.class), mock(OmgIpnAuditService.class),
|
|
|
+ mock(OmgPaymentQueryService.class), refundService);
|
|
|
+ }
|
|
|
+}
|