package com.tourguide.modules.order.service;
|
|
import com.tourguide.modules.operation.entity.OperationScenicSpot;
|
import com.tourguide.modules.operation.entity.ScenicMeetingPoint;
|
import com.tourguide.modules.operation.entity.ScenicPricing;
|
import com.tourguide.modules.operation.mapper.OperationScenicSpotMapper;
|
import com.tourguide.modules.operation.mapper.ScenicMeetingPointMapper;
|
import com.tourguide.modules.operation.mapper.ScenicPricingMapper;
|
import com.tourguide.modules.operation.service.PlatformSettingsService;
|
import com.tourguide.modules.order.domain.OrderStatus;
|
import com.tourguide.modules.order.dto.MiniOrderCreateRequest;
|
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.user.entity.MiniUser;
|
import com.tourguide.modules.user.mapper.GuideUserMapper;
|
import com.tourguide.modules.user.service.MiniUserService;
|
import com.tourguide.modules.system.service.GuideNotificationService;
|
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.ArgumentMatchers.any;
|
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
class MiniTourOrderCommandServiceTest {
|
private TourOrderMapper orderMapper;
|
private MiniUserService miniUserService;
|
private OperationScenicSpotMapper scenicSpotMapper;
|
private ScenicMeetingPointMapper meetingPointMapper;
|
private ScenicPricingMapper pricingMapper;
|
private GuideUserMapper guideUserMapper;
|
private PlatformSettingsService platformSettingsService;
|
private GuideOrderMatchingService matchingService;
|
private GuideNotificationService notificationService;
|
private MiniTourOrderCommandService commandService;
|
|
@BeforeEach
|
void setUp() {
|
orderMapper = mock(TourOrderMapper.class);
|
miniUserService = mock(MiniUserService.class);
|
scenicSpotMapper = mock(OperationScenicSpotMapper.class);
|
meetingPointMapper = mock(ScenicMeetingPointMapper.class);
|
pricingMapper = mock(ScenicPricingMapper.class);
|
guideUserMapper = mock(GuideUserMapper.class);
|
platformSettingsService = mock(PlatformSettingsService.class);
|
matchingService = mock(GuideOrderMatchingService.class);
|
notificationService = mock(GuideNotificationService.class);
|
commandService = new MiniTourOrderCommandService(
|
orderMapper, miniUserService, scenicSpotMapper, meetingPointMapper, pricingMapper,
|
guideUserMapper, platformSettingsService, matchingService, notificationService);
|
}
|
|
@Test
|
void createShouldKeepOrderPendingPaymentUntilPaymentSucceeds() {
|
MiniUser visitor = new MiniUser();
|
visitor.setId(7L);
|
visitor.setNickname("游客");
|
visitor.setMobile("13800138000");
|
when(miniUserService.findEnabledById(7L)).thenReturn(visitor);
|
|
OperationScenicSpot scenicSpot = new OperationScenicSpot();
|
scenicSpot.setId(11L);
|
scenicSpot.setScenicName("青城山景区");
|
scenicSpot.setStatus(1);
|
when(scenicSpotMapper.selectOne(any())).thenReturn(scenicSpot);
|
|
ScenicMeetingPoint meetingPoint = new ScenicMeetingPoint();
|
meetingPoint.setId(12L);
|
meetingPoint.setScenicSpotId(11L);
|
meetingPoint.setPointName("景区正门");
|
meetingPoint.setStatus(1);
|
when(meetingPointMapper.selectOne(any())).thenReturn(meetingPoint);
|
|
ScenicPricing pricing = new ScenicPricing();
|
pricing.setId(13L);
|
pricing.setScenicSpotId(11L);
|
pricing.setServiceType("GROUP_QUICK");
|
pricing.setOriginalPrice(new BigDecimal("40.00"));
|
pricing.setDiscountPrice(new BigDecimal("36.00"));
|
pricing.setMaxParticipants(10);
|
when(pricingMapper.selectOne(any())).thenReturn(pricing);
|
doAnswer(invocation -> {
|
TourOrder order = invocation.getArgument(0);
|
order.setId(99L);
|
return 1;
|
}).when(orderMapper).insert(any(TourOrder.class));
|
|
MiniOrderCreateRequest request = new MiniOrderCreateRequest();
|
request.setScenicSpotId(11L);
|
request.setMeetingPointId(12L);
|
request.setServicePackageId(13L);
|
request.setPeopleCount(4);
|
|
TourOrderResponse response = commandService.create(7L, request);
|
|
ArgumentCaptor<TourOrder> captor = ArgumentCaptor.forClass(TourOrder.class);
|
verify(orderMapper).insert(captor.capture());
|
TourOrder order = captor.getValue();
|
assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING_PAYMENT.getCode());
|
assertThat(order.getPaymentMethod()).isNull();
|
assertThat(order.getPaymentOrderNo()).isNull();
|
assertThat(order.getPaymentAmount()).isNull();
|
assertThat(order.getPaymentTime()).isNull();
|
assertThat(response.getStatus()).isEqualTo(OrderStatus.PENDING_PAYMENT.getCode());
|
}
|
|
@Test
|
void confirmPaymentShouldMovePendingOrderToPendingAccept() {
|
MiniUser visitor = new MiniUser();
|
visitor.setId(7L);
|
when(miniUserService.findEnabledById(7L)).thenReturn(visitor);
|
|
TourOrder order = new TourOrder();
|
order.setId(99L);
|
order.setOrderNo("MJ202607290001");
|
order.setVisitorId(7L);
|
order.setAmount(new BigDecimal("144.00"));
|
order.setStatus(OrderStatus.PENDING_PAYMENT.getCode());
|
when(orderMapper.selectOne(any())).thenReturn(order);
|
when(orderMapper.selectById(99L)).thenReturn(order);
|
|
TourOrderResponse response = commandService.confirmPayment(7L, 99L);
|
|
assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING_ACCEPT.getCode());
|
assertThat(order.getPaymentMethod()).isEqualTo("WECHAT");
|
assertThat(order.getPaymentOrderNo()).isEqualTo("LOCALMJ202607290001");
|
assertThat(order.getPaymentAmount()).isEqualByComparingTo("144.00");
|
assertThat(order.getPaymentTime()).isNotNull();
|
assertThat(response.getStatus()).isEqualTo(OrderStatus.PENDING_ACCEPT.getCode());
|
verify(orderMapper).updateById(order);
|
}
|
|
@Test
|
void createShouldRejectVisitorWithUnfinishedOrder() {
|
MiniUser visitor = new MiniUser();
|
visitor.setId(7L);
|
when(miniUserService.findEnabledById(7L)).thenReturn(visitor);
|
when(orderMapper.selectCount(any())).thenReturn(1L);
|
|
assertThatThrownBy(() -> commandService.create(7L, new MiniOrderCreateRequest()))
|
.isInstanceOf(com.tourguide.common.exception.BusinessException.class)
|
.hasMessage("您有一个未完成的订单,请先完成或取消后再下单");
|
|
verify(orderMapper, never()).insert(any(TourOrder.class));
|
}
|
|
@Test
|
void cancelPendingMeetingOrderShouldNotifyAssignedGuide() {
|
MiniUser visitor = new MiniUser();
|
visitor.setId(7L);
|
when(miniUserService.findEnabledById(7L)).thenReturn(visitor);
|
|
TourOrder order = new TourOrder();
|
order.setId(99L);
|
order.setOrderNo("MJ202607300001");
|
order.setVisitorId(7L);
|
order.setGuideId(8L);
|
order.setStatus(OrderStatus.PENDING_MEETING.getCode());
|
order.setPaymentTime(LocalDateTime.now());
|
order.setPaymentAmount(new BigDecimal("36.00"));
|
when(orderMapper.selectOne(any())).thenReturn(order);
|
|
commandService.cancel(7L, 99L);
|
|
assertThat(order.getStatus()).isEqualTo(OrderStatus.CANCELLED.getCode());
|
verify(orderMapper).updateById(order);
|
verify(notificationService).notifyOrderCancelled(order);
|
}
|
}
|