package jnpf.dmsMapper; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.session.*; import org.junit.jupiter.api.*; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.transaction.SpringManagedTransactionFactory; import org.springframework.jdbc.datasource.SingleConnectionDataSource; import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.sql.*; import java.util.*; import static org.junit.jupiter.api.Assertions.*; /** Real shared usage predicate and native picker; only session-private TEMP tables are written. */ @EnabledIfEnvironmentVariable(named="DMS_OCCUPANCY_TEST_URL",matches=".+") class DmsNumberUsagePostgresTest { private Connection connection; private SingleConnectionDataSource source; private SqlSessionTemplate sessions; private DmsWenjianBianhaoMapper mapper; private final String tenant="number-usage-"+UUID.randomUUID(); @BeforeEach void setup() throws Exception { connection=DriverManager.getConnection(System.getenv("DMS_OCCUPANCY_TEST_URL"), System.getenv("DMS_OCCUPANCY_TEST_USER"),System.getenv("DMS_OCCUPANCY_TEST_PASSWORD")); source=new SingleConnectionDataSource(connection,true); for(String table:List.of("dms_wenjian_bianhao","dms_wenjian_ziyuan","dms_wenjian_xinzeng_shenhe", "dms_documents","dms_wenjian_mingcheng_biangeng_shenqing")) { try(var statement=connection.createStatement()) { statement.execute("CREATE TEMP TABLE "+table+" AS SELECT * FROM public."+table+" WITH NO DATA"); } } Configuration config=new Configuration(new Environment("test",new SpringManagedTransactionFactory(),source)); for(String resource:List.of("mapper/BusinessFileOccupancyMapper.xml","mapper/DmsWenjianBianhaoMapper.xml")) { try(var in=getClass().getClassLoader().getResourceAsStream(resource)) { String xml=new String(Objects.requireNonNull(in).readAllBytes(),StandardCharsets.UTF_8).replace("public.","pg_temp."); new XMLMapperBuilder(new StringReader(xml),config,resource,config.getSqlFragments()).parse(); } } sessions=new SqlSessionTemplate(new SqlSessionFactoryBuilder().build(config)); mapper=sessions.getMapper(DmsWenjianBianhaoMapper.class); execute("INSERT INTO dms_wenjian_bianhao(f_id,f_tenant_id,wenjian_bianhao,biz_status) VALUES ('number',?,'N-001','using')",tenant); } @AfterEach void close() throws Exception {if(source!=null)source.destroy();else if(connection!=null)connection.close();} private void execute(String sql,Object...values) throws SQLException { try(var p=connection.prepareStatement(sql)){for(int i=0;i candidates(String id) { return sessions.selectList(DmsWenjianBianhaoMapper.class.getName()+".selectNameChangeAvailablePage", Map.of("tenantId",tenant,"bianhaoId",id,"keyword","")); } @Test void unusedNumberIsAvailableButSavedReviewDraftBlocksEvenExactIdLookup() throws Exception { assertFalse(mapper.numberAlreadyUsed(tenant,"number"));assertEquals(1,candidates("").size()); execute("INSERT INTO dms_wenjian_xinzeng_shenhe(f_id,f_tenant_id,wenjian_bianhao_id,f_flow_state) VALUES ('draft',?,'number',0)",tenant); assertTrue(mapper.numberAlreadyUsed(tenant,"number"));assertTrue(candidates("").isEmpty());assertTrue(candidates("number").isEmpty()); } @Test void ExactNumberUseAlsoBlocksAndOtherTenantDoesNot() throws Exception { execute("INSERT INTO dms_wenjian_xinzeng_shenhe(f_id,f_tenant_id,wenjian_bianhao,f_flow_state) VALUES ('draft',?,'N-001',0)","other-tenant"); assertFalse(mapper.numberAlreadyUsed(tenant,"number")); execute("UPDATE dms_wenjian_xinzeng_shenhe SET f_tenant_id=?",tenant); assertTrue(mapper.numberAlreadyUsed(tenant,"number")); } @Test void historicalResourceStillCountsAsUsed() throws Exception { execute("INSERT INTO dms_wenjian_ziyuan(f_id,f_tenant_id,wenjian_bianhao,biz_status,f_delete_mark) VALUES ('file',?,'N-001','expired',1)",tenant); assertTrue(mapper.numberAlreadyUsed(tenant,"number"));assertTrue(candidates("").isEmpty()); } @Test void centerDocumentCountsAsUsed() throws Exception { execute("INSERT INTO dms_documents(id,tenant_id,document_no) VALUES (?::uuid,?,'N-001')",UUID.randomUUID().toString(),tenant); assertTrue(mapper.numberAlreadyUsed(tenant,"number"));assertTrue(candidates("").isEmpty()); } }