package com.tourguide.modules.user.service; import com.tourguide.modules.order.mapper.TourOrderMapper; import com.tourguide.modules.user.entity.GuideAutoDisableConfig; import com.tourguide.modules.user.entity.GuideUser; import com.tourguide.modules.user.mapper.GuideAutoDisableConfigMapper; import com.tourguide.modules.user.mapper.GuideRealtimeStatusMapper; import com.tourguide.modules.user.mapper.GuideReceivingSessionMapper; 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.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; class GuideAutoDisableServiceTest { private GuideAutoDisableConfigMapper configMapper; private GuideUserMapper guideUserMapper; private TourOrderMapper orderMapper; private GuideRealtimeStatusMapper realtimeStatusMapper; private GuideReceivingSessionMapper receivingSessionMapper; private GuideAutoDisableService service; @BeforeEach void setUp() { configMapper = mock(GuideAutoDisableConfigMapper.class); guideUserMapper = mock(GuideUserMapper.class); orderMapper = mock(TourOrderMapper.class); realtimeStatusMapper = mock(GuideRealtimeStatusMapper.class); receivingSessionMapper = mock(GuideReceivingSessionMapper.class); service = new GuideAutoDisableService(configMapper, guideUserMapper, orderMapper, realtimeStatusMapper, receivingSessionMapper); } @Test void shouldDisableEligibleNonWhitelistedGuide() { GuideAutoDisableConfig config = validConfig(); GuideUser guide = eligibleGuide(0); when(configMapper.selectById(1)).thenReturn(config); when(guideUserMapper.selectList(any())).thenReturn(Collections.singletonList(guide)); when(orderMapper.selectCount(any())).thenReturn(0L); when(guideUserMapper.autoDisableIfEligible(8L, 10, new BigDecimal("4.50"))).thenReturn(1); service.disableEligibleGuides(); verify(guideUserMapper).autoDisableIfEligible(8L, 10, new BigDecimal("4.50")); verify(realtimeStatusMapper).disableReceiving(8L); verify(receivingSessionMapper).stopReceivingByGuide(8L); } @Test void shouldNeverDisableWhitelistedGuide() { service.disableIfEligible(eligibleGuide(1), validConfig()); verifyNoInteractions(orderMapper, realtimeStatusMapper, receivingSessionMapper); verify(guideUserMapper, never()).autoDisableIfEligible(any(), any(), any()); } @Test void shouldKeepGuideEnabledWhenActiveServiceOrderExists() { when(orderMapper.selectCount(any())).thenReturn(1L); service.disableIfEligible(eligibleGuide(0), validConfig()); verify(guideUserMapper, never()).autoDisableIfEligible(any(), any(), any()); verifyNoInteractions(realtimeStatusMapper, receivingSessionMapper); } @Test void shouldNotCloseReceivingWhenAtomicDisableConditionNoLongerMatches() { when(orderMapper.selectCount(any())).thenReturn(0L); when(guideUserMapper.autoDisableIfEligible(8L, 10, new BigDecimal("4.50"))).thenReturn(0); service.disableIfEligible(eligibleGuide(0), validConfig()); verifyNoInteractions(realtimeStatusMapper, receivingSessionMapper); } @Test void shouldSkipScanWhenConfigIsMissingOrInvalid() { when(configMapper.selectById(1)).thenReturn(null, invalidConfig()); service.disableEligibleGuides(); service.disableEligibleGuides(); verify(guideUserMapper, never()).selectList(any()); verifyNoInteractions(orderMapper, realtimeStatusMapper, receivingSessionMapper); } private GuideAutoDisableConfig validConfig() { GuideAutoDisableConfig config = new GuideAutoDisableConfig(); config.setId(1); config.setOrderThreshold(10); config.setRatingThreshold(new BigDecimal("4.50")); return config; } private GuideAutoDisableConfig invalidConfig() { GuideAutoDisableConfig config = validConfig(); config.setOrderThreshold(0); return config; } private GuideUser eligibleGuide(int whitelisted) { GuideUser guide = new GuideUser(); guide.setId(8L); guide.setStatus(GuideUserService.STATUS_ENABLED); guide.setAcceptedOrderCount(12L); guide.setRating(new BigDecimal("4.20")); guide.setAutoDisableWhitelisted(whitelisted); return guide; } }