合并员工亲属资产后端实施
This commit is contained in:
@@ -2,7 +2,11 @@ package com.ruoyi.info.collection.controller;
|
||||
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.vo.AssetImportFailureVO;
|
||||
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
|
||||
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||
import com.ruoyi.info.collection.service.ICcdiAssetInfoImportService;
|
||||
import com.ruoyi.info.collection.utils.EasyExcelUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -13,8 +17,8 @@ import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -72,6 +76,44 @@ class CcdiAssetInfoControllerTest {
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("导入任务已提交,正在后台处理", result.get(AjaxResult.MSG_TAG));
|
||||
ImportResultVO data = (ImportResultVO) result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals("task-1", data.getTaskId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImportStatus_shouldDelegateToImportService() {
|
||||
ImportStatusVO statusVO = new ImportStatusVO();
|
||||
statusVO.setTaskId("task-2");
|
||||
when(assetInfoImportService.getImportStatus("task-2")).thenReturn(statusVO);
|
||||
|
||||
AjaxResult result = controller.getImportStatus("task-2");
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals(statusVO, result.get(AjaxResult.DATA_TAG));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImportFailures_shouldReturnPagedRows() {
|
||||
AssetImportFailureVO failure1 = new AssetImportFailureVO();
|
||||
failure1.setPersonId("A1");
|
||||
AssetImportFailureVO failure2 = new AssetImportFailureVO();
|
||||
failure2.setPersonId("A2");
|
||||
when(assetInfoImportService.getImportFailures("task-3")).thenReturn(List.of(failure1, failure2));
|
||||
|
||||
TableDataInfo result = controller.getImportFailures("task-3", 2, 1);
|
||||
|
||||
assertEquals(2, result.getTotal());
|
||||
assertEquals(1, result.getRows().size());
|
||||
assertEquals("A2", ((AssetImportFailureVO) result.getRows().get(0)).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importTemplate_shouldUseRelativeAssetTemplateName() {
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
controller.importTemplate(null);
|
||||
|
||||
mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(null, CcdiAssetInfoExcel.class, "亲属资产信息"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,37 +26,33 @@ class CcdiAssetInfoMapperTest {
|
||||
private static final String RESOURCE = "mapper/info/collection/CcdiAssetInfoMapper.xml";
|
||||
|
||||
@Test
|
||||
void selectByFamilyId_shouldFilterByFamilyId() throws Exception {
|
||||
void selectByFamilyIdAndPersonId_shouldFilterByOwnershipKey() throws Exception {
|
||||
MappedStatement mappedStatement = loadMappedStatement(
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.selectByFamilyId");
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.selectByFamilyIdAndPersonId");
|
||||
|
||||
String sql = renderSql(mappedStatement, Map.of("familyId", "320101199001010011"));
|
||||
String sql = renderSql(mappedStatement, Map.of(
|
||||
"familyId", "320101199001010011",
|
||||
"personId", "320101199201010022"
|
||||
));
|
||||
|
||||
assertTrue(sql.contains("FROM ccdi_asset_info"), sql);
|
||||
assertTrue(sql.contains("WHERE family_id = ?"), sql);
|
||||
assertTrue(sql.contains("AND person_id = ?"), sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectByPersonId_shouldFilterByPersonId() throws Exception {
|
||||
void deleteByFamilyIdAndPersonId_shouldFilterByOwnershipKey() throws Exception {
|
||||
MappedStatement mappedStatement = loadMappedStatement(
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.selectByPersonId");
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.deleteByFamilyIdAndPersonId");
|
||||
|
||||
String sql = renderSql(mappedStatement, Map.of("personId", "320101199201010022"));
|
||||
|
||||
assertTrue(sql.contains("FROM ccdi_asset_info"), sql);
|
||||
assertTrue(sql.contains("WHERE person_id = ?"), sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteByFamilyIds_shouldRenderInClause() throws Exception {
|
||||
MappedStatement mappedStatement = loadMappedStatement(
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.deleteByFamilyIds");
|
||||
|
||||
String sql = renderSql(mappedStatement, Map.of("familyIds", List.of("A", "B")));
|
||||
String sql = renderSql(mappedStatement, Map.of(
|
||||
"familyId", "320101199001010011",
|
||||
"personId", "320101199201010022"
|
||||
));
|
||||
|
||||
assertTrue(sql.contains("DELETE FROM ccdi_asset_info"), sql);
|
||||
assertTrue(sql.contains("family_id IN"), sql);
|
||||
assertFalse(sql.contains("IN ()"), sql);
|
||||
assertTrue(sql.contains("WHERE family_id = ?"), sql);
|
||||
assertTrue(sql.contains("AND person_id = ?"), sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -84,23 +80,18 @@ class CcdiAssetInfoMapperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void ownerLookupQueries_shouldResolveFromEmployeeAndFamilyRelation() throws Exception {
|
||||
MappedStatement employeeStatement = loadMappedStatement(
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.selectOwnerByEmployeeIdCards");
|
||||
void ownerLookupQuery_shouldResolveFromFamilyRelationOnly() throws Exception {
|
||||
MappedStatement familyStatement = loadMappedStatement(
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.selectOwnerByFamilyRelationIdCards");
|
||||
"com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper.selectOwnerCandidatesByRelationCertNos");
|
||||
|
||||
String employeeSql = renderSql(employeeStatement, Map.of("personIds", List.of("A")));
|
||||
String familySql = renderSql(familyStatement, Map.of("personIds", List.of("B")));
|
||||
|
||||
assertTrue(employeeSql.contains("FROM ccdi_base_staff"), employeeSql);
|
||||
assertTrue(employeeSql.contains("id_card AS personId"), employeeSql);
|
||||
assertTrue(employeeSql.contains("id_card AS familyId"), employeeSql);
|
||||
String familySql = renderSql(familyStatement, Map.of("relationCertNos", List.of("B")));
|
||||
|
||||
assertTrue(familySql.contains("FROM ccdi_staff_fmy_relation"), familySql);
|
||||
assertTrue(familySql.contains("relation_cert_no AS personId"), familySql);
|
||||
assertTrue(familySql.contains("person_id AS familyId"), familySql);
|
||||
assertTrue(familySql.contains("relation_cert_no IN"), familySql);
|
||||
assertTrue(familySql.contains("is_emp_family = 1"), familySql);
|
||||
assertFalse(familySql.contains("FROM ccdi_base_staff"), familySql);
|
||||
}
|
||||
|
||||
private MappedStatement loadMappedStatement(String statementId) throws Exception {
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.ruoyi.info.collection.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.pagehelper.parser.defaults.DefaultCountSqlParser;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffFmyRelationQueryDTO;
|
||||
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.Environment;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||
import org.apache.ibatis.type.TypeAliasRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CcdiStaffFmyRelationMapperTest {
|
||||
|
||||
private static final String RESOURCE = "mapper/info/collection/CcdiStaffFmyRelationMapper.xml";
|
||||
|
||||
@Test
|
||||
void selectRelationPage_shouldRenderWhitespaceBeforeDynamicAndClause() throws Exception {
|
||||
MappedStatement mappedStatement = loadMappedStatement(
|
||||
"com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper.selectRelationPage");
|
||||
|
||||
CcdiStaffFmyRelationQueryDTO queryDTO = new CcdiStaffFmyRelationQueryDTO();
|
||||
queryDTO.setPersonId("320101199001010011");
|
||||
String sql = renderSql(mappedStatement, Map.of(
|
||||
"page", new Page<>(1, 10),
|
||||
"query", queryDTO
|
||||
));
|
||||
String countSql = normalizeSql(new DefaultCountSqlParser().getSmartCountSql(sql, "0"));
|
||||
|
||||
assertTrue(sql.contains("WHERE 1 = 1 AND r.is_emp_family = 1 AND r.person_id = ?"), sql);
|
||||
assertFalse(sql.contains("1AND"), sql);
|
||||
assertFalse(countSql.contains("1AND"), countSql);
|
||||
}
|
||||
|
||||
private MappedStatement loadMappedStatement(String statementId) throws Exception {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), new NoOpDataSource()));
|
||||
registerTypeAliases(configuration.getTypeAliasRegistry());
|
||||
configuration.getLanguageRegistry().register(XMLLanguageDriver.class);
|
||||
configuration.addMapper(CcdiStaffFmyRelationMapper.class);
|
||||
|
||||
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE)) {
|
||||
XMLMapperBuilder xmlMapperBuilder =
|
||||
new XMLMapperBuilder(inputStream, configuration, RESOURCE, configuration.getSqlFragments());
|
||||
xmlMapperBuilder.parse();
|
||||
}
|
||||
return configuration.getMappedStatement(statementId);
|
||||
}
|
||||
|
||||
private String renderSql(MappedStatement mappedStatement, Map<String, Object> params) {
|
||||
BoundSql boundSql = mappedStatement.getBoundSql(new HashMap<>(params));
|
||||
return normalizeSql(boundSql.getSql());
|
||||
}
|
||||
|
||||
private String normalizeSql(String sql) {
|
||||
return sql.replaceAll("\\s+", " ").trim();
|
||||
}
|
||||
|
||||
private void registerTypeAliases(TypeAliasRegistry typeAliasRegistry) {
|
||||
typeAliasRegistry.registerAlias("map", Map.class);
|
||||
}
|
||||
|
||||
private static class NoOpDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public java.sql.Connection getConnection() {
|
||||
throw new UnsupportedOperationException("Not required for SQL rendering tests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.sql.Connection getConnection(String username, String password) {
|
||||
throw new UnsupportedOperationException("Not required for SQL rendering tests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.io.PrintWriter getLogWriter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(java.io.PrintWriter out) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoginTimeout(int seconds) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoginTimeout() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.logging.Logger getParentLogger() {
|
||||
return java.util.logging.Logger.getGlobal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiAssetInfoDTO;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CcdiAssetInfoDesignContractTest {
|
||||
|
||||
@Test
|
||||
void aggregateSaveDto_shouldNotExposePersonId() {
|
||||
Set<String> fieldNames = Arrays.stream(CcdiAssetInfoDTO.class.getDeclaredFields())
|
||||
.map(field -> field.getName())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
assertFalse(fieldNames.contains("personId"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldStillExposePersonIdForRelationCertNoMatching() {
|
||||
Set<String> fieldNames = Arrays.stream(CcdiAssetInfoExcel.class.getDeclaredFields())
|
||||
.map(field -> field.getName())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
assertTrue(fieldNames.contains("personId"));
|
||||
}
|
||||
}
|
||||
@@ -82,19 +82,17 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoAsync_shouldResolveFamilyIdFromEmployeeIdCard() {
|
||||
void importAssetInfoAsync_shouldResolveFamilyIdFromFamilyRelationForRelativeAsset() {
|
||||
CcdiAssetInfoExcel excel = buildExcel("320101199001010011", "房产");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(assetInfoMapper.selectOwnerByEmployeeIdCards(List.of("320101199001010011")))
|
||||
.thenReturn(List.of(owner("320101199001010011", "320101199001010011")));
|
||||
when(assetInfoMapper.selectOwnerByFamilyRelationIdCards(List.of("320101199001010011")))
|
||||
.thenReturn(List.of());
|
||||
when(assetInfoMapper.selectOwnerCandidatesByRelationCertNos(List.of("320101199001010011")))
|
||||
.thenReturn(List.of(owner("320101199001010011", "320101199009090099")));
|
||||
|
||||
service.importAssetInfoAsync(List.of(excel), "task-1", "tester");
|
||||
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(captor.capture());
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199009090099", captor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getPersonId());
|
||||
}
|
||||
|
||||
@@ -102,9 +100,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
void importAssetInfoAsync_shouldResolveFamilyIdFromFamilyRelationIdCard() {
|
||||
CcdiAssetInfoExcel excel = buildExcel("320101199201010022", "车辆");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(assetInfoMapper.selectOwnerByEmployeeIdCards(List.of("320101199201010022")))
|
||||
.thenReturn(List.of());
|
||||
when(assetInfoMapper.selectOwnerByFamilyRelationIdCards(List.of("320101199201010022")))
|
||||
when(assetInfoMapper.selectOwnerCandidatesByRelationCertNos(List.of("320101199201010022")))
|
||||
.thenReturn(List.of(owner("320101199201010022", "320101199001010011")));
|
||||
|
||||
service.importAssetInfoAsync(List.of(excel), "task-2", "tester");
|
||||
@@ -122,17 +118,15 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(assetInfoMapper.selectOwnerByEmployeeIdCards(List.of("320101199001010011", "320101199001010099")))
|
||||
.thenReturn(List.of(owner("320101199001010011", "320101199001010011")));
|
||||
when(assetInfoMapper.selectOwnerByFamilyRelationIdCards(List.of("320101199001010011", "320101199001010099")))
|
||||
.thenReturn(List.of());
|
||||
when(assetInfoMapper.selectOwnerCandidatesByRelationCertNos(List.of("320101199001010011", "320101199001010099")))
|
||||
.thenReturn(List.of(owner("320101199001010011", "320101199009090099")));
|
||||
|
||||
service.importAssetInfoAsync(List.of(good, bad), "task-3", "tester");
|
||||
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> insertCaptor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(insertCaptor.capture());
|
||||
assertEquals(1, insertCaptor.getValue().size());
|
||||
assertEquals("320101199001010011", insertCaptor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199009090099", insertCaptor.getValue().get(0).getFamilyId());
|
||||
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:assetInfo:task-3:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
@@ -140,7 +134,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
assertEquals(1, failures.size());
|
||||
AssetImportFailureVO failure = (AssetImportFailureVO) failures.get(0);
|
||||
assertEquals("320101199001010099", failure.getPersonId());
|
||||
assertTrue(failure.getErrorMessage().contains("未找到资产归属员工"));
|
||||
assertTrue(failure.getErrorMessage().contains("未找到亲属资产归属员工"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -148,13 +142,11 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
CcdiAssetInfoExcel excel = buildExcel("320101199201010022", "车辆");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(assetInfoMapper.selectOwnerByEmployeeIdCards(List.of("320101199201010022")))
|
||||
when(assetInfoMapper.selectOwnerCandidatesByRelationCertNos(List.of("320101199201010022")))
|
||||
.thenReturn(List.of(
|
||||
owner("320101199201010022", "320101199001010011"),
|
||||
owner("320101199201010022", "320101199001010033")
|
||||
));
|
||||
when(assetInfoMapper.selectOwnerByFamilyRelationIdCards(List.of("320101199201010022")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
service.importAssetInfoAsync(List.of(excel), "task-4", "tester");
|
||||
|
||||
@@ -162,7 +154,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:assetInfo:task-4:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
AssetImportFailureVO failure = (AssetImportFailureVO) ((List<?>) failureCaptor.getValue()).get(0);
|
||||
assertTrue(failure.getErrorMessage().contains("资产归属员工不唯一"));
|
||||
assertTrue(failure.getErrorMessage().contains("亲属资产归属员工不唯一"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,7 +175,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
));
|
||||
AssetImportFailureVO failureVO = new AssetImportFailureVO();
|
||||
failureVO.setPersonId("320101199001010099");
|
||||
failureVO.setErrorMessage("未找到资产归属员工");
|
||||
failureVO.setErrorMessage("未找到亲属资产归属员工");
|
||||
when(valueOperations.get("import:assetInfo:task-5:failures")).thenReturn(List.of(failureVO));
|
||||
|
||||
ImportStatusVO statusVO = service.getImportStatus("task-5");
|
||||
|
||||
@@ -6,18 +6,23 @@ import com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper;
|
||||
import com.ruoyi.info.collection.service.impl.CcdiAssetInfoServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.invocation.Invocation;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockingDetails;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -42,43 +47,64 @@ class CcdiAssetInfoServiceImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaceByFamilyId_shouldDeleteThenInsertNormalizedRows() {
|
||||
CcdiAssetInfoDTO selfOwnedAsset = buildDto("320101199001010011", "房产");
|
||||
CcdiAssetInfoDTO familyOwnedAsset = buildDto("320101199201010022", "车辆");
|
||||
void replaceByFamilyIdAndPersonId_shouldDeleteThenInsertNormalizedRows() throws Exception {
|
||||
CcdiAssetInfoDTO familyOwnedAsset = buildDto("房产");
|
||||
CcdiAssetInfoDTO anotherAsset = buildDto("车辆");
|
||||
|
||||
service.replaceByFamilyId("320101199001010011", List.of(selfOwnedAsset, familyOwnedAsset));
|
||||
Method method = CcdiAssetInfoServiceImpl.class.getMethod(
|
||||
"replaceByFamilyIdAndPersonId", String.class, String.class, List.class);
|
||||
method.invoke(service, "320101199001010011", "A123456789", List.of(familyOwnedAsset, anotherAsset));
|
||||
|
||||
verify(assetInfoMapper).deleteByFamilyId("320101199001010011");
|
||||
Invocation deleteInvocation = mockingDetails(assetInfoMapper).getInvocations().stream()
|
||||
.filter(invocation -> "deleteByFamilyIdAndPersonId".equals(invocation.getMethod().getName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
assertEquals("320101199001010011", deleteInvocation.getArguments()[0]);
|
||||
assertEquals("A123456789", deleteInvocation.getArguments()[1]);
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(captor.capture());
|
||||
|
||||
List<CcdiAssetInfo> savedList = captor.getValue();
|
||||
assertEquals(2, savedList.size());
|
||||
assertEquals("320101199001010011", savedList.get(0).getFamilyId());
|
||||
assertEquals("320101199001010011", savedList.get(0).getPersonId());
|
||||
assertEquals("A123456789", savedList.get(0).getPersonId());
|
||||
assertEquals("320101199001010011", savedList.get(1).getFamilyId());
|
||||
assertEquals("320101199201010022", savedList.get(1).getPersonId());
|
||||
assertEquals("A123456789", savedList.get(1).getPersonId());
|
||||
assertEquals("房产", savedList.get(0).getAssetMainType());
|
||||
assertEquals("车辆", savedList.get(1).getAssetMainType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaceByFamilyId_shouldIgnoreEmptyRows() {
|
||||
void replaceByFamilyIdAndPersonId_shouldIgnoreEmptyRows() throws Exception {
|
||||
CcdiAssetInfoDTO emptyRow = new CcdiAssetInfoDTO();
|
||||
|
||||
service.replaceByFamilyId("320101199001010011", List.of(emptyRow));
|
||||
Method method = CcdiAssetInfoServiceImpl.class.getMethod(
|
||||
"replaceByFamilyIdAndPersonId", String.class, String.class, List.class);
|
||||
method.invoke(service, "320101199001010011", "A123456789", List.of(emptyRow));
|
||||
|
||||
verify(assetInfoMapper).deleteByFamilyId("320101199001010011");
|
||||
Invocation deleteInvocation = mockingDetails(assetInfoMapper).getInvocations().stream()
|
||||
.filter(invocation -> "deleteByFamilyIdAndPersonId".equals(invocation.getMethod().getName()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
assertEquals("320101199001010011", deleteInvocation.getArguments()[0]);
|
||||
assertEquals("A123456789", deleteInvocation.getArguments()[1]);
|
||||
verify(assetInfoMapper, never()).insertBatch(anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteByFamilyId_shouldDelegateToMapper() {
|
||||
when(assetInfoMapper.deleteByFamilyId("320101199001010011")).thenReturn(1);
|
||||
void replaceByFamilyIdAndPersonId_shouldValidateRequiredFields() throws Exception {
|
||||
CcdiAssetInfoDTO invalid = new CcdiAssetInfoDTO();
|
||||
invalid.setAssetMainType("房产");
|
||||
invalid.setAssetSubType("商品房");
|
||||
invalid.setAssetName("测试房产");
|
||||
invalid.setAssetStatus("正常");
|
||||
|
||||
int result = service.deleteByFamilyId("320101199001010011");
|
||||
Method method = CcdiAssetInfoServiceImpl.class.getMethod(
|
||||
"replaceByFamilyIdAndPersonId", String.class, String.class, List.class);
|
||||
InvocationTargetException exception = assertThrows(InvocationTargetException.class,
|
||||
() -> method.invoke(service, "320101199001010011", "A123456789", List.of(invalid)));
|
||||
|
||||
assertEquals(1, result);
|
||||
assertEquals("当前估值不能为空", exception.getCause().getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,9 +118,8 @@ class CcdiAssetInfoServiceImplTest {
|
||||
verify(assetInfoMapper).deleteByFamilyIds(eq(familyIds));
|
||||
}
|
||||
|
||||
private CcdiAssetInfoDTO buildDto(String personId, String assetMainType) {
|
||||
private CcdiAssetInfoDTO buildDto(String assetMainType) {
|
||||
CcdiAssetInfoDTO dto = new CcdiAssetInfoDTO();
|
||||
dto.setPersonId(personId);
|
||||
dto.setAssetMainType(assetMainType);
|
||||
dto.setAssetSubType(assetMainType + "小类");
|
||||
dto.setAssetName(assetMainType + "名称");
|
||||
|
||||
@@ -56,8 +56,8 @@ class CcdiBaseStaffServiceImplTest {
|
||||
addDTO.setPhone("13812345678");
|
||||
addDTO.setStatus("0");
|
||||
addDTO.setAssetInfoList(List.of(
|
||||
buildAssetDto("320101199001010011", "房产"),
|
||||
buildAssetDto("320101199201010022", "车辆")
|
||||
buildAssetDto("房产"),
|
||||
buildAssetDto("车辆")
|
||||
));
|
||||
|
||||
when(baseStaffMapper.selectById(1001L)).thenReturn(null);
|
||||
@@ -71,8 +71,8 @@ class CcdiBaseStaffServiceImplTest {
|
||||
verify(assetInfoService).replaceByFamilyId(eq("320101199001010011"), captor.capture());
|
||||
List<CcdiAssetInfoDTO> savedAssets = captor.getValue();
|
||||
assertEquals(2, savedAssets.size());
|
||||
assertEquals("320101199001010011", savedAssets.get(0).getPersonId());
|
||||
assertEquals("320101199201010022", savedAssets.get(1).getPersonId());
|
||||
assertEquals("房产", savedAssets.get(0).getAssetMainType());
|
||||
assertEquals("车辆", savedAssets.get(1).getAssetMainType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,7 +88,7 @@ class CcdiBaseStaffServiceImplTest {
|
||||
editDTO.setIdCard("320101199001010011");
|
||||
editDTO.setPhone("13812345678");
|
||||
editDTO.setStatus("0");
|
||||
editDTO.setAssetInfoList(List.of(buildAssetDto("320101199201010022", "车辆")));
|
||||
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
||||
|
||||
when(baseStaffMapper.selectById(1001L)).thenReturn(existing);
|
||||
when(baseStaffMapper.selectCount(any())).thenReturn(0L);
|
||||
@@ -114,7 +114,7 @@ class CcdiBaseStaffServiceImplTest {
|
||||
editDTO.setIdCard("320101199001010011");
|
||||
editDTO.setPhone("13812345678");
|
||||
editDTO.setStatus("0");
|
||||
editDTO.setAssetInfoList(List.of(buildAssetDto("320101199201010022", "车辆")));
|
||||
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
||||
|
||||
when(baseStaffMapper.selectById(1001L)).thenReturn(existing);
|
||||
when(baseStaffMapper.selectCount(any())).thenReturn(0L);
|
||||
@@ -172,9 +172,8 @@ class CcdiBaseStaffServiceImplTest {
|
||||
verify(assetInfoService).deleteByFamilyIds(List.of("320101199001010011", "320101199001010022"));
|
||||
}
|
||||
|
||||
private CcdiAssetInfoDTO buildAssetDto(String personId, String assetMainType) {
|
||||
private CcdiAssetInfoDTO buildAssetDto(String assetMainType) {
|
||||
CcdiAssetInfoDTO dto = new CcdiAssetInfoDTO();
|
||||
dto.setPersonId(personId);
|
||||
dto.setAssetMainType(assetMainType);
|
||||
dto.setAssetSubType(assetMainType + "小类");
|
||||
dto.setAssetName(assetMainType + "名称");
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiAssetInfoDTO;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffFmyRelationAddDTO;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffFmyRelationEditDTO;
|
||||
import com.ruoyi.info.collection.domain.vo.CcdiAssetInfoVO;
|
||||
import com.ruoyi.info.collection.domain.vo.CcdiStaffFmyRelationVO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
class CcdiStaffFmyRelationAssetAggregationTest {
|
||||
|
||||
@Test
|
||||
void addDto_shouldExposeAssetInfoList() {
|
||||
CcdiStaffFmyRelationAddDTO addDTO = new CcdiStaffFmyRelationAddDTO();
|
||||
List<CcdiAssetInfoDTO> assetInfoList = List.of(new CcdiAssetInfoDTO());
|
||||
|
||||
addDTO.setAssetInfoList(assetInfoList);
|
||||
|
||||
assertSame(assetInfoList, addDTO.getAssetInfoList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void editDto_shouldExposeAssetInfoList() {
|
||||
CcdiStaffFmyRelationEditDTO editDTO = new CcdiStaffFmyRelationEditDTO();
|
||||
List<CcdiAssetInfoDTO> assetInfoList = List.of(new CcdiAssetInfoDTO());
|
||||
|
||||
editDTO.setAssetInfoList(assetInfoList);
|
||||
|
||||
assertSame(assetInfoList, editDTO.getAssetInfoList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void relationVo_shouldExposeAssetInfoList() {
|
||||
CcdiStaffFmyRelationVO relationVO = new CcdiStaffFmyRelationVO();
|
||||
List<CcdiAssetInfoVO> assetInfoList = List.of(new CcdiAssetInfoVO());
|
||||
|
||||
relationVO.setAssetInfoList(assetInfoList);
|
||||
|
||||
assertSame(assetInfoList, relationVO.getAssetInfoList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.info.collection.domain.CcdiAssetInfo;
|
||||
import com.ruoyi.info.collection.domain.CcdiStaffFmyRelation;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiAssetInfoDTO;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffFmyRelationAddDTO;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffFmyRelationEditDTO;
|
||||
import com.ruoyi.info.collection.domain.vo.CcdiStaffFmyRelationVO;
|
||||
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
|
||||
import com.ruoyi.info.collection.service.impl.CcdiStaffFmyRelationServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiStaffFmyRelationServiceImplTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiStaffFmyRelationServiceImpl service;
|
||||
|
||||
@Mock
|
||||
private CcdiStaffFmyRelationMapper relationMapper;
|
||||
|
||||
@Mock
|
||||
private ICcdiStaffFmyRelationImportService relationImportService;
|
||||
|
||||
@Mock
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Mock
|
||||
private ICcdiAssetInfoService assetInfoService;
|
||||
|
||||
@Test
|
||||
void selectRelationById_shouldAggregateAssetInfoList() {
|
||||
CcdiStaffFmyRelationVO relationVO = new CcdiStaffFmyRelationVO();
|
||||
relationVO.setId(10L);
|
||||
relationVO.setPersonId("320101199001010011");
|
||||
relationVO.setRelationCertNo("A123456789");
|
||||
CcdiAssetInfo assetInfo = new CcdiAssetInfo();
|
||||
assetInfo.setFamilyId("320101199001010011");
|
||||
assetInfo.setPersonId("A123456789");
|
||||
assetInfo.setAssetMainType("房产");
|
||||
|
||||
when(relationMapper.selectRelationById(10L)).thenReturn(relationVO);
|
||||
when(assetInfoService.selectByFamilyIdAndPersonId("320101199001010011", "A123456789"))
|
||||
.thenReturn(List.of(assetInfo));
|
||||
|
||||
CcdiStaffFmyRelationVO result = service.selectRelationById(10L);
|
||||
|
||||
assertNotNull(result.getAssetInfoList());
|
||||
assertEquals(1, result.getAssetInfoList().size());
|
||||
assertEquals("A123456789", result.getAssetInfoList().get(0).getPersonId());
|
||||
assertEquals("房产", result.getAssetInfoList().get(0).getAssetMainType());
|
||||
}
|
||||
|
||||
@Test
|
||||
void insertRelation_shouldSaveRelationThenReplaceRelativeAssets() {
|
||||
CcdiStaffFmyRelationAddDTO addDTO = new CcdiStaffFmyRelationAddDTO();
|
||||
addDTO.setPersonId("320101199001010011");
|
||||
addDTO.setRelationType("配偶");
|
||||
addDTO.setRelationName("李四");
|
||||
addDTO.setRelationCertType("护照");
|
||||
addDTO.setRelationCertNo("A123456789");
|
||||
addDTO.setAssetInfoList(List.of(buildAssetDto("房产")));
|
||||
|
||||
when(relationMapper.insert(any(CcdiStaffFmyRelation.class))).thenReturn(1);
|
||||
|
||||
int result = service.insertRelation(addDTO);
|
||||
|
||||
assertEquals(1, result);
|
||||
ArgumentCaptor<CcdiStaffFmyRelation> relationCaptor = ArgumentCaptor.forClass(CcdiStaffFmyRelation.class);
|
||||
verify(relationMapper).insert(relationCaptor.capture());
|
||||
assertEquals("MANUAL", relationCaptor.getValue().getDataSource());
|
||||
assertEquals(Boolean.TRUE, relationCaptor.getValue().getIsEmpFamily());
|
||||
assertEquals(Boolean.FALSE, relationCaptor.getValue().getIsCustFamily());
|
||||
verify(assetInfoService).replaceByFamilyIdAndPersonId("320101199001010011", "A123456789", addDTO.getAssetInfoList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateRelation_shouldRejectRelationCertChange() {
|
||||
CcdiStaffFmyRelation existing = new CcdiStaffFmyRelation();
|
||||
existing.setId(10L);
|
||||
existing.setRelationCertType("护照");
|
||||
existing.setRelationCertNo("A123456789");
|
||||
|
||||
CcdiStaffFmyRelationEditDTO editDTO = new CcdiStaffFmyRelationEditDTO();
|
||||
editDTO.setId(10L);
|
||||
editDTO.setPersonId("320101199001010011");
|
||||
editDTO.setRelationType("配偶");
|
||||
editDTO.setRelationName("李四");
|
||||
editDTO.setRelationCertType("身份证");
|
||||
editDTO.setRelationCertNo("A123456789");
|
||||
|
||||
when(relationMapper.selectById(10L)).thenReturn(existing);
|
||||
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> service.updateRelation(editDTO));
|
||||
|
||||
assertEquals("关系人证件类型/证件号码不允许修改", exception.getMessage());
|
||||
verify(relationMapper, never()).updateById(any(CcdiStaffFmyRelation.class));
|
||||
verify(assetInfoService, never()).replaceByFamilyIdAndPersonId(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateRelation_shouldRejectRelationCertNoChange() {
|
||||
CcdiStaffFmyRelation existing = new CcdiStaffFmyRelation();
|
||||
existing.setId(10L);
|
||||
existing.setRelationCertType("护照");
|
||||
existing.setRelationCertNo("A123456789");
|
||||
|
||||
CcdiStaffFmyRelationEditDTO editDTO = new CcdiStaffFmyRelationEditDTO();
|
||||
editDTO.setId(10L);
|
||||
editDTO.setPersonId("320101199001010011");
|
||||
editDTO.setRelationType("配偶");
|
||||
editDTO.setRelationName("李四");
|
||||
editDTO.setRelationCertType("护照");
|
||||
editDTO.setRelationCertNo("B987654321");
|
||||
|
||||
when(relationMapper.selectById(10L)).thenReturn(existing);
|
||||
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> service.updateRelation(editDTO));
|
||||
|
||||
assertEquals("关系人证件类型/证件号码不允许修改", exception.getMessage());
|
||||
verify(relationMapper, never()).updateById(any(CcdiStaffFmyRelation.class));
|
||||
verify(assetInfoService, never()).replaceByFamilyIdAndPersonId(any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateRelation_shouldReplaceAssetsByOwnershipKey() {
|
||||
CcdiStaffFmyRelation existing = new CcdiStaffFmyRelation();
|
||||
existing.setId(10L);
|
||||
existing.setRelationCertType("护照");
|
||||
existing.setRelationCertNo("A123456789");
|
||||
|
||||
CcdiStaffFmyRelationEditDTO editDTO = new CcdiStaffFmyRelationEditDTO();
|
||||
editDTO.setId(10L);
|
||||
editDTO.setPersonId("320101199001010011");
|
||||
editDTO.setRelationType("配偶");
|
||||
editDTO.setRelationName("李四");
|
||||
editDTO.setRelationCertType("护照");
|
||||
editDTO.setRelationCertNo("A123456789");
|
||||
editDTO.setAssetInfoList(List.of(buildAssetDto("车辆")));
|
||||
|
||||
when(relationMapper.selectById(10L)).thenReturn(existing);
|
||||
when(relationMapper.updateById(any(CcdiStaffFmyRelation.class))).thenReturn(1);
|
||||
|
||||
int result = service.updateRelation(editDTO);
|
||||
|
||||
assertEquals(1, result);
|
||||
verify(assetInfoService).replaceByFamilyIdAndPersonId("320101199001010011", "A123456789", editDTO.getAssetInfoList());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteRelationByIds_shouldDeleteRelativeAssetsBeforeDeletingRelations() {
|
||||
CcdiStaffFmyRelation relation1 = new CcdiStaffFmyRelation();
|
||||
relation1.setId(10L);
|
||||
relation1.setPersonId("320101199001010011");
|
||||
relation1.setRelationCertNo("A123456789");
|
||||
CcdiStaffFmyRelation relation2 = new CcdiStaffFmyRelation();
|
||||
relation2.setId(11L);
|
||||
relation2.setPersonId("320101199001010022");
|
||||
relation2.setRelationCertNo("B987654321");
|
||||
|
||||
when(relationMapper.selectBatchIds(List.of(10L, 11L))).thenReturn(List.of(relation1, relation2));
|
||||
when(relationMapper.deleteBatchIds(List.of(10L, 11L))).thenReturn(2);
|
||||
|
||||
int result = service.deleteRelationByIds(new Long[]{10L, 11L});
|
||||
|
||||
assertEquals(2, result);
|
||||
var order = inOrder(assetInfoService, relationMapper);
|
||||
order.verify(assetInfoService).deleteByFamilyIdAndPersonId("320101199001010011", "A123456789");
|
||||
order.verify(assetInfoService).deleteByFamilyIdAndPersonId("320101199001010022", "B987654321");
|
||||
order.verify(relationMapper).deleteBatchIds(List.of(10L, 11L));
|
||||
}
|
||||
|
||||
private CcdiAssetInfoDTO buildAssetDto(String assetMainType) {
|
||||
CcdiAssetInfoDTO dto = new CcdiAssetInfoDTO();
|
||||
dto.setAssetMainType(assetMainType);
|
||||
dto.setAssetSubType(assetMainType + "小类");
|
||||
dto.setAssetName(assetMainType + "名称");
|
||||
dto.setCurrentValue(new BigDecimal("100.00"));
|
||||
dto.setAssetStatus("正常");
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user