package com.tourguide.modules.user.service; import com.tourguide.common.exception.BusinessException; import com.tourguide.modules.finance.mapper.GuideWithdrawalMapper; import com.tourguide.modules.operation.entity.OperationCity; import com.tourguide.modules.operation.entity.OperationScenicSpot; import com.tourguide.modules.operation.entity.ScenicMeetingPoint; import com.tourguide.modules.operation.mapper.OperationCityMapper; import com.tourguide.modules.operation.mapper.OperationScenicSpotMapper; import com.tourguide.modules.operation.mapper.ScenicMeetingPointMapper; import com.tourguide.modules.user.dto.GuideTeamScenicRequest; import com.tourguide.modules.user.dto.GuideTeamSaveRequest; import com.tourguide.modules.user.entity.GuideTeam; import com.tourguide.modules.user.entity.GuideUser; import com.tourguide.modules.user.mapper.GuideTeamMapper; import com.tourguide.modules.user.mapper.GuideTeamScenicConfigMapper; import com.tourguide.modules.user.mapper.GuideUserMapper; 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.verify; import static org.mockito.Mockito.when; class GuideTeamServiceTest { private GuideTeamMapper teamMapper; private GuideTeamScenicConfigMapper scenicConfigMapper; private GuideUserMapper guideUserMapper; private GuideWithdrawalMapper withdrawalMapper; private OperationScenicSpotMapper operationScenicSpotMapper; private OperationCityMapper operationCityMapper; private ScenicMeetingPointMapper meetingPointMapper; private GuideTeamService service; @BeforeEach void setUp() { teamMapper = mock(GuideTeamMapper.class); scenicConfigMapper = mock(GuideTeamScenicConfigMapper.class); guideUserMapper = mock(GuideUserMapper.class); withdrawalMapper = mock(GuideWithdrawalMapper.class); operationScenicSpotMapper = mock(OperationScenicSpotMapper.class); operationCityMapper = mock(OperationCityMapper.class); meetingPointMapper = mock(ScenicMeetingPointMapper.class); service = new GuideTeamService(teamMapper, scenicConfigMapper, guideUserMapper, withdrawalMapper, operationScenicSpotMapper, operationCityMapper, meetingPointMapper); } @Test void updateShouldRejectCollectionGuideWithBalance() { GuideTeam team = team(); GuideUser guide = collectionGuide(new BigDecimal("0.01")); when(teamMapper.selectById(6L)).thenReturn(team); when(teamMapper.selectCount(any())).thenReturn(0L); when(guideUserMapper.selectForUpdate(8L)).thenReturn(guide); assertThatThrownBy(() -> service.update(6L, request(8L))) .isInstanceOf(BusinessException.class) .hasMessageContaining("余额必须为0"); } @Test void updateShouldRejectCollectionGuideWithActiveWithdrawal() { GuideTeam team = team(); GuideUser guide = collectionGuide(BigDecimal.ZERO); when(teamMapper.selectById(6L)).thenReturn(team); when(teamMapper.selectCount(any())).thenReturn(0L); when(guideUserMapper.selectForUpdate(8L)).thenReturn(guide); when(withdrawalMapper.countActiveByGuideId(8L)).thenReturn(1L); assertThatThrownBy(() -> service.update(6L, request(8L))) .isInstanceOf(BusinessException.class) .hasMessageContaining("进行中的提现单"); } @Test void updateShouldConfigureEligibleCollectionGuide() { GuideTeam team = team(); GuideUser guide = collectionGuide(BigDecimal.ZERO); when(teamMapper.selectById(6L)).thenReturn(team); when(teamMapper.selectCount(any())).thenReturn(0L); when(guideUserMapper.selectForUpdate(8L)).thenReturn(guide); when(scenicConfigMapper.selectList(any())).thenReturn(Collections.emptyList()); assertThat(service.update(6L, request(8L)).getCollectionGuideId()).isEqualTo(8L); } @Test void updateShouldAcceptScenicAndMeetingPointsFromScenicManagement() { when(teamMapper.selectById(6L)).thenReturn(team()); when(teamMapper.selectCount(any())).thenReturn(0L); when(scenicConfigMapper.selectList(any())).thenReturn(Collections.emptyList()); mockManagedScenic("博物馆东门"); GuideTeamSaveRequest request = request(null); request.setScenicConfigs(Collections.singletonList(scenicRequest("博物馆东门"))); service.update(6L, request); verify(scenicConfigMapper).upsert(any()); } @Test void updateShouldRejectMeetingPointOutsideScenicManagement() { when(teamMapper.selectById(6L)).thenReturn(team()); when(teamMapper.selectCount(any())).thenReturn(0L); mockManagedScenic("博物馆东门"); GuideTeamSaveRequest request = request(null); request.setScenicConfigs(Collections.singletonList(scenicRequest("自行填写的汇合点"))); assertThatThrownBy(() -> service.update(6L, request)) .isInstanceOf(BusinessException.class) .hasMessage("汇合点必须从所选景区的启用汇合点中选择"); } private GuideTeam team() { GuideTeam team = new GuideTeam(); team.setId(6L); team.setTeamName("测试讲解队"); return team; } private GuideUser collectionGuide(BigDecimal balance) { GuideUser guide = new GuideUser(); guide.setId(8L); guide.setTeamId(6L); guide.setStatus(1); guide.setBalance(balance); return guide; } private void mockManagedScenic(String meetingPointName) { OperationCity city = new OperationCity(); city.setId(1L); city.setCityName("成都"); city.setStatus(1); when(operationCityMapper.selectOne(any())).thenReturn(city); OperationScenicSpot scenicSpot = new OperationScenicSpot(); scenicSpot.setId(2L); scenicSpot.setScenicName("博物馆"); scenicSpot.setCityId(1L); scenicSpot.setStatus(1); when(operationScenicSpotMapper.selectOne(any())).thenReturn(scenicSpot); ScenicMeetingPoint meetingPoint = new ScenicMeetingPoint(); meetingPoint.setPointName(meetingPointName); meetingPoint.setStatus(1); when(meetingPointMapper.selectList(any())).thenReturn(Collections.singletonList(meetingPoint)); } private GuideTeamScenicRequest scenicRequest(String meetingPointName) { GuideTeamScenicRequest request = new GuideTeamScenicRequest(); request.setScenicName("博物馆"); request.setCityName("成都"); request.setMeetingPoints(meetingPointName); return request; } private GuideTeamSaveRequest request(Long collectionGuideId) { GuideTeamSaveRequest request = new GuideTeamSaveRequest(); request.setTeamName("测试讲解队"); request.setContactPhone("13800138000"); request.setCommissionRatio(BigDecimal.TEN); request.setWechatOpenId("openid"); request.setCollectionGuideId(collectionGuideId); request.setScenicConfigs(Collections.emptyList()); return request; } }