From 39f6fca28e3f78abe48f08e474ec011abb990b36 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期三, 09 九月 2026 10:39:21 +0800
Subject: [PATCH] update
---
backend/src/test/java/com/tourguide/modules/order/service/TourOrderServiceTest.java | 125 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 120 insertions(+), 5 deletions(-)
diff --git a/backend/src/test/java/com/tourguide/modules/order/service/TourOrderServiceTest.java b/backend/src/test/java/com/tourguide/modules/order/service/TourOrderServiceTest.java
index d34cb6b..cc021c9 100644
--- a/backend/src/test/java/com/tourguide/modules/order/service/TourOrderServiceTest.java
+++ b/backend/src/test/java/com/tourguide/modules/order/service/TourOrderServiceTest.java
@@ -1,45 +1,60 @@
package com.tourguide.modules.order.service;
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tourguide.common.exception.BusinessException;
import com.tourguide.modules.order.domain.OrderStatus;
import com.tourguide.modules.order.domain.RefundStatus;
+import com.tourguide.modules.order.dto.TourOrderResponse;
import com.tourguide.modules.order.entity.TourOrder;
import com.tourguide.modules.order.mapper.TourOrderMapper;
import com.tourguide.modules.review.mapper.OrderReviewMapper;
+import com.tourguide.modules.review.entity.OrderReview;
import com.tourguide.modules.system.service.GuideNotificationService;
+import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.any;
class TourOrderServiceTest {
private TourOrderMapper orderMapper;
private TourOrderService orderService;
+ private OrderRefundService refundService;
+ private GuideNotificationService notificationService;
+ private static boolean tableInfoInitialized;
+ private static boolean reviewTableInfoInitialized;
@BeforeEach
void setUp() {
orderMapper = mock(TourOrderMapper.class);
+ refundService = mock(OrderRefundService.class);
+ notificationService = mock(GuideNotificationService.class);
orderService = new TourOrderService(orderMapper, mock(OrderReviewMapper.class),
- mock(GuideNotificationService.class));
+ notificationService, refundService);
}
@Test
void shouldRefundRequestedAmount() {
TourOrder order = refundableOrder();
when(orderMapper.selectForUpdate(1L)).thenReturn(order);
+ when(refundService.requestRefund(order, new BigDecimal("100.00"))).thenReturn(true);
orderService.refund(1L, new BigDecimal("100.00"));
- assertThat(order.getRefundAmount()).isEqualByComparingTo("100.00");
- assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUNDED.getCode());
- assertThat(order.getStatus()).isEqualTo(OrderStatus.REFUNDED.getCode());
- verify(orderMapper).updateById(order);
+ verify(refundService).requestRefund(order, new BigDecimal("100.00"));
}
@Test
@@ -52,6 +67,105 @@
.hasMessage("退款金额不能超过当前可退金额");
}
+ @Test
+ void shouldAllowFollowUpRefundForPartialOrder() {
+ TourOrder order = refundableOrder();
+ order.setStatus(OrderStatus.CANCELLED.getCode());
+ order.setRefundStatus(RefundStatus.PARTIAL.getCode());
+ order.setRefundedAmount(new BigDecimal("100.00"));
+ when(orderMapper.selectForUpdate(1L)).thenReturn(order);
+ when(refundService.requestRefund(order, new BigDecimal("56.00"))).thenReturn(true);
+
+ TourOrderResponse response = orderService.refund(1L, new BigDecimal("56.00"));
+
+ assertThat(response.getRefundableAmount()).isEqualByComparingTo("56.00");
+ verify(refundService).requestRefund(order, new BigDecimal("56.00"));
+ }
+
+ @Test
+ void shouldRejectFollowUpRefundAboveRemainingAmount() {
+ TourOrder order = refundableOrder();
+ order.setStatus(OrderStatus.CANCELLED.getCode());
+ order.setRefundStatus(RefundStatus.PARTIAL.getCode());
+ order.setRefundedAmount(new BigDecimal("100.00"));
+ when(orderMapper.selectForUpdate(1L)).thenReturn(order);
+
+ assertThatThrownBy(() -> orderService.refund(1L, new BigDecimal("56.01")))
+ .isInstanceOf(BusinessException.class)
+ .hasMessage("退款金额不能超过当前可退金额");
+ }
+
+ @Test
+ void shouldReportProviderFailureInsteadOfSuccess() {
+ TourOrder order = refundableOrder();
+ when(orderMapper.selectForUpdate(1L)).thenReturn(order);
+ when(refundService.requestRefund(order, new BigDecimal("100.00"))).thenReturn(false);
+
+ assertThatThrownBy(() -> orderService.refund(1L, new BigDecimal("100.00")))
+ .isInstanceOf(BusinessException.class)
+ .hasMessage("支付渠道退款失败,请稍后重试");
+ }
+
+ @Test
+ void notificationFailureShouldNotFailAcceptedRefund() {
+ TourOrder order = refundableOrder();
+ order.setStatus(OrderStatus.PENDING_MEETING.getCode());
+ order.setGuideId(42L);
+ when(orderMapper.selectForUpdate(1L)).thenReturn(order);
+ when(refundService.requestRefund(order, new BigDecimal("100.00"))).thenReturn(true);
+ doThrow(new IllegalStateException("notification unavailable"))
+ .when(notificationService).notifyOrderCancelled(order);
+
+ TourOrderResponse response = orderService.refund(1L, new BigDecimal("100.00"));
+
+ assertThat(response).isNotNull();
+ verify(notificationService).notifyOrderCancelled(order);
+ }
+
+ @Test
+ void shouldFilterOrdersByGuideId() {
+ initializeTableInfo();
+ when(orderMapper.selectPage(any(Page.class), any())).thenAnswer(invocation -> invocation.getArgument(0));
+
+ orderService.page(1, 10, null, null, 42L, null, null, null, null);
+
+ ArgumentCaptor<LambdaQueryWrapper<TourOrder>> queryCaptor = ArgumentCaptor.forClass(LambdaQueryWrapper.class);
+ verify(orderMapper).selectPage(any(Page.class), queryCaptor.capture());
+ queryCaptor.getValue().getSqlSegment();
+ assertThat(queryCaptor.getValue().getParamNameValuePairs().values()).contains(42L);
+ }
+
+ @Test
+ void detailShouldOnlyTreatVisibleReviewAsReviewed() {
+ initializeTableInfo();
+ initializeReviewTableInfo();
+ OrderReviewMapper reviewMapper = mock(OrderReviewMapper.class);
+ orderService = new TourOrderService(orderMapper, reviewMapper, notificationService, refundService);
+ TourOrder order = new TourOrder();
+ order.setId(1L);
+ when(orderMapper.selectById(1L)).thenReturn(order);
+
+ orderService.detail(1L);
+
+ ArgumentCaptor<LambdaQueryWrapper<OrderReview>> queryCaptor = ArgumentCaptor.forClass(LambdaQueryWrapper.class);
+ verify(reviewMapper).selectOne(queryCaptor.capture());
+ assertThat(queryCaptor.getValue().getSqlSegment()).contains("status");
+ }
+
+ private static void initializeTableInfo() {
+ if (!tableInfoInitialized) {
+ TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), TourOrder.class);
+ tableInfoInitialized = true;
+ }
+ }
+
+ private static void initializeReviewTableInfo() {
+ if (!reviewTableInfoInitialized) {
+ TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), OrderReview.class);
+ reviewTableInfoInitialized = true;
+ }
+ }
+
private TourOrder refundableOrder() {
TourOrder order = new TourOrder();
order.setId(1L);
@@ -60,6 +174,7 @@
order.setRefundStatus(RefundStatus.NONE.getCode());
order.setAmount(new BigDecimal("256.10"));
order.setPaymentAmount(new BigDecimal("156.00"));
+ order.setPaymentTime(LocalDateTime.now());
order.setPaymentMethod("WECHAT");
return order;
}
--
Gitblit v1.7.1