package jnpf.dmsMapper;
|
|
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
|
import org.apache.ibatis.io.Resources;
|
import org.apache.ibatis.mapping.MappedStatement;
|
import org.apache.ibatis.mapping.ResultMapping;
|
import org.apache.ibatis.session.Configuration;
|
import org.junit.jupiter.api.Test;
|
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.Reader;
|
import java.util.Arrays;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
class DmsWenjianBanbenMapperXmlTest {
|
|
private static final List<String> MAPPERS = Arrays.asList(
|
"DmsWenjianZiyuanMapper",
|
"DmsWenjianBanbenMapper",
|
"DmsWenjianGuanxiMapper",
|
"DmsWenjianXinzengShenheMapper",
|
"DmsWenjianXinzengShenheJiluMingxiMapper",
|
"DmsWenjianXiudingShenqingMapper",
|
"DmsWenjianXiudingShenqingZixiangMapper",
|
"DmsWenjianXiudingShenheMapper",
|
"DmsXiudingKanwuMapper",
|
"DmsWenjianXiudingShenheJiluMingxiMapper",
|
"DmsWenjianGuanlianMingxiMapper",
|
"DmsWenjianXiazaiShenqingMapper",
|
"DmsWenjianXiazaiShenqingDetailMapper",
|
"DmsWenjianDayinShenqingMapper",
|
"DmsWenjianDayinShenqingDetailMapper");
|
|
@Test
|
void allVersionMappersParseAndAvoidSelectStar() throws IOException {
|
for (String mapper : MAPPERS) {
|
String resource = resource(mapper);
|
String xml;
|
try (Reader reader = Resources.getResourceAsReader(resource)) {
|
xml = read(reader);
|
}
|
assertFalse(xml.toUpperCase().contains("SELECT *"), resource);
|
parse(resource);
|
}
|
}
|
|
@Test
|
void flowAndVersionFieldsHaveExplicitMappings() throws IOException {
|
Configuration newAudit = parse(resource("DmsWenjianXinzengShenheMapper"));
|
assertMapping(newAudit,
|
DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"f_flow_state", "flowState");
|
assertMapping(newAudit,
|
DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"shengxiao_wenjian_banben_id", "shengxiaoWenjianBanbenId");
|
assertMapping(newAudit,
|
DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"shifou_peixun", "shifouPeixun");
|
assertMapping(newAudit,
|
DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"peixun_wancheng_riqi", "peixunWanchengRiqi");
|
assertTrue(newAudit.getMappedStatement(
|
DmsWenjianXinzengShenheMapper.class.getName() + ".selectByFlowForUpdate")
|
.getBoundSql(null).getSql().contains("peixun_wancheng_riqi"));
|
|
Configuration version = parse(resource("DmsWenjianBanbenMapper"));
|
assertMapping(version,
|
DmsWenjianBanbenMapper.class.getName() + ".selectCurrentByFileId",
|
"yuan_wenjian_banben_id", "yuanWenjianBanbenId");
|
assertMapping(version,
|
DmsWenjianBanbenMapper.class.getName() + ".selectById",
|
"bei_tidai_yuanyin", "beiTidaiYuanyin");
|
|
Configuration file = parse(resource("DmsWenjianZiyuanMapper"));
|
assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate",
|
"youxiao_qi_zhi", "youxiaoQiZhi");
|
assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate",
|
"fushen_riqi", "fushenRiqi");
|
assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate",
|
"fushen_shenqing_id", "fushenShenqingId");
|
assertMapping(file, DmsWenjianZiyuanMapper.class.getName() + ".selectByIdForUpdate",
|
"jinyong_laiyuan", "jinyongLaiyuan");
|
|
Configuration revisionAudit = parse(resource("DmsWenjianXiudingShenheMapper"));
|
assertMapping(revisionAudit,
|
DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"xiuding_shenqing_zixiang_id", "xiudingShenqingZixiangId");
|
assertMapping(revisionAudit,
|
DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"shifou_peixun", "shifouPeixun");
|
assertMapping(revisionAudit,
|
DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate",
|
"peixun_wancheng_riqi", "peixunWanchengRiqi");
|
assertTrue(revisionAudit.getMappedStatement(
|
DmsWenjianXiudingShenheMapper.class.getName() + ".selectByFlowForUpdate")
|
.getBoundSql(null).getSql().contains("peixun_wancheng_riqi"));
|
|
Configuration revisionDetail = parse(resource("DmsWenjianXiudingShenqingZixiangMapper"));
|
assertMapping(revisionDetail,
|
DmsWenjianXiudingShenqingZixiangMapper.class.getName() + ".selectByIdForUpdate",
|
"yuan_wenjian_banben_id", "yuanWenjianBanbenId");
|
}
|
|
@Test
|
void resourceAdvanceChecksExpectedVersionId() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianZiyuanMapper"));
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsWenjianZiyuanMapper.class.getName() + ".advanceCurrentVersion");
|
String sql = statement.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(sql.contains("dangqian_banben_id = ?"));
|
assertTrue(sql.contains("biz_status = 'effective'"));
|
}
|
|
@Test
|
void reviewMetadataDoesNotOverwriteTheCenterProjectedDeadline() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianZiyuanMapper"));
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsWenjianZiyuanMapper.class.getName() + ".updateReviewExtension");
|
Map<String, Object> params = new HashMap<>();
|
params.put("wenjianId", "file-1");
|
params.put("yanqiZhi", new java.util.Date());
|
params.put("fushenShenqingId", "application-1");
|
params.put("fushenRiqi", "2026-09-14 12:30:45");
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ");
|
org.junit.jupiter.api.Assertions.assertFalse(sql.contains("youxiao_qi_zhi = ?"));
|
assertTrue(sql.contains("fushen_shenqing_id = ?"));
|
assertTrue(sql.contains("fushen_riqi = ?"));
|
assertTrue(sql.contains("f_id = ?"));
|
assertTrue(sql.contains("f_delete_mark IS NULL"));
|
}
|
|
@Test
|
void resourceFileVersionLookupUsesActiveResource() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianZiyuanMapper"));
|
MappedStatement statement = configuration.getMappedStatement(
|
DmsWenjianZiyuanMapper.class.getName() + ".selectFileVersionIdByWenjianId");
|
Map<String, Object> params = new HashMap<>();
|
params.put("wenjianId", "file-1");
|
String sql = statement.getBoundSql(params).getSql().replaceAll("\\s+", " ");
|
assertTrue(sql.contains("SELECT wenjian_zhongxin_banben_id"));
|
assertTrue(sql.contains("f_id = ?"));
|
assertTrue(sql.contains("f_delete_mark IS NULL"));
|
}
|
|
@Test
|
void reservedNumberLookupsIncludeDeletedResources() throws IOException {
|
Configuration configuration = parse(resource("DmsWenjianZiyuanMapper"));
|
for (String method : Arrays.asList("selectByNumberForUpdate", "selectByNumberDetailForUpdate")) {
|
String sql = configuration.getMappedStatement(
|
DmsWenjianZiyuanMapper.class.getName() + "." + method)
|
.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(sql.contains("f_tenant_id = ?"));
|
assertTrue(sql.contains("FOR UPDATE"));
|
assertFalse(sql.contains("f_delete_mark IS NULL"));
|
}
|
}
|
|
@Test
|
void workflowDownloadLookupsLockOnlyActiveTenantRows() throws IOException {
|
Configuration resources = parse(resource("DmsWenjianZiyuanMapper"));
|
for (String method : Arrays.asList(
|
"selectActiveByNumberForUpdate", "selectActiveByNumberDetailForUpdate")) {
|
String sql = resources.getMappedStatement(
|
DmsWenjianZiyuanMapper.class.getName() + "." + method)
|
.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(sql.contains("f_tenant_id = ?"));
|
assertTrue(sql.contains("f_delete_mark IS NULL"));
|
assertTrue(sql.contains("FOR UPDATE"));
|
}
|
|
Configuration requests = parse(resource("DmsWenjianXiazaiShenqingMapper"));
|
String requestSql = requests.getMappedStatement(
|
DmsWenjianXiazaiShenqingMapper.class.getName() + ".selectByFlowForUpdate")
|
.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(requestSql.contains("f_tenant_id = ?"));
|
assertTrue(requestSql.contains("f_delete_mark IS NULL"));
|
assertTrue(requestSql.contains("FOR UPDATE"));
|
|
Configuration details = parse(resource("DmsWenjianXiazaiShenqingDetailMapper"));
|
String detailSql = details.getMappedStatement(
|
DmsWenjianXiazaiShenqingDetailMapper.class.getName()
|
+ ".selectByRequestForUpdate")
|
.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(detailSql.contains("f_tenant_id = ?"));
|
assertTrue(detailSql.contains("f_delete_mark IS NULL"));
|
assertTrue(detailSql.contains("FOR UPDATE"));
|
|
Configuration printRequests = parse(resource("DmsWenjianDayinShenqingMapper"));
|
String printRequestSql = printRequests.getMappedStatement(
|
DmsWenjianDayinShenqingMapper.class.getName() + ".selectByFlowForUpdate")
|
.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(printRequestSql.contains("f_tenant_id = ?"));
|
assertTrue(printRequestSql.contains("f_delete_mark IS NULL"));
|
assertTrue(printRequestSql.contains("FOR UPDATE"));
|
|
Configuration printDetails = parse(resource("DmsWenjianDayinShenqingDetailMapper"));
|
String printDetailSql = printDetails.getMappedStatement(
|
DmsWenjianDayinShenqingDetailMapper.class.getName()
|
+ ".selectByRequestForUpdate")
|
.getBoundSql(null).getSql().replaceAll("\\s+", " ");
|
assertTrue(printDetailSql.contains("f_tenant_id = ?"));
|
assertTrue(printDetailSql.contains("f_delete_mark IS NULL"));
|
assertTrue(printDetailSql.contains("FOR UPDATE"));
|
}
|
|
private Configuration parse(String resource) throws IOException {
|
Configuration configuration = new Configuration();
|
try (InputStream input = Resources.getResourceAsStream(resource)) {
|
XMLMapperBuilder builder = new XMLMapperBuilder(
|
input, configuration, resource, configuration.getSqlFragments());
|
builder.parse();
|
}
|
return configuration;
|
}
|
|
private void assertMapping(Configuration configuration, String statementId,
|
String column, String property) {
|
MappedStatement statement = configuration.getMappedStatement(statementId);
|
boolean mapped = statement.getResultMaps().stream()
|
.flatMap(resultMap -> resultMap.getResultMappings().stream())
|
.anyMatch(mapping -> matches(mapping, column, property));
|
assertTrue(mapped, column + " must map explicitly to " + property);
|
}
|
|
private boolean matches(ResultMapping mapping, String column, String property) {
|
return column.equals(mapping.getColumn()) && property.equals(mapping.getProperty());
|
}
|
|
private String read(Reader reader) throws IOException {
|
StringBuilder result = new StringBuilder();
|
char[] buffer = new char[2048];
|
int length;
|
while ((length = reader.read(buffer)) >= 0) {
|
result.append(buffer, 0, length);
|
}
|
return result.toString();
|
}
|
|
private String resource(String mapper) {
|
return "mapper/" + mapper + ".xml";
|
}
|
}
|