package jnpf.dmsService; import jnpf.dmsEntity.DmsWenjianBanbenEntity; import jnpf.dmsEntity.DmsWenjianZiyuanEntity; import jnpf.dmsEntity.permission.entity.DmsFilePermissionEntity; import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity; import jnpf.dmsEntity.print.DmsWenjianDayinShenqingDetailEntity; import jnpf.dmsEntity.print.DmsWenjianDayinShenqingEntity; import jnpf.dmsEntity.print.form.DmsWorkflowPrintAuthorizeForm; import jnpf.dmsEntity.print.vo.DmsWorkflowPrintAuthorizationVO; import jnpf.dmsMapper.DmsWenjianDayinShenqingDetailMapper; import jnpf.dmsMapper.DmsWenjianDayinShenqingMapper; import jnpf.exception.DataException; import jnpf.flowable.WorkFlowApi; import jnpf.flowable.entity.TaskEntity; import jnpf.flowable.enums.TaskStatusEnum; import org.junit.jupiter.api.Test; import java.util.Collections; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; 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.verify; import static org.mockito.Mockito.when; class DmsWorkflowPrintAuthorizationServiceTest { private static final String TENANT_ID = "tenant-1"; private static final String FLOW_ID = "flow-1"; private static final String TASK_ID = "task-1"; private static final String REQUEST_ID = "print-request-1"; private static final String DETAIL_ID = "print-detail-1"; private static final String APPLICANT_ID = "applicant-1"; private static final UUID DOCUMENT_ID = UUID.fromString("018f0000-0000-7000-8000-000000000811"); private static final UUID VERSION_ID = UUID.fromString("018f0000-0000-7000-8000-000000000812"); private static final UUID PERMISSION_ID = UUID.fromString("018f0000-0000-7000-8000-000000000813"); @Test void grantsPermanentPrintToMainRequestApplicantAndReturnsPrintMetadata() { Fixture fixture = new Fixture(); when(fixture.workFlowApi.getInfoSubmit(TASK_ID)).thenReturn(task(TaskStatusEnum.PASSED.getCode())); when(fixture.requestMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID)) .thenReturn(Collections.singletonList(request())); DmsWenjianDayinShenqingDetailEntity detail = detail("2"); detail.setPrinterUserId("different-printer"); when(fixture.detailMapper.selectByRequestForUpdate(TENANT_ID, REQUEST_ID)) .thenReturn(Collections.singletonList(detail)); when(fixture.fileResolutionService.resolve(TENANT_ID, DETAIL_ID, "file-ref-1", "QM-001", "质量手册", "V1.0")).thenReturn(resolved()); DmsFilePermissionEntity permission = new DmsFilePermissionEntity(); permission.setId(PERMISSION_ID); permission.setResourceId(VERSION_ID); when(fixture.permissionGrantService.ensureWorkflowPrintPermissions( eq(TENANT_ID), eq("print-request:" + REQUEST_ID), eq(APPLICANT_ID), eq(Collections.singletonList(VERSION_ID)), eq("jnpf-file"), any())) .thenReturn(Collections.singletonList(permission)); DmsWorkflowPrintAuthorizationVO result = fixture.service.authorize( TENANT_ID, form(), "jnpf-file"); assertTrue(result.getCompleted()); assertEquals(APPLICANT_ID, result.getApplicantUserId()); assertEquals(2, result.getFiles().get(0).getPrintCopies()); assertEquals("1-3", result.getFiles().get(0).getPrintPages()); assertEquals(PERMISSION_ID, result.getFiles().get(0).getPermissionId()); assertTrue(result.getFiles().get(0).getPermanent()); } @Test void rejectsUnapprovedTaskBeforeReadingPrintRequest() { Fixture fixture = new Fixture(); when(fixture.workFlowApi.getInfoSubmit(TASK_ID)).thenReturn(task(TaskStatusEnum.RUNNING.getCode())); assertThrows(DataException.class, () -> fixture.service.authorize(TENANT_ID, form(), "jnpf-file")); verify(fixture.requestMapper, never()).selectByFlowForUpdate(any(), any(), any()); } @Test void rejectsNonIntegerPrintCopiesBeforeGrantingPermission() { Fixture fixture = new Fixture(); when(fixture.workFlowApi.getInfoSubmit(TASK_ID)).thenReturn(task(TaskStatusEnum.PASSED.getCode())); when(fixture.requestMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID)) .thenReturn(Collections.singletonList(request())); when(fixture.detailMapper.selectByRequestForUpdate(TENANT_ID, REQUEST_ID)) .thenReturn(Collections.singletonList(detail("2.5"))); when(fixture.fileResolutionService.resolve(any(), any(), any(), any(), any(), any())) .thenReturn(resolved()); assertThrows(DataException.class, () -> fixture.service.authorize(TENANT_ID, form(), "jnpf-file")); verify(fixture.permissionGrantService, never()).ensureWorkflowPrintPermissions( any(), any(), any(), any(), any(), any()); } private static DmsWorkflowPrintAuthorizeForm form() { DmsWorkflowPrintAuthorizeForm form = new DmsWorkflowPrintAuthorizeForm(); form.setSourceId(FLOW_ID); form.setTaskId(TASK_ID); return form; } private static TaskEntity task(Integer status) { TaskEntity task = new TaskEntity(); task.setId(TASK_ID); task.setFlowId(FLOW_ID); task.setStatus(status); return task; } private static DmsWenjianDayinShenqingEntity request() { DmsWenjianDayinShenqingEntity request = new DmsWenjianDayinShenqingEntity(); request.setId(REQUEST_ID); request.setApplicantUserId(APPLICANT_ID); request.setFlowState(TaskStatusEnum.PASSED.getCode()); request.setBizSign("print-sign-1"); return request; } private static DmsWenjianDayinShenqingDetailEntity detail(String copies) { DmsWenjianDayinShenqingDetailEntity detail = new DmsWenjianDayinShenqingDetailEntity(); detail.setId(DETAIL_ID); detail.setFileReferenceId("file-ref-1"); detail.setFileNumber("QM-001"); detail.setFileName("质量手册"); detail.setVersionLabel("V1.0"); detail.setPrintCopies(copies); detail.setPrintPages("1-3"); detail.setPurpose("培训"); return detail; } private static DmsWorkflowFileResolutionService.ResolvedFile resolved() { DmsWenjianZiyuanEntity file = new DmsWenjianZiyuanEntity(); file.setId("business-file-1"); DmsWenjianBanbenEntity businessVersion = new DmsWenjianBanbenEntity(); businessVersion.setId("business-version-1"); DmsFileVersionEntity version = new DmsFileVersionEntity(); version.setId(VERSION_ID); version.setDocumentId(DOCUMENT_ID); version.setFileName("quality-manual.docx"); version.setSizeBytes(2048L); return new DmsWorkflowFileResolutionService.ResolvedFile(file, businessVersion, version); } private static final class Fixture { private final WorkFlowApi workFlowApi = mock(WorkFlowApi.class); private final DmsWenjianDayinShenqingMapper requestMapper = mock(DmsWenjianDayinShenqingMapper.class); private final DmsWenjianDayinShenqingDetailMapper detailMapper = mock(DmsWenjianDayinShenqingDetailMapper.class); private final DmsWorkflowFileResolutionService fileResolutionService = mock(DmsWorkflowFileResolutionService.class); private final DmsPermissionGrantService permissionGrantService = mock(DmsPermissionGrantService.class); private final DmsWorkflowPrintAuthorizationService service = new DmsWorkflowPrintAuthorizationService(workFlowApi, requestMapper, detailMapper, fileResolutionService, permissionGrantService); } }