| | |
| | | |
| | | import com.tourguide.modules.operation.service.PlatformSettingsService; |
| | | import com.tourguide.modules.order.domain.OrderStatus; |
| | | import com.tourguide.modules.order.domain.RefundStatus; |
| | | import com.tourguide.modules.order.entity.TourOrder; |
| | | import com.tourguide.modules.order.mapper.TourOrderMapper; |
| | | import com.tourguide.modules.order.payment.PaymentRefundGateway; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | | import org.junit.jupiter.api.Test; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.mockito.Mockito.mock; |
| | | import static org.mockito.Mockito.never; |
| | | import static org.mockito.Mockito.verify; |
| | |
| | | |
| | | class OrderAutoRefundServiceTest { |
| | | private TourOrderMapper orderMapper; |
| | | private PaymentRefundGateway paymentRefundGateway; |
| | | private OrderRefundService orderRefundService; |
| | | private OrderAutoRefundService autoRefundService; |
| | | |
| | | @BeforeEach |
| | | void setUp() { |
| | | orderMapper = mock(TourOrderMapper.class); |
| | | paymentRefundGateway = mock(PaymentRefundGateway.class); |
| | | orderRefundService = mock(OrderRefundService.class); |
| | | autoRefundService = new OrderAutoRefundService( |
| | | orderMapper, mock(PlatformSettingsService.class), paymentRefundGateway); |
| | | orderMapper, mock(PlatformSettingsService.class), orderRefundService); |
| | | } |
| | | |
| | | @Test |
| | | void shouldRefundActualPaymentAmountAfterClaimingOrder() { |
| | | void shouldRequestRefundAfterClaimingOrder() { |
| | | TourOrder order = paidCancelledOrder(); |
| | | when(orderMapper.claimUnacceptedOrderForRefund(9L)).thenReturn(1); |
| | | when(orderMapper.selectById(9L)).thenReturn(order); |
| | | when(paymentRefundGateway.refund(order, new BigDecimal("36.00"))).thenReturn("LOCALRF001"); |
| | | |
| | | autoRefundService.refundIfStillUnaccepted(9L); |
| | | |
| | | assertThat(order.getStatus()).isEqualTo(OrderStatus.CANCELLED.getCode()); |
| | | assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUNDED.getCode()); |
| | | assertThat(order.getRefundAmount()).isEqualByComparingTo("36.00"); |
| | | assertThat(order.getRefundOrderNo()).isEqualTo("LOCALRF001"); |
| | | assertThat(order.getRefundMethod()).isEqualTo("WECHAT"); |
| | | assertThat(order.getRefundTime()).isNotNull(); |
| | | verify(orderMapper).updateById(order); |
| | | verify(orderRefundService).requestRefund(order); |
| | | } |
| | | |
| | | @Test |
| | |
| | | autoRefundService.refundIfStillUnaccepted(9L); |
| | | |
| | | verify(orderMapper, never()).selectById(9L); |
| | | verify(paymentRefundGateway, never()).refund(org.mockito.ArgumentMatchers.any(), |
| | | org.mockito.ArgumentMatchers.any()); |
| | | } |
| | | |
| | | @Test |
| | | void shouldRecordFailureWhenPaymentGatewayIsUnavailable() { |
| | | TourOrder order = paidCancelledOrder(); |
| | | when(orderMapper.claimUnacceptedOrderForRefund(9L)).thenReturn(1); |
| | | when(orderMapper.selectById(9L)).thenReturn(order); |
| | | when(paymentRefundGateway.refund(order, new BigDecimal("36.00"))) |
| | | .thenThrow(new IllegalStateException("not configured")); |
| | | |
| | | autoRefundService.refundIfStillUnaccepted(9L); |
| | | |
| | | assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUND_FAILED.getCode()); |
| | | verify(orderMapper).updateById(order); |
| | | verify(orderRefundService, never()).requestRefund(org.mockito.ArgumentMatchers.any()); |
| | | } |
| | | |
| | | private TourOrder paidCancelledOrder() { |
| | |
| | | order.setOrderNo("MJ202607290009"); |
| | | order.setStatus(OrderStatus.CANCELLED.getCode()); |
| | | order.setPaymentMethod("WECHAT"); |
| | | order.setPaymentOrderNo("LOCALMJ202607290009"); |
| | | order.setPaymentOrderNo("PY202608031700000000000000000001"); |
| | | order.setAmount(new BigDecimal("40.00")); |
| | | order.setPaymentAmount(new BigDecimal("36.00")); |
| | | return order; |