package jnpf.dmsService; import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import jnpf.dmsEntity.DmsWenjianFushenYanqiShenqingEntity; import jnpf.dmsEntity.DmsWenjianFushenYanqiShenqingZixiangEntity; import jnpf.dmsEntity.storage.form.DmsFileExtendValidityForm; import jnpf.dmsMapper.DmsWenjianFushenYanqiShenqingMapper; import jnpf.dmsMapper.DmsWenjianFushenYanqiShenqingZixiangMapper; import jnpf.dmsMapper.DmsWenjianZiyuanMapper; import jnpf.dmsService.impl.DmsWenjianFushenYanqiShenqingTongguoServiceImpl; import jnpf.exception.DataException; import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.session.Configuration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.TimeZone; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class DmsWenjianFushenYanqiShenqingTongguoServiceTest { @BeforeEach void setUp() { initialize(DmsWenjianFushenYanqiShenqingEntity.class); initialize(DmsWenjianFushenYanqiShenqingZixiangEntity.class); } @Test void updatesEveryReferencedResourceForTheApprovedApplication() throws Exception { DmsWenjianFushenYanqiShenqingMapper shenqingMapper = mock(DmsWenjianFushenYanqiShenqingMapper.class); DmsWenjianFushenYanqiShenqingZixiangMapper zixiangMapper = mock(DmsWenjianFushenYanqiShenqingZixiangMapper.class); DmsWenjianZiyuanMapper ziyuanMapper = mock(DmsWenjianZiyuanMapper.class); DmsFileValidityService fileValidityService = mock(DmsFileValidityService.class); Date shenqingRiqi = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .parse("2026-09-14 12:30:45"); Date yanqiZhi1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .parse("2027-01-01 00:00:00"); Date yanqiZhi2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .parse("2027-02-01 00:00:00"); when(shenqingMapper.selectList(any())).thenReturn(Collections.singletonList(application(shenqingRiqi))); when(zixiangMapper.selectList(any())).thenReturn(Arrays.asList( detail("file-1", yanqiZhi1), detail("file-2", yanqiZhi2))); when(ziyuanMapper.selectFileVersionIdByWenjianId("file-1")) .thenReturn("018f0000-0000-7000-8000-000000000801"); when(ziyuanMapper.selectFileVersionIdByWenjianId("file-2")) .thenReturn("018f0000-0000-7000-8000-000000000802"); when(ziyuanMapper.updateReviewExtension(any(), any(), any(), any())).thenReturn(1); String applicationId = service(shenqingMapper, zixiangMapper, ziyuanMapper, fileValidityService) .tongguo("flow-1", "task-1"); assertEquals("apply-1", applicationId); verify(ziyuanMapper).updateReviewExtension( "file-1", yanqiZhi1, "apply-1", "2026-09-14 12:30:45"); verify(ziyuanMapper).updateReviewExtension( "file-2", yanqiZhi2, "apply-1", "2026-09-14 12:30:45"); ArgumentCaptor formCaptor = ArgumentCaptor.forClass(DmsFileExtendValidityForm.class); verify(fileValidityService).extendValidity(formCaptor.capture()); DmsFileExtendValidityForm form = formCaptor.getValue(); assertEquals("flow-1", form.getSourceId()); assertEquals("task-1", form.getTaskId()); assertEquals(2, form.getFiles().size()); assertEquals("018f0000-0000-7000-8000-000000000801", form.getFiles().get(0).getFileVersionId().toString()); assertEquals("018f0000-0000-7000-8000-000000000802", form.getFiles().get(1).getFileVersionId().toString()); SimpleDateFormat effectiveToFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); effectiveToFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); assertEquals("2027-01-02 00:00:00", effectiveToFormat.format(form.getFiles().get(0).getEffectiveTo())); assertEquals("2027-02-02 00:00:00", effectiveToFormat.format(form.getFiles().get(1).getEffectiveTo())); } @Test void rollsBackWhenAReferencedResourceCannotBeUpdated() throws Exception { DmsWenjianFushenYanqiShenqingMapper shenqingMapper = mock(DmsWenjianFushenYanqiShenqingMapper.class); DmsWenjianFushenYanqiShenqingZixiangMapper zixiangMapper = mock(DmsWenjianFushenYanqiShenqingZixiangMapper.class); DmsWenjianZiyuanMapper ziyuanMapper = mock(DmsWenjianZiyuanMapper.class); DmsFileValidityService fileValidityService = mock(DmsFileValidityService.class); when(shenqingMapper.selectList(any())).thenReturn(Collections.singletonList(application(new Date()))); when(zixiangMapper.selectList(any())).thenReturn(Collections.singletonList(detail("missing-file", new Date()))); when(ziyuanMapper.selectFileVersionIdByWenjianId("missing-file")) .thenReturn("018f0000-0000-7000-8000-000000000803"); when(ziyuanMapper.updateReviewExtension(any(), any(), any(), any())).thenReturn(0); DataException error = assertThrows(DataException.class, () -> service(shenqingMapper, zixiangMapper, ziyuanMapper, fileValidityService) .tongguo("flow-1", "task-1")); assertEquals("未找到可更新的文件资源:wenjian_id=missing-file", error.getMessage()); } @Test void rejectsAnUnknownApprovalFlow() { DmsWenjianFushenYanqiShenqingMapper shenqingMapper = mock(DmsWenjianFushenYanqiShenqingMapper.class); DmsWenjianFushenYanqiShenqingZixiangMapper zixiangMapper = mock(DmsWenjianFushenYanqiShenqingZixiangMapper.class); DmsWenjianZiyuanMapper ziyuanMapper = mock(DmsWenjianZiyuanMapper.class); DmsFileValidityService fileValidityService = mock(DmsFileValidityService.class); when(shenqingMapper.selectList(any())).thenReturn(Collections.emptyList()); DataException error = assertThrows(DataException.class, () -> service(shenqingMapper, zixiangMapper, ziyuanMapper, fileValidityService) .tongguo("flow-1", "task-1")); assertEquals("未找到文件复审延期申请:flow_id=flow-1, task_id=task-1", error.getMessage()); verify(zixiangMapper, never()).selectList(any()); verify(ziyuanMapper, never()).updateReviewExtension(any(), any(), any(), any()); verify(fileValidityService, never()).extendValidity(any()); } @Test void executesFrozenVersionAndReleasesAfterResourceProjection() throws Exception { var main=mock(DmsWenjianFushenYanqiShenqingMapper.class); var details=mock(DmsWenjianFushenYanqiShenqingZixiangMapper.class); var resources=mock(DmsWenjianZiyuanMapper.class); var validity=mock(DmsFileValidityService.class); var guard=mock(DmsBusinessLifecycleGuard.class); var receipt=new jnpf.dmsBusinessOccupancy.BusinessFileOccupancy(); receipt.setFileId("file-1");receipt.setCenterVersionId("018f0000-0000-7000-8000-000000000801"); var receipts=java.util.List.of(receipt); when(main.selectList(any())).thenReturn(java.util.List.of(application(new Date()))); when(details.selectList(any())).thenReturn(java.util.List.of(detail("file-1",new Date()))); when(guard.requireCurrentUserExtension("task-1","apply-1",java.util.List.of("file-1"))).thenReturn(receipts); when(resources.updateReviewExtension(any(),any(),any(),any())).thenReturn(1); var service=new DmsWenjianFushenYanqiShenqingTongguoServiceImpl(main,details,resources,validity,guard); service.tongguo("flow-1","task-1"); var capture=ArgumentCaptor.forClass(DmsFileExtendValidityForm.class); var order=org.mockito.Mockito.inOrder(validity,resources,guard); order.verify(validity).extendValidity(capture.capture()); assertEquals(receipt.getCenterVersionId(),capture.getValue().getFiles().get(0).getFileVersionId().toString()); order.verify(resources).updateReviewExtension(any(),any(),any(),any()); order.verify(guard).completeExecution(receipts); verify(resources,never()).selectFileVersionIdByWenjianId(any()); } private void initialize(Class entityClass) { if (TableInfoHelper.getTableInfo(entityClass) == null) { TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new Configuration(), ""), entityClass); } } private DmsWenjianFushenYanqiShenqingTongguoService service( DmsWenjianFushenYanqiShenqingMapper shenqingMapper, DmsWenjianFushenYanqiShenqingZixiangMapper zixiangMapper, DmsWenjianZiyuanMapper ziyuanMapper, DmsFileValidityService fileValidityService) { return new DmsWenjianFushenYanqiShenqingTongguoServiceImpl( shenqingMapper, zixiangMapper, ziyuanMapper, fileValidityService, new DmsBusinessLifecycleGuard(null,false)); } private DmsWenjianFushenYanqiShenqingEntity application(Date shenqingRiqi) { DmsWenjianFushenYanqiShenqingEntity application = new DmsWenjianFushenYanqiShenqingEntity(); application.setId("apply-1"); application.setFlowId("flow-1"); application.setFlowTaskId("task-1"); application.setShenqingRiqi(shenqingRiqi); return application; } private DmsWenjianFushenYanqiShenqingZixiangEntity detail(String wenjianId, Date yanqiZhi) { DmsWenjianFushenYanqiShenqingZixiangEntity detail = new DmsWenjianFushenYanqiShenqingZixiangEntity(); detail.setWenjianId(wenjianId); detail.setYanqiZhi(yanqiZhi); return detail; } }