yanderong
2026-10-02 bca4733e4b0fcd9b6496e608304549a09f982463
ruoyi-service/ruoyi-account/src/test/java/com/ruoyi/account/service/impl/TAppUserWhitelistServiceImplTest.java
@@ -6,6 +6,7 @@
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.ruoyi.account.api.dto.AppUserWhitelistAllocateDTO;
import com.ruoyi.account.api.dto.AppUserWhitelistAllocateItemDTO;
import com.ruoyi.account.api.dto.AppUserWhitelistStatusDTO;
import com.ruoyi.account.api.model.TAppUser;
import com.ruoyi.account.api.model.TAppUserWhitelist;
import com.ruoyi.account.api.model.TCompanyAllocateRecord;
@@ -13,6 +14,7 @@
import com.ruoyi.account.api.vo.AppUserWhitelistImportResultVO;
import com.ruoyi.account.api.vo.AppUserWhitelistMatchVO;
import com.ruoyi.account.mapper.TAppUserWhitelistMapper;
import com.ruoyi.account.service.PartnerAppUserAccessService;
import com.ruoyi.account.service.TAppUserService;
import com.ruoyi.account.service.TAppUserWhitelistSiteService;
import com.ruoyi.account.service.TCompanyAllocateRecordService;
@@ -56,6 +58,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -75,6 +78,7 @@
    @Mock private GroupCompanyClient groupCompanyClient;
    @Mock private RedissonClient redissonClient;
    @Mock private TCompanyAllocateRecordService companyAllocateRecordService;
    @Mock private PartnerAppUserAccessService partnerAppUserAccessService;
    private TAppUserWhitelistServiceImpl service;
@@ -99,6 +103,10 @@
        ReflectionTestUtils.setField(service, "groupCompanyClient", groupCompanyClient);
        ReflectionTestUtils.setField(service, "redissonClient", redissonClient);
        ReflectionTestUtils.setField(service, "companyAllocateRecordService", companyAllocateRecordService);
        ReflectionTestUtils.setField(service, "partnerAppUserAccessService", partnerAppUserAccessService);
        // 默认透传(模拟非公司账号),公司账号隔离场景由具体用例覆盖打桩
        lenient().when(partnerAppUserAccessService.resolveCompanyFilter(any())).thenAnswer(invocation -> invocation.getArgument(0));
        lenient().when(partnerAppUserAccessService.getCurrentCompanyId()).thenReturn(null);
        RLock lock = mock(RLock.class);
        // 并发锁仅在额度相关场景使用,宽松桩避免严格模式下未使用即报错
        lenient().when(redissonClient.getLock(any())).thenReturn(lock);
@@ -371,6 +379,89 @@
        assertEquals("分配明细中存在重复白名单用户", exception.getMessage());
    }
    // ---------------- updateStatus ----------------
    @Test
    void updateStatusRejectsInvalidParams() {
        assertThrows(ServiceException.class, () -> service.updateStatus(null));
        AppUserWhitelistStatusDTO noId = new AppUserWhitelistStatusDTO();
        noId.setStatus(1);
        assertThrows(ServiceException.class, () -> service.updateStatus(noId));
        AppUserWhitelistStatusDTO badStatus = new AppUserWhitelistStatusDTO();
        badStatus.setId(1L);
        badStatus.setStatus(3);
        ServiceException exception = assertThrows(ServiceException.class, () -> service.updateStatus(badStatus));
        assertEquals("白名单用户状态参数错误", exception.getMessage());
        verify(mapper, never()).update(isNull(), any(Wrapper.class));
    }
    @Test
    void updateStatusRejectsMissingRecord() {
        when(mapper.selectById(1L)).thenReturn(null);
        AppUserWhitelistStatusDTO dto = new AppUserWhitelistStatusDTO();
        dto.setId(1L);
        dto.setStatus(2);
        ServiceException exception = assertThrows(ServiceException.class, () -> service.updateStatus(dto));
        assertEquals("白名单用户不存在或已删除", exception.getMessage());
        verify(mapper, never()).update(isNull(), any(Wrapper.class));
    }
    @Test
    void updateStatusKeepsUnchangedStatusWithoutUpdate() {
        TAppUserWhitelist existing = new TAppUserWhitelist();
        existing.setId(1L);
        existing.setStatus(1);
        when(mapper.selectById(1L)).thenReturn(existing);
        AppUserWhitelistStatusDTO dto = new AppUserWhitelistStatusDTO();
        dto.setId(1L);
        dto.setStatus(1);
        assertTrue(service.updateStatus(dto));
        // 状态未变化时视为幂等成功,不产生更新语句,避免污染 update_time / update_by
        verify(mapper, never()).update(isNull(), any(Wrapper.class));
    }
    @Test
    void updateStatusDisablesWhitelist() {
        TAppUserWhitelist existing = new TAppUserWhitelist();
        existing.setId(1L);
        existing.setStatus(1);
        when(mapper.selectById(1L)).thenReturn(existing);
        when(mapper.update(isNull(), any(Wrapper.class))).thenReturn(1);
        AppUserWhitelistStatusDTO dto = new AppUserWhitelistStatusDTO();
        dto.setId(1L);
        dto.setStatus(2);
        assertTrue(service.updateStatus(dto));
        ArgumentCaptor<Wrapper> wrapperCaptor = ArgumentCaptor.forClass(Wrapper.class);
        verify(mapper).update(isNull(), wrapperCaptor.capture());
        String sqlSet = wrapperCaptor.getValue().getSqlSet();
        assertTrue(sqlSet.contains("status"));
        assertTrue(sqlSet.contains("update_time"));
    }
    @Test
    void updateStatusThrowsWhenUpdateAffectsNoRow() {
        TAppUserWhitelist existing = new TAppUserWhitelist();
        existing.setId(1L);
        existing.setStatus(1);
        when(mapper.selectById(1L)).thenReturn(existing);
        when(mapper.update(isNull(), any(Wrapper.class))).thenReturn(0);
        AppUserWhitelistStatusDTO dto = new AppUserWhitelistStatusDTO();
        dto.setId(1L);
        dto.setStatus(2);
        ServiceException exception = assertThrows(ServiceException.class, () -> service.updateStatus(dto));
        assertEquals("白名单用户状态更新失败,请重试", exception.getMessage());
    }
    private TGroupCompany allocationCompany(Integer id, String name) {
        TGroupCompany company = new TGroupCompany();
        company.setId(id);
@@ -428,4 +519,42 @@
        row.createCell(1).setCellValue(benefitType);
        row.createCell(2).setCellValue(whitelistSite);
    }
    // ==================== 公司账号数据隔离 ====================
    @Test
    void getAllocateOverviewForcesCompanyFilterForCompanyAccount() {
        // 公司账号:额度概览的公司参数被强制覆盖为本公司
        when(partnerAppUserAccessService.resolveCompanyFilter(9)).thenReturn(2);
        TGroupCompany company = new TGroupCompany();
        company.setId(2);
        company.setName("本公司");
        company.setAccountMode(2);
        company.setAvailableBalance(new BigDecimal("100.00"));
        when(groupCompanyClient.getCompanyById(2)).thenReturn(R.ok(company));
        AppUserWhitelistAllocateVO vo = service.getAllocateOverview(9);
        assertEquals(Integer.valueOf(2), vo.getCompanyId());
        verify(groupCompanyClient).getCompanyById(2);
    }
    @Test
    void updateStatusRejectsCrossCompanyRecord() {
        // 公司账号:启停其他公司的白名单被越权校验拦截
        TAppUserWhitelist existing = new TAppUserWhitelist();
        existing.setId(1L);
        existing.setStatus(1);
        existing.setCompanyId(9);
        when(mapper.selectById(1L)).thenReturn(existing);
        doThrow(new ServiceException("无权操作其他公司的数据")).when(partnerAppUserAccessService).assertCompanyVisible(9);
        AppUserWhitelistStatusDTO dto = new AppUserWhitelistStatusDTO();
        dto.setId(1L);
        dto.setStatus(2);
        ServiceException exception = assertThrows(ServiceException.class, () -> service.updateStatus(dto));
        assertEquals("无权操作其他公司的数据", exception.getMessage());
        verify(mapper, never()).update(isNull(), any(Wrapper.class));
    }
}