package jnpf.dmsService; import jnpf.base.UserInfo; import jnpf.dmsEntity.permission.entity.DmsDocumentEntity; import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity; import jnpf.dmsEntity.permission.enums.DmsPermissionAction; import jnpf.dmsEntity.permission.enums.DmsResourceType; import jnpf.dmsEntity.storage.form.DmsFileExtendValidityForm; import jnpf.dmsEntity.storage.form.DmsFileExtendValidityForm.FileRequest; import jnpf.dmsMapper.DmsDocumentMapper; import jnpf.dmsMapper.DmsFileVersionMapper; import jnpf.dmsMapper.DmsVersionStateMapper; import jnpf.dmsPermission.DmsCurrentIdentity; import jnpf.exception.DataException; import jnpf.flowable.entity.TaskEntity; import jnpf.flowable.enums.TaskStatusEnum; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InOrder; import java.util.Arrays; import java.util.Date; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.*; class DmsFileValidityServiceTest { private static final String TENANT = "tenant-1"; private final DmsCurrentIdentity identity = mock(DmsCurrentIdentity.class); private final DmsPermissionDecisionService permissions = mock(DmsPermissionDecisionService.class); private final DmsWorkflowFileActivationService workflow = mock(DmsWorkflowFileActivationService.class); private final DmsFileVersionMapper versions = mock(DmsFileVersionMapper.class); private final DmsDocumentMapper documents = mock(DmsDocumentMapper.class); private final DmsVersionStateMapper states = mock(DmsVersionStateMapper.class); private final DmsFileValidityProjection projection = mock(DmsFileValidityProjection.class); private final DmsFileValidityService service = new DmsFileValidityService( identity, permissions, workflow, versions, documents, states, projection,new DmsBusinessLifecycleGuard(null,false)); private final UUID firstId = UUID.fromString("018f0000-0000-7000-8000-000000000801"); private final UUID secondId = UUID.fromString("018f0000-0000-7000-8000-000000000802"); private final UUID firstDocumentId = UUID.fromString("018f0000-0000-7000-8000-000000000811"); private final UUID secondDocumentId = UUID.fromString("018f0000-0000-7000-8000-000000000812"); private final Date firstExpiry = new Date(1893456000000L); private final Date secondExpiry = new Date(1924992000000L); private DmsFileExtendValidityForm form; private TaskEntity task; @BeforeEach void setUp() { UserInfo user = new UserInfo(); when(identity.requireUser()).thenReturn(user); when(identity.tenantId(user)).thenReturn(TENANT); form = form(file(firstId, firstExpiry), file(secondId, secondExpiry)); form.setSourceId(" flow-1 "); form.setTaskId(" task-1 "); task = new TaskEntity(); task.setStatus(TaskStatusEnum.PASSED.getCode()); when(workflow.requireTask("flow-1", "task-1")).thenReturn(task); stubVersion(firstId, firstDocumentId); stubVersion(secondId, secondDocumentId); when(documents.selectByTenantAndIdForUpdate(TENANT, firstDocumentId)) .thenReturn(new DmsDocumentEntity()); when(documents.selectByTenantAndIdForUpdate(TENANT, secondDocumentId)) .thenReturn(new DmsDocumentEntity()); when(states.updateCurrentEffectiveTo(TENANT, firstId, firstExpiry)).thenReturn(1); when(states.updateCurrentEffectiveTo(TENANT, secondId, secondExpiry)).thenReturn(1); } @Test void workflowRequestChecksApprovalAndPermissionThenUpdatesEveryCurrentVersion() { service.extendValidity(form); verify(workflow).requireTask("flow-1", "task-1"); verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, firstId, DmsPermissionAction.UPDATE); verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, secondId, DmsPermissionAction.UPDATE); InOrder updates = inOrder(states); updates.verify(states).updateCurrentEffectiveTo(TENANT, firstId, firstExpiry); updates.verify(states).updateCurrentEffectiveTo(TENANT, secondId, secondExpiry); verify(projection).apply(TENANT, firstId, firstExpiry, null); } @Test void requestWithoutWorkflowStillChecksPermissionAndCurrentValidity() { form.setSourceId(" "); form.setTaskId(null); service.extendValidity(form); verifyNoInteractions(workflow); verify(permissions).requireAllowed(DmsResourceType.FILE_VERSION, firstId, DmsPermissionAction.UPDATE); verify(states).updateCurrentEffectiveTo(TENANT, firstId, firstExpiry); verify(states).updateCurrentEffectiveTo(TENANT, secondId, secondExpiry); } @Test void rejectsWhenOnlyOneWorkflowIdentifierIsProvided() { form.setTaskId(null); assertThrows(DataException.class, () -> service.extendValidity(form)); verifyNoInteractions(identity, workflow, permissions, versions, documents, states); } @Test void rejectsUnapprovedWorkflowBeforeReadingFiles() { task.setStatus(null); assertThrows(DataException.class, () -> service.extendValidity(form)); verifyNoInteractions(permissions, versions, documents, states); } @Test void rejectsDuplicateFileVersionIds() { form.setFiles(Arrays.asList(file(firstId, firstExpiry), file(firstId, secondExpiry))); assertThrows(DataException.class, () -> service.extendValidity(form)); verifyNoInteractions(identity, workflow, permissions, versions, documents, states); } @Test void stopsBeforeAnyUpdateWhenOneVersionDoesNotExist() { when(versions.selectByTenantAndId(TENANT, secondId)).thenReturn(null); assertThrows(DataException.class, () -> service.extendValidity(form)); verifyNoInteractions(documents, states); } @Test void reportsFailureSoTransactionCanRollBackTheWholeBatch() { when(states.updateCurrentEffectiveTo(TENANT, secondId, secondExpiry)).thenReturn(0); assertThrows(DataException.class, () -> service.extendValidity(form)); verify(states).updateCurrentEffectiveTo(TENANT, firstId, firstExpiry); verify(states).updateCurrentEffectiveTo(TENANT, secondId, secondExpiry); } private DmsFileExtendValidityForm form(FileRequest... files) { DmsFileExtendValidityForm value = new DmsFileExtendValidityForm(); value.setFiles(Arrays.asList(files)); return value; } private FileRequest file(UUID fileVersionId, Date effectiveTo) { FileRequest value = new FileRequest(); value.setFileVersionId(fileVersionId); value.setEffectiveTo(effectiveTo); return value; } private void stubVersion(UUID fileVersionId, UUID documentId) { DmsFileVersionEntity version = new DmsFileVersionEntity(); version.setDocumentId(documentId); when(versions.selectByTenantAndId(TENANT, fileVersionId)).thenReturn(version); } }