package jnpf.dmsMapper; import jnpf.dmsEntity.fenfa.DmsWenjianChongdaFasong; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.session.*; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.junit.jupiter.api.*; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; import java.sql.*; import java.util.Date; import java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.*; /** 生产Mapper及迁移在连接内临时表验证;不写public业务表,关闭连接自动销毁。 */ @EnabledIfEnvironmentVariable(named="DMS_LEDGER_TEST_JDBC_URL", matches=".+") class DmsWenjianChongdaMapperPostgresTest { Connection connection; SqlSession session; DmsWenjianChongdaMapper mapper; @BeforeEach void setup() throws Exception { connection=DriverManager.getConnection(System.getenv("DMS_LEDGER_TEST_JDBC_URL"),System.getenv("DMS_LEDGER_TEST_DB_USER"),System.getenv("DMS_LEDGER_TEST_DB_PASSWORD")); connection.setAutoCommit(false); try(var s=connection.createStatement()) { s.execute("SET LOCAL search_path TO pg_temp"); s.execute("CREATE TEMP TABLE dms_wenjian_bupingheng_dengji(f_id varchar(64),f_tenant_id varchar(64),f_delete_mark integer,zhixing_shijian timestamp,f_version integer)"); s.execute("CREATE TEMP TABLE lims_sign(f_id text,f_tenant_id text,f_creator_user_id text,f_delete_mark integer,meta_data text)"); try(var input=getClass().getResourceAsStream("/forms/original-serial-reprint/schema.sql")) { String schema=new String(input.readAllBytes(),StandardCharsets.UTF_8).replace("CREATE TABLE IF NOT EXISTS dms_wenjian_chongda_fasong", "CREATE TEMP TABLE IF NOT EXISTS dms_wenjian_chongda_fasong"); s.execute(schema); } } Configuration c=new Configuration(); c.setEnvironment(new Environment("test",new JdbcTransactionFactory(),new org.apache.ibatis.datasource.unpooled.UnpooledDataSource())); try(var xml=getClass().getResourceAsStream("/mapper/DmsWenjianChongdaMapper.xml")) { new XMLMapperBuilder(xml,c,"mapper/DmsWenjianChongdaMapper.xml",c.getSqlFragments()).parse(); } session=new SqlSessionFactoryBuilder().build(c).openSession(connection);mapper=session.getMapper(DmsWenjianChongdaMapper.class); } @AfterEach void cleanup() throws Exception { if(connection!=null&&!connection.isClosed()) connection.rollback();if(session!=null)session.close();if(connection!=null)connection.close(); } DmsWenjianChongdaFasong attempt(String id) { var a=new DmsWenjianChongdaFasong();a.setId(id);a.setTenantId("test");a.setPrintRecordId("copy");a.setTaskId("task");a.setFileVersionId("version");a.setUserId("actor");a.setCopies(1);a.setState("OPEN");a.setBatchesJson("[]");a.setNumbersJson("[{\"serialNumber\":\"original\"}]");a.setReason("reason");a.setBizSign("sign-"+id);a.setCreatedAt(new Date());return a; } @Test void persistsAndMapsFrozenAttemptThenCompletesNativeDocument() throws Exception { var a=attempt("request");assertEquals(1,mapper.insertAttempt(a)); var read=mapper.selectActive("test","copy");assertEquals("actor",read.getUserId());assertEquals(a.getNumbersJson(),read.getNumbersJson());assertEquals(1,read.getCopies()); try(var s=connection.createStatement()) {s.execute("INSERT INTO dms_wenjian_bupingheng_dengji(f_id,f_tenant_id,chongda_fasong_id) VALUES ('doc','test','request')");} a.setSubmittedAt(new Date());a.setDocumentId(mapper.findDocument("test","request").getDocumentId()); assertEquals(1,mapper.completeDocument(a));assertEquals(0,mapper.completeDocument(a));a.setState("CLOSED");assertEquals(1,mapper.updateAttempt(a)); assertNull(mapper.selectActive("test","copy"));assertEquals("doc",mapper.selectAttempt("test","request").getDocumentId()); assertEquals(1,mapper.insertAttempt(attempt("request2"))); } @Test void cancellationPersistsAndReleasesActiveSlot() { var a=attempt("cancelled");mapper.insertAttempt(a);a.setPageCount(8);a.setState("CANCELLED");a.setCancelledAt(new Date());mapper.updateAttempt(a); var read=mapper.selectAttempt("test","cancelled");assertEquals(8,read.getPageCount());assertNotNull(read.getCancelledAt());assertNull(mapper.selectActive("test","copy")); assertEquals(1,mapper.insertAttempt(attempt("next"))); } @Test void activeAttemptUniquenessRejectsParallelRequests() {mapper.insertAttempt(attempt("one"));assertThrows(Exception.class,()->mapper.insertAttempt(attempt("two")));} @Test void nativeAssociationRemainsUniqueAfterSoftDelete() throws Exception { try(var s=connection.createStatement()) { s.execute("INSERT INTO dms_wenjian_bupingheng_dengji(f_id,f_tenant_id,chongda_fasong_id,f_delete_mark) VALUES ('deleted','test','request',1)"); assertThrows(SQLException.class,()->s.execute("INSERT INTO dms_wenjian_bupingheng_dengji(f_id,f_tenant_id,chongda_fasong_id) VALUES ('second','test','request')")); } } @Test void signatureBindsActorRequestCopyReasonAndMeasure() throws Exception { String data="{\"biz_form_id\":\"37a318b30d7c4daf9670d141b33ed1b7\",\"biz_data\":[{\"chongda_fasong_id\":\"request\",\"bupingheng_mingxi\":[{\"dayin_jilu_id\":\"copy\",\"cuoshi\":\"cuoshi3\",\"yuanyin\":\" reason \"}]}]}"; try(var s=connection.prepareStatement("INSERT INTO lims_sign VALUES ('sign','test','actor',NULL,?)")) {s.setString(1,data);s.executeUpdate();} assertNotNull(mapper.validSignature("test","actor","sign","copy","request","reason")); assertNull(mapper.validSignature("test","other","sign","copy","request","reason")); assertNull(mapper.validSignature("test","actor","sign","copy","another","reason")); assertNull(mapper.validSignature("test","actor","sign","copy","request","changed")); assertNull(mapper.validSignature("test","actor","sign","other","request","reason")); } }