package com.tourguide.modules.user.service;
|
|
import com.tourguide.modules.operation.dto.PlatformSettingsResponse;
|
import com.tourguide.modules.operation.entity.OperationScenicSpot;
|
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.mapper.TourOrderMapper;
|
import com.tourguide.modules.user.dto.GuideReceivingOptionResponse;
|
import com.tourguide.modules.user.dto.GuideReceivingStartRequest;
|
import com.tourguide.modules.user.entity.GuideScenicConfig;
|
import com.tourguide.modules.user.entity.GuideUser;
|
import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper;
|
import com.tourguide.modules.user.mapper.GuideReceivingSessionMapper;
|
import com.tourguide.modules.user.mapper.GuideScenicConfigMapper;
|
import com.tourguide.modules.user.mapper.GuideTeamScenicConfigMapper;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
|
import java.math.BigDecimal;
|
import java.util.Collections;
|
|
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.mock;
|
import static org.mockito.Mockito.when;
|
|
class GuideReceivingServiceTest {
|
private GuideUserService guideUserService;
|
private GuideScenicConfigMapper guideScenicMapper;
|
private OperationScenicSpotMapper scenicMapper;
|
private ScenicMeetingPointMapper meetingPointMapper;
|
private ScenicPricingMapper pricingMapper;
|
private GuideReceivingSessionMapper sessionMapper;
|
private GuideRealtimeStatusMapper realtimeStatusMapper;
|
private PlatformSettingsService platformSettingsService;
|
private GuideReceivingService service;
|
|
@BeforeEach
|
void setUp() {
|
guideUserService = mock(GuideUserService.class);
|
guideScenicMapper = mock(GuideScenicConfigMapper.class);
|
GuideTeamScenicConfigMapper teamScenicMapper = mock(GuideTeamScenicConfigMapper.class);
|
scenicMapper = mock(OperationScenicSpotMapper.class);
|
meetingPointMapper = mock(ScenicMeetingPointMapper.class);
|
pricingMapper = mock(ScenicPricingMapper.class);
|
sessionMapper = mock(GuideReceivingSessionMapper.class);
|
realtimeStatusMapper = mock(GuideRealtimeStatusMapper.class);
|
platformSettingsService = mock(PlatformSettingsService.class);
|
TourOrderMapper orderMapper = mock(TourOrderMapper.class);
|
service = new GuideReceivingService(guideUserService, guideScenicMapper, teamScenicMapper, scenicMapper,
|
meetingPointMapper, pricingMapper, sessionMapper, realtimeStatusMapper, platformSettingsService,
|
orderMapper);
|
}
|
|
@Test
|
void shouldEnablePremiumOptionsForGuideWithExplicitPermission() {
|
when(guideUserService.findEnabledById(8L)).thenReturn(explicitPremiumGuide());
|
when(platformSettingsService.getSettings()).thenReturn(strictSettings());
|
when(guideScenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicConfig()));
|
when(scenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicSpot()));
|
when(meetingPointMapper.selectList(any())).thenReturn(Collections.emptyList());
|
when(pricingMapper.selectList(any())).thenReturn(Collections.singletonList(premiumPricing()));
|
|
GuideReceivingOptionResponse response = service.options(8L);
|
|
assertThat(response.isPremiumEnabled()).isTrue();
|
}
|
|
@Test
|
void shouldExposeConfiguredServicePricesForGuideOptions() {
|
when(guideUserService.findEnabledById(8L)).thenReturn(explicitPremiumGuide());
|
when(platformSettingsService.getSettings()).thenReturn(strictSettings());
|
when(guideScenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicConfig()));
|
when(scenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicSpot()));
|
when(meetingPointMapper.selectList(any())).thenReturn(Collections.emptyList());
|
ScenicPricing pricing = premiumPricing();
|
pricing.setOriginalPrice(new BigDecimal("860.00"));
|
pricing.setDiscountPrice(new BigDecimal("836.00"));
|
when(pricingMapper.selectList(any())).thenReturn(Collections.singletonList(pricing));
|
|
GuideReceivingOptionResponse response = service.options(8L);
|
|
GuideReceivingOptionResponse.ServiceOption option = response.getScenics().get(0).getServices().get(0);
|
assertThat(option.getOriginalPrice()).isEqualByComparingTo("860.00");
|
assertThat(option.getDiscountPrice()).isEqualByComparingTo("836.00");
|
}
|
|
@Test
|
void shouldEnablePremiumOptionsForLegacyWhitelistedGuideBelowRuleThresholds() {
|
when(guideUserService.findEnabledById(8L)).thenReturn(whitelistedGuide());
|
when(platformSettingsService.getSettings()).thenReturn(strictSettings());
|
when(guideScenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicConfig()));
|
when(scenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicSpot()));
|
when(meetingPointMapper.selectList(any())).thenReturn(Collections.emptyList());
|
when(pricingMapper.selectList(any())).thenReturn(Collections.singletonList(premiumPricing()));
|
|
GuideReceivingOptionResponse response = service.options(8L);
|
|
assertThat(response.isPremiumEnabled()).isTrue();
|
}
|
|
@Test
|
void shouldRejectStartingPremiumServiceWithoutPermission() {
|
when(guideUserService.findEnabledById(8L)).thenReturn(nonWhitelistedGuide());
|
when(platformSettingsService.getSettings()).thenReturn(strictSettings());
|
when(scenicMapper.selectOne(any())).thenReturn(scenicSpot());
|
when(guideScenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicConfig()));
|
when(meetingPointMapper.selectCount(any())).thenReturn(1L);
|
when(pricingMapper.selectList(any())).thenReturn(Collections.singletonList(premiumPricing()));
|
|
GuideReceivingStartRequest request = new GuideReceivingStartRequest();
|
request.setScenicSpotId(3L);
|
request.setMeetingPointId(4L);
|
request.setReceivingMode("GROUP");
|
request.setServiceTypes(Collections.singletonList("GROUP_PREMIUM"));
|
|
assertThatThrownBy(() -> service.start(8L, request))
|
.isInstanceOf(com.tourguide.common.exception.BusinessException.class)
|
.hasMessage("premium service requirements are not met");
|
}
|
|
@Test
|
void shouldDisablePremiumOptionsForNonWhitelistedGuideBelowRuleThresholds() {
|
when(guideUserService.findEnabledById(8L)).thenReturn(nonWhitelistedGuide());
|
when(platformSettingsService.getSettings()).thenReturn(strictSettings());
|
when(guideScenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicConfig()));
|
when(scenicMapper.selectList(any())).thenReturn(Collections.singletonList(scenicSpot()));
|
when(meetingPointMapper.selectList(any())).thenReturn(Collections.emptyList());
|
when(pricingMapper.selectList(any())).thenReturn(Collections.singletonList(premiumPricing()));
|
|
GuideReceivingOptionResponse response = service.options(8L);
|
|
assertThat(response.isPremiumEnabled()).isFalse();
|
}
|
|
private GuideUser whitelistedGuide() {
|
GuideUser guide = new GuideUser();
|
guide.setId(8L);
|
guide.setAcceptedOrderCount(0L);
|
guide.setRating(BigDecimal.ZERO);
|
guide.setAutoDisableWhitelisted(1);
|
guide.setStatus(GuideUserService.STATUS_ENABLED);
|
return guide;
|
}
|
|
private GuideUser explicitPremiumGuide() {
|
GuideUser guide = nonWhitelistedGuide();
|
guide.setPremiumEnabled(1);
|
return guide;
|
}
|
|
private GuideUser nonWhitelistedGuide() {
|
GuideUser guide = whitelistedGuide();
|
guide.setAutoDisableWhitelisted(0);
|
return guide;
|
}
|
|
private GuideScenicConfig scenicConfig() {
|
GuideScenicConfig config = new GuideScenicConfig();
|
config.setGuideId(8L);
|
config.setScenicName("Test Scenic");
|
return config;
|
}
|
|
private OperationScenicSpot scenicSpot() {
|
OperationScenicSpot scenic = new OperationScenicSpot();
|
scenic.setId(3L);
|
scenic.setScenicName("Test Scenic");
|
scenic.setStatus(1);
|
return scenic;
|
}
|
|
private ScenicPricing premiumPricing() {
|
ScenicPricing pricing = new ScenicPricing();
|
pricing.setId(9L);
|
pricing.setScenicSpotId(3L);
|
pricing.setServiceType("GROUP_PREMIUM");
|
pricing.setDurationMinutes(60);
|
pricing.setMinParticipants(20);
|
pricing.setMaxParticipants(30);
|
return pricing;
|
}
|
|
private PlatformSettingsResponse strictSettings() {
|
PlatformSettingsResponse settings = new PlatformSettingsResponse();
|
settings.setPreciseDispatchOrderCount(10);
|
settings.setPreciseDispatchRating(new BigDecimal("4.8"));
|
return settings;
|
}
|
}
|