package jnpf.dmsService; import jnpf.base.ActionResult; import jnpf.dms.DmsResourceApi; import jnpf.dmsEntity.DmsWenjianBanbenEntity; import jnpf.dmsEntity.fenfa.DmsWenjianDayinRenwuEntity; import jnpf.dmsEntity.print.DmsWenjianDayinShenqingDetailEntity; import jnpf.dmsEntity.print.DmsWenjianDayinShenqingEntity; import jnpf.dmsEntity.print.form.DmsWorkflowPrintFilesGrantForm; import jnpf.dmsEntity.print.vo.DmsWorkflowPrintFilesGrantResultVO; import jnpf.dmsMapper.DmsWenjianBanbenMapper; import jnpf.dmsMapper.DmsWenjianDayinShenqingDetailMapper; import jnpf.dmsMapper.DmsWenjianDayinShenqingMapper; import jnpf.dmsMapper.DmsWenjianFenfaMapper; import jnpf.exception.DataException; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class DmsWenjianFuzhuGuanliDayinServiceTest { private static final UUID DOCUMENT_ID = UUID.fromString("018f0000-0000-7000-8000-000000000901"); private static final UUID FILE_VERSION_ID = UUID.fromString("018f0000-0000-7000-8000-000000000902"); @Test void grantsPermanentPrintPermissionToTheApplicant() { Fixture fixture = new Fixture(); when(fixture.shenqingMapper.selectList(any())) .thenReturn(Collections.singletonList(application())); when(fixture.zixiangMapper.selectList(any())) .thenReturn(Arrays.asList( detail("version-1", "detail-1"), detail("version-1", "detail-2"))); when(fixture.banbenMapper.selectList(any())) .thenReturn(Collections.singletonList(banben("version-1"))); DmsWorkflowPrintFilesGrantResultVO expected = new DmsWorkflowPrintFilesGrantResultVO(1, 1); when(fixture.dmsResourceApi.grantWorkflowPrintFiles( eq("jnpf-flowable"), any())).thenReturn(ActionResult.success("success", expected)); DmsWorkflowPrintFilesGrantResultVO result = fixture.service.dayinWenjianShouquan( " flow-1 ", " task-1 "); assertSame(expected, result); ArgumentCaptor formCaptor = ArgumentCaptor.forClass(DmsWorkflowPrintFilesGrantForm.class); verify(fixture.dmsResourceApi).grantWorkflowPrintFiles( eq("jnpf-flowable"), formCaptor.capture()); DmsWorkflowPrintFilesGrantForm form = formCaptor.getValue(); assertEquals("applicant-1", form.getUserId()); assertEquals(1, form.getFiles().size()); assertEquals(DOCUMENT_ID, form.getFiles().get(0).getDocumentId()); assertEquals(FILE_VERSION_ID, form.getFiles().get(0).getFileVersionId()); assertNull(form.getFiles().get(0).getValidTo()); ArgumentCaptor taskCaptor = ArgumentCaptor.forClass(DmsWenjianDayinRenwuEntity.class); verify(fixture.fenfaMapper, times(2)).insertPrintTaskIfAbsent(taskCaptor.capture()); List tasks = taskCaptor.getAllValues(); assertEquals("wenjian_dayin", tasks.get(0).getLaiyuanLeixing()); assertEquals("application-1", tasks.get(0).getLaiyuanDanjuId()); assertEquals("detail-1", tasks.get(0).getLaiyuanMingxiId()); assertEquals("file-1", tasks.get(0).getWenjianId()); assertEquals("DOC-001", tasks.get(0).getWenjianBianhao()); assertEquals("质量文件", tasks.get(0).getWenjianMingcheng()); assertEquals("A(01)", tasks.get(0).getBanbenhao()); assertEquals(application().getFileAdministratorDate(), tasks.get(0).getShenheWanchengRiqi()); assertEquals("department-1", tasks.get(0).getJieshouBumenId()); assertEquals("[\"wenjian\"]", tasks.get(0).getWenjianLeibie()); assertEquals(2, tasks.get(0).getDayinFenshu()); assertEquals("daidayin", tasks.get(0).getBizStatus()); assertEquals("yes", tasks.get(0).getShifouShoukong()); assertEquals("applicant-1", tasks.get(0).getCreatorUserId()); assertEquals("detail-2", tasks.get(1).getLaiyuanMingxiId()); } @Test void rejectsPartialBusinessVersionMatchesBeforeCallingTheAuthorizationApi() { Fixture fixture = new Fixture(); when(fixture.shenqingMapper.selectList(any())) .thenReturn(Collections.singletonList(application())); when(fixture.zixiangMapper.selectList(any())) .thenReturn(Arrays.asList(detail("version-1"), detail("version-2"))); when(fixture.banbenMapper.selectList(any())) .thenReturn(Collections.singletonList(banben("version-1"))); assertThrows(DataException.class, () -> fixture.service.dayinWenjianShouquan("flow-1", "task-1")); verify(fixture.dmsResourceApi, never()).grantWorkflowPrintFiles(any(), any()); } @Test void validatesEveryQuantityBeforeGrantingOrWritingAnyTask() { for (String copies : Arrays.asList(null, "", "0", "-1", "1.5", "+1", "2147483648")) { Fixture fixture = new Fixture(); DmsWenjianDayinShenqingDetailEntity invalid = detail("version-1", "invalid"); invalid.setPrintCopies(copies); when(fixture.shenqingMapper.selectList(any())).thenReturn(List.of(application())); when(fixture.zixiangMapper.selectList(any())) .thenReturn(List.of(detail("version-1", "valid"), invalid)); when(fixture.banbenMapper.selectList(any())).thenReturn(List.of(banben("version-1"))); assertThrows(DataException.class, () -> fixture.service.dayinWenjianShouquan("flow-1", "task-1")); verify(fixture.dmsResourceApi, never()).grantWorkflowPrintFiles(any(), any()); verify(fixture.fenfaMapper, never()).insertPrintTaskIfAbsent(any()); } } @Test void missingVersionControlledFlagDoesNotSilentlyBecomeUncontrolled() { Fixture fixture = new Fixture(); DmsWenjianBanbenEntity version = banben("version-1"); version.setShifouShoukong(null); when(fixture.shenqingMapper.selectList(any())).thenReturn(List.of(application())); when(fixture.zixiangMapper.selectList(any())).thenReturn(List.of(detail("version-1"))); when(fixture.banbenMapper.selectList(any())).thenReturn(List.of(version)); assertThrows(DataException.class, () -> fixture.service.dayinWenjianShouquan("flow-1", "task-1")); verify(fixture.dmsResourceApi, never()).grantWorkflowPrintFiles(any(), any()); verify(fixture.fenfaMapper, never()).insertPrintTaskIfAbsent(any()); } @Test void rejectsMalformedFileCenterIdsBeforeCallingTheAuthorizationApi() { Fixture fixture = new Fixture(); DmsWenjianBanbenEntity malformed = banben("version-1"); malformed.setWenjianZhongxinBanbenId("not-a-uuid"); when(fixture.shenqingMapper.selectList(any())) .thenReturn(Collections.singletonList(application())); when(fixture.zixiangMapper.selectList(any())) .thenReturn(Collections.singletonList(detail("version-1"))); when(fixture.banbenMapper.selectList(any())) .thenReturn(Collections.singletonList(malformed)); assertThrows(DataException.class, () -> fixture.service.dayinWenjianShouquan("flow-1", "task-1")); verify(fixture.dmsResourceApi, never()).grantWorkflowPrintFiles(any(), any()); } private static DmsWenjianDayinShenqingEntity application() { DmsWenjianDayinShenqingEntity entity = new DmsWenjianDayinShenqingEntity(); entity.setId("application-1"); entity.setTenantId("tenant-1"); entity.setApplicantUserId(" applicant-1 "); entity.setShenqingrenBumen("department-1"); entity.setFileAdministratorDate(new Date(1_789_000_000_000L)); return entity; } private static DmsWenjianDayinShenqingDetailEntity detail(String banbenId) { return detail(banbenId, "detail-" + banbenId); } private static DmsWenjianDayinShenqingDetailEntity detail( String banbenId, String detailId) { DmsWenjianDayinShenqingDetailEntity entity = new DmsWenjianDayinShenqingDetailEntity(); entity.setId(detailId); entity.setBanbenId(banbenId); entity.setFileReferenceId("file-1"); entity.setFileNumber("DOC-001"); entity.setFileName("质量文件"); entity.setVersionLabel("A(01)"); entity.setEffectiveDate("2026-09-01 08:30:00"); entity.setReceivingDepartmentId("detail-department"); entity.setPrintCopies("2"); return entity; } private static DmsWenjianBanbenEntity banben(String banbenId) { DmsWenjianBanbenEntity entity = new DmsWenjianBanbenEntity(); entity.setId(banbenId); entity.setTenantId("tenant-1"); entity.setShifouShoukong("yes"); entity.setWenjianZhongxinWenjianId(DOCUMENT_ID.toString()); entity.setWenjianZhongxinBanbenId(FILE_VERSION_ID.toString()); return entity; } private static class Fixture { private final DmsWenjianDayinShenqingMapper shenqingMapper = mock(DmsWenjianDayinShenqingMapper.class); private final DmsWenjianDayinShenqingDetailMapper zixiangMapper = mock(DmsWenjianDayinShenqingDetailMapper.class); private final DmsWenjianBanbenMapper banbenMapper = mock(DmsWenjianBanbenMapper.class); private final DmsWenjianFenfaMapper fenfaMapper = mock(DmsWenjianFenfaMapper.class); private final DmsResourceApi dmsResourceApi = mock(DmsResourceApi.class); private final DmsWenjianFuzhuGuanliDayinService service = new DmsWenjianFuzhuGuanliDayinService( shenqingMapper, zixiangMapper, banbenMapper, fenfaMapper, mock(DmsWenjianDayinHaomaService.class), dmsResourceApi); } }