package jnpf.dmsService; import jnpf.base.UserInfo; import jnpf.base.ActionResult; import jnpf.dmsEntity.storage.form.DmsApprovedRegistrationForm; import jnpf.dmsEntity.storage.form.DmsApprovedRegistrationCallback; import jnpf.dmsEntity.storage.approval.DmsApprovedBatch; import jnpf.dmsEntity.storage.approval.DmsApprovedItem; import jnpf.dmsEntity.wenjianbianhao.DmsFlowEventType; import jnpf.dmsEntity.wenjianbianhao.form.DmsFlowEventForm; import jnpf.dmsMapper.DmsApprovedBatchMapper; import jnpf.dmsPermission.DmsCurrentIdentity; import jnpf.dmsService.impl.DmsWenjianBanbenServiceImpl; import jnpf.exception.DataException; import jnpf.flowable.WorkFlowApi; import jnpf.flowable.entity.TaskEntity; import org.junit.jupiter.api.Test; import java.util.Date; import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class DmsApprovedFlowServiceTest { WorkFlowApi workflow = mock(WorkFlowApi.class); DmsCurrentIdentity identity = mock(DmsCurrentIdentity.class); DmsApprovedFileAcceptanceService acceptance = mock(DmsApprovedFileAcceptanceService.class); DmsApprovedContentService files = mock(DmsApprovedContentService.class); DmsApprovedFileActivationService activation = mock(DmsApprovedFileActivationService.class); DmsWenjianBanbenServiceImpl business = mock(DmsWenjianBanbenServiceImpl.class); DmsApprovedBatchMapper receipts = mock(DmsApprovedBatchMapper.class); DmsApprovedFileRetryService retry = new DmsApprovedFileRetryService(receipts, acceptance, files, activation, business, mock(DmsApprovedDisableProcessor.class), new DmsInvalidationProperties()); DmsApprovedFlowService service = new DmsApprovedFlowService(workflow, identity, acceptance, retry, business, receipts, mock(DmsTemplateNotificationService.class)); DmsFlowEventForm form() { DmsFlowEventForm form = new DmsFlowEventForm(); form.setFlowId("flow"); form.setTaskId("task"); form.setEventType(DmsFlowEventType.END); return form; } DmsApprovedBatch receipt(String status) { DmsApprovedBatch b = new DmsApprovedBatch(); b.setId(UUID.randomUUID()); b.setTenantId("tenant"); b.setStatus(status); return b; } @Test void ignoresClientApprovalClaimAndRejectsWrongTaskOrFlow() { TaskEntity task = new TaskEntity(); task.setId("other"); task.setFlowId("flow"); task.setStatus(2); when(workflow.getInfoSubmit("task")).thenReturn(task); assertThrows(DataException.class, () -> service.sync(form(), "xinzeng_shenhe")); task.setId("task"); task.setFlowId("other-flow"); assertThrows(DataException.class, () -> service.sync(form(), "xinzeng_shenhe")); verifyNoInteractions(acceptance, business); } @Test void acceptedFutureBatchDoesNotWriteBusinessVersions() { DmsApprovedBatch b = receipt("WAITING"); when(activation.activate("tenant", b.getId())).thenReturn(b); service.activateAndApply(b); verifyNoInteractions(business); } @Test void centerActivationPrecedesBusinessProjection() { DmsApprovedBatch b = receipt("EFFECTIVE"); when(activation.activate("tenant", b.getId())).thenReturn(b); service.activateAndApply(b); org.mockito.InOrder order = inOrder(activation, business); order.verify(activation).activate("tenant", b.getId()); order.verify(business).applyApproved(b); } @Test void failedBusinessWriteDoesNotChangeCenterFactOrScheduleRetry() { DmsApprovedBatch b = receipt("EFFECTIVE"); when(activation.activate("tenant", b.getId())).thenReturn(b); doThrow(new DataException("write failed")).when(business).applyApproved(b); assertThrows(DataException.class, () -> service.activateAndApply(b)); verifyNoInteractions(receipts); } @Test void failedActivationLeavesAnExplicitFailureReceipt() { DmsApprovedBatch b = receipt("WAITING"); when(activation.activate("tenant", b.getId())).thenThrow(new DataException("conflict")); assertThrows(DataException.class, () -> service.activateAndApply(b)); verify(receipts).fail("tenant", b.getId()); verifyNoInteractions(business); } @Test void approvedEventCommitsProgressThenPushesTheCompleteSetToExistingRegisterRoute() { TaskEntity task = new TaskEntity(); task.setId("task"); task.setFlowId("flow"); task.setStatus(2); task.setEndTime(new Date()); UserInfo user = new UserInfo(); user.setUserId("actor"); when(workflow.getInfoSubmit("task")).thenReturn(task); when(identity.requireUser()).thenReturn(user); when(identity.tenantId(user)).thenReturn("tenant"); DmsApprovedBatch b = receipt("WAITING"); b.setFlowId("flow"); b.setTaskId("task"); b.setAuditType("xinzeng_shenhe"); DmsApprovedBatch staged = receipt("REGISTERING"); staged.setId(b.getId()); staged.setFlowId("flow"); staged.setTaskId("task"); staged.setAuditType("xinzeng_shenhe"); staged.setSourceDigest("digest"); DmsApprovedItem main = new DmsApprovedItem(); main.setSourceKey("main"); staged.setItems(java.util.Collections.singletonList(main)); staged.setActorId("actor"); staged.setApprovedAt(task.getEndTime()); staged.setAttempts(1); when(acceptance.enqueue("tenant", "flow", "task", "xinzeng_shenhe", "actor", task.getEndTime())).thenReturn(staged); when(receipts.claim(eq("tenant"), eq(staged.getId()), any(), anyBoolean())).thenAnswer(inv -> { staged.setLeaseToken(inv.getArgument(2)); return 1; }); when(receipts.find("tenant", "task", "xinzeng_shenhe")).thenReturn(staged); when(acceptance.stage("tenant", "flow", "task", "xinzeng_shenhe", "actor", task.getEndTime())).thenReturn(staged); ActionResult response = new ActionResult<>(); response.setCode(200); response.setData(b); when(files.register(any())).thenReturn(b); when(activation.activate("tenant", b.getId())).thenReturn(b); service.sync(form(), "xinzeng_shenhe"); org.mockito.ArgumentCaptor c = org.mockito.ArgumentCaptor.forClass(DmsApprovedBatch.class); org.mockito.InOrder order = inOrder(acceptance, files); order.verify(acceptance).stage("tenant", "flow", "task", "xinzeng_shenhe", "actor", task.getEndTime()); order.verify(files).register(c.capture()); assertEquals(staged.getId(), c.getValue().getId()); assertEquals("main", c.getValue().getItems().get(0).getSourceKey()); assertEquals("task", c.getValue().getTaskId()); assertEquals("flow", c.getValue().getFlowId()); assertEquals("xinzeng_shenhe", c.getValue().getAuditType()); verify(activation).activate("tenant", b.getId()); verifyNoInteractions(business); when(files.register(any())).thenReturn(null); assertThrows(DataException.class, () -> service.sync(form(), "xinzeng_shenhe")); } @Test void registrationCallbackCommitsAcceptanceBeforeActivationAndBusinessWrite() { DmsApprovedRegistrationCallback callback = new DmsApprovedRegistrationCallback(); DmsApprovedBatch b = receipt("EFFECTIVE"); b.setTaskId("task"); b.setAuditType("xinzeng_shenhe"); DmsApprovedBatch applied = receipt("APPLIED"); when(acceptance.accept(callback, "jnpf-file")).thenReturn(b); when(activation.activate("tenant", b.getId())).thenReturn(b); when(receipts.find("tenant", "task", "xinzeng_shenhe")).thenReturn(applied); assertSame(applied, service.completeRegistration(callback, "jnpf-file")); org.mockito.InOrder order = inOrder(acceptance, activation, business); order.verify(acceptance).accept(callback, "jnpf-file"); order.verify(activation).activate("tenant", b.getId()); order.verify(business).applyApproved(b); verifyNoInteractions(files); } }