package cn.iocoder.yudao.module.crm.service.customer;
|
|
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.CrmCustomerImportExcelVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.CrmCustomerImportReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.customer.CrmCustomerPageReqVO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
|
import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
|
import cn.iocoder.yudao.module.crm.framework.excel.core.AutoPoolEnabledConvert;
|
import cn.iocoder.yudao.module.crm.framework.permission.core.aop.CrmPermissionAspect;
|
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
|
import cn.idev.excel.metadata.data.ReadCellData;
|
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import java.lang.reflect.Proxy;
|
import java.math.BigDecimal;
|
import java.util.List;
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
class CrmCustomerAutoPoolTest {
|
|
@Test
|
void excelReadsYesNoAndRejectsInvalidValues() {
|
var converter = new AutoPoolEnabledConvert();
|
assertTrue(converter.convertToJavaData(new ReadCellData<>("是"), null, null));
|
assertFalse(converter.convertToJavaData(new ReadCellData<>("否"), null, null));
|
assertFalse(converter.convertToJavaData(new ReadCellData<>(BigDecimal.ZERO), null, null));
|
assertNull(converter.convertToJavaData(new ReadCellData<>(" "), null, null));
|
assertThrows(IllegalArgumentException.class,
|
() -> converter.convertToJavaData(new ReadCellData<>("不确定"), null, null));
|
assertEquals("否", converter.convertToExcelData(false, null, null).getStringValue());
|
}
|
|
@Test
|
void oldTemplateCreatesCustomerWithAutoPoolEnabled() {
|
assertTrue(importCustomer(null, false).getAutoPoolEnabled());
|
}
|
|
@Test
|
void importingDisabledCustomerKeepsItDisabled() {
|
assertFalse(importCustomer(false, false).getAutoPoolEnabled());
|
}
|
|
@Test
|
void blankImportUpdateDoesNotOverwriteExistingSetting() {
|
// null 由 MyBatis 的非空更新策略忽略,不覆盖已有的 false。
|
assertNull(importCustomer(null, true).getAutoPoolEnabled());
|
}
|
|
@Test
|
void explicitImportUpdateCanDisableAutoPool() {
|
assertFalse(importCustomer(false, true).getAutoPoolEnabled());
|
}
|
|
@Test
|
void publicPoolListStillFiltersDisabledCustomersInAllScene() {
|
assertPoolListFilter(false);
|
}
|
|
@Test
|
void superAdminPoolListIncludesDisabledCustomers() {
|
assertPoolListFilter(true);
|
}
|
|
private void assertPoolListFilter(boolean superAdmin) {
|
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), "test"), CrmCustomerDO.class);
|
var mapper = CrmCustomerMapper.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(),
|
new Class<?>[]{CrmCustomerMapper.class}, (proxy, method, args) -> {
|
if (method.getName().equals("selectJoinPage")) {
|
var query = (com.github.yulichang.wrapper.MPJLambdaWrapper<?>) args[2];
|
String sql = query.getSqlSegment();
|
assertTrue(sql.contains("owner_user_id IS NULL"), sql);
|
assertEquals(!superAdmin, sql.contains("auto_pool_enabled ="), sql);
|
return new cn.iocoder.yudao.framework.common.pojo.PageResult<>(List.of(), 0L);
|
}
|
return java.lang.reflect.InvocationHandler.invokeDefault(proxy, method, args);
|
}));
|
mapper.selectPage(new CrmCustomerPageReqVO().setPool(true)
|
.setSceneType(CrmSceneTypeEnum.ALL.getType()), 1L, superAdmin);
|
}
|
|
@Test
|
void hiddenCustomerDoesNotGetPublicReadFallback() {
|
var aspect = new CrmPermissionAspect();
|
var enabled = new AtomicReference<>(false);
|
var mapper = CrmCustomerMapper.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(),
|
new Class<?>[]{CrmCustomerMapper.class}, (proxy, method, args) ->
|
new CrmCustomerDO().setId(1L).setAutoPoolEnabled(enabled.get())));
|
ReflectionTestUtils.setField(aspect, "customerMapper", mapper);
|
assertEquals(false, ReflectionTestUtils.invokeMethod(aspect, "isPublicPoolVisible",
|
CrmBizTypeEnum.CRM_CUSTOMER.getType(), 1L));
|
enabled.set(true);
|
assertEquals(true, ReflectionTestUtils.invokeMethod(aspect, "isPublicPoolVisible",
|
CrmBizTypeEnum.CRM_CUSTOMER.getType(), 1L));
|
}
|
|
@Test
|
void automaticPoolQueryRequiresEnabledFlagOutsideTimeoutOrConditions() {
|
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), "test"), CrmCustomerDO.class);
|
var captured = new AtomicReference<LambdaQueryWrapper<CrmCustomerDO>>();
|
var mapper = CrmCustomerMapper.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(),
|
new Class<?>[]{CrmCustomerMapper.class}, (proxy, method, args) -> {
|
if (method.isDefault()) {
|
return java.lang.reflect.InvocationHandler.invokeDefault(proxy, method, args);
|
}
|
assertEquals("selectList", method.getName());
|
captured.set((LambdaQueryWrapper<CrmCustomerDO>) args[0]);
|
return List.of();
|
}));
|
mapper.selectListByAutoPool(new CrmCustomerPoolConfigDO().setDealExpireDays(30).setContactExpireDays(7));
|
String sql = captured.get().getSqlSegment();
|
assertTrue(sql.contains("auto_pool_enabled ="), sql);
|
assertTrue(sql.indexOf("auto_pool_enabled") < sql.indexOf(" OR "), sql);
|
assertTrue(captured.get().getParamNameValuePairs().containsValue(true));
|
}
|
|
private CrmCustomerDO importCustomer(Boolean enabled, boolean existing) {
|
var service = new CrmCustomerServiceImpl();
|
var saved = new AtomicReference<CrmCustomerDO>();
|
var mapper = CrmCustomerMapper.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(),
|
new Class<?>[]{CrmCustomerMapper.class}, (proxy, method, args) -> switch (method.getName()) {
|
case "selectByCustomerName" -> existing
|
? new CrmCustomerDO().setId(1L).setAutoPoolEnabled(false) : null;
|
case "insert", "updateById" -> {
|
saved.set((CrmCustomerDO) args[0]);
|
yield 1;
|
}
|
default -> throw new AssertionError(method.getName());
|
}));
|
ReflectionTestUtils.setField(service, "customerMapper", mapper);
|
var result = service.importCustomerList(List.of(new CrmCustomerImportExcelVO()
|
.setName("测试客户").setAutoPoolEnabled(enabled)),
|
CrmCustomerImportReqVO.builder().updateSupport(true).build());
|
assertTrue(result.getFailureCustomerNames().isEmpty());
|
return saved.get();
|
}
|
}
|