package jnpf.dmsService;
|
|
import jnpf.base.UserInfo;
|
import jnpf.dmsEntity.DmsWenjianXinzengShenheEntity;
|
import jnpf.dmsEntity.DmsWenjianXiudingShenheEntity;
|
import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
|
import jnpf.dmsEntity.storage.enums.DmsWorkflowFileType;
|
import jnpf.dmsEntity.storage.DmsWorkflowSourceKey;
|
import jnpf.dmsEntity.storage.form.DmsWorkflowFilePrepareForm;
|
import jnpf.dmsEntity.storage.vo.DmsWorkflowFilePrepareVO;
|
import jnpf.dmsEntity.storage.vo.DmsFileUploadVO;
|
import jnpf.dmsMapper.DmsFileObjectMapper;
|
import jnpf.dmsMapper.DmsFileVersionMapper;
|
import jnpf.dmsMapper.DmsWenjianXinzengShenheMapper;
|
import jnpf.dmsMapper.DmsWenjianXiudingShenheMapper;
|
import jnpf.dmsPermission.DmsCurrentIdentity;
|
import jnpf.dmsPermission.DmsPermissionException;
|
import jnpf.exception.DataException;
|
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.assertNull;
|
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.verifyNoInteractions;
|
import static org.mockito.Mockito.when;
|
|
class DmsWorkflowFilePrepareServiceTest {
|
private static final String SOURCE_ID = "flow-1";
|
private static final String TASK_ID = "task-1";
|
private static final UUID VERSION_ID =
|
UUID.fromString("018f0000-0000-7000-8000-000000000701");
|
private static final UUID DOCUMENT_ID =
|
UUID.fromString("018f0000-0000-7000-8000-000000000702");
|
|
@Test
|
void refusesToGuessTaskOwnershipOfLegacyFlowOnlyRegistration() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXinzengShenheEntity audit = new DmsWenjianXinzengShenheEntity();
|
audit.setFlowState(1);
|
when(fixture.newAuditMapper.selectByFlowForUpdate("tenant-1", SOURCE_ID, TASK_ID))
|
.thenReturn(Collections.singletonList(audit));
|
when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", SOURCE_ID))
|
.thenReturn(new DmsFileUploadVO());
|
assertThrows(DataException.class,
|
() -> fixture.prepare(fixture.form(DmsWorkflowFileType.CREATE, null)));
|
verifyNoInteractions(fixture.fileVersionMapper);
|
}
|
|
@Test
|
void runningNewWorkflowReturnsInitialVersionContext() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXinzengShenheEntity audit = new DmsWenjianXinzengShenheEntity();
|
audit.setFlowState(1);
|
when(fixture.newAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.singletonList(audit));
|
|
DmsWorkflowFilePrepareVO result = fixture.prepare(
|
fixture.form(DmsWorkflowFileType.CREATE, null));
|
|
assertEquals("D(00)", result.getVersionLabel());
|
assertNull(result.getDocumentId());
|
verifyNoInteractions(fixture.revisionAuditMapper, fixture.fileVersionMapper,
|
fixture.decisionService);
|
}
|
|
@Test
|
void runningWorkflowCanPrepareAFileBeforeApproval() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXinzengShenheEntity audit = new DmsWenjianXinzengShenheEntity();
|
audit.setFlowState(1);
|
when(fixture.newAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.singletonList(audit));
|
|
DmsWorkflowFilePrepareVO result = fixture.prepare(
|
fixture.form(DmsWorkflowFileType.CREATE, null));
|
|
assertEquals("D(00)", result.getVersionLabel());
|
verifyNoInteractions(fixture.fileVersionMapper, fixture.decisionService);
|
}
|
|
@Test
|
void passedBusinessWorkflowCannotBeRegisteredAgain() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXinzengShenheEntity audit = new DmsWenjianXinzengShenheEntity();
|
audit.setFlowState(2);
|
when(fixture.newAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.singletonList(audit));
|
|
assertThrows(DataException.class, () -> fixture.prepare(
|
fixture.form(DmsWorkflowFileType.CREATE, null)));
|
|
verifyNoInteractions(fixture.fileVersionMapper, fixture.decisionService);
|
}
|
|
@Test
|
void sourceAndTaskMustIdentifyOneBusinessWorkflow() {
|
Fixture fixture = new Fixture();
|
when(fixture.newAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.emptyList());
|
|
assertThrows(DataException.class, () -> fixture.prepare(
|
fixture.form(DmsWorkflowFileType.CREATE, null)));
|
|
verifyNoInteractions(fixture.fileVersionMapper, fixture.decisionService);
|
}
|
|
@Test
|
void runningRevisionResolvesDocumentAndNextVersionFromCurrentVersion() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXiudingShenheEntity audit = new DmsWenjianXiudingShenheEntity();
|
audit.setFlowState(1);
|
when(fixture.revisionAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.singletonList(audit));
|
DmsFileVersionEntity base = version(VERSION_ID, DOCUMENT_ID);
|
when(fixture.fileVersionMapper.selectByTenantAndId("tenant-1", VERSION_ID))
|
.thenReturn(base);
|
when(fixture.fileVersionMapper.selectCurrentEffective("tenant-1", DOCUMENT_ID))
|
.thenReturn(base);
|
when(fixture.fileVersionMapper.selectNextVersionNo("tenant-1", DOCUMENT_ID))
|
.thenReturn(2L);
|
|
DmsWorkflowFilePrepareVO result = fixture.prepare(
|
fixture.form(DmsWorkflowFileType.REVISE, VERSION_ID));
|
|
assertEquals(DOCUMENT_ID, result.getDocumentId());
|
assertEquals("D(01)", result.getVersionLabel());
|
assertEquals("工作流审核通过", result.getRevisionReason());
|
verify(fixture.decisionService).requireAllowed(any(), any(), any());
|
}
|
|
@Test
|
void revisionRequiresCurrentEffectiveVersion() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXiudingShenheEntity audit = new DmsWenjianXiudingShenheEntity();
|
audit.setFlowState(1);
|
when(fixture.revisionAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.singletonList(audit));
|
when(fixture.fileVersionMapper.selectByTenantAndId("tenant-1", VERSION_ID))
|
.thenReturn(version(VERSION_ID, DOCUMENT_ID));
|
when(fixture.fileVersionMapper.selectCurrentEffective("tenant-1", DOCUMENT_ID))
|
.thenReturn(version(UUID.randomUUID(), DOCUMENT_ID));
|
|
assertThrows(DmsPermissionException.class, () -> fixture.prepare(
|
fixture.form(DmsWorkflowFileType.REVISE, VERSION_ID)));
|
|
verify(fixture.fileVersionMapper, never()).selectNextVersionNo(any(), any());
|
}
|
|
@Test
|
void exactRevisionRetryCanUseItsSupersededBaseVersion() {
|
Fixture fixture = new Fixture();
|
DmsWenjianXiudingShenheEntity audit = new DmsWenjianXiudingShenheEntity();
|
audit.setFlowState(1);
|
when(fixture.revisionAuditMapper.selectByFlowForUpdate(
|
"tenant-1", SOURCE_ID, TASK_ID)).thenReturn(Collections.singletonList(audit));
|
DmsFileUploadVO existing = new DmsFileUploadVO();
|
existing.setDocumentId(DOCUMENT_ID);
|
existing.setBaseFileVersionId(VERSION_ID);
|
existing.setVersionLabel("D(01)");
|
existing.setRevisionReason("工作流审核通过");
|
when(fixture.fileObjectMapper.selectUploadBySource(
|
"tenant-1", "jnpf-file", DmsWorkflowSourceKey.of(SOURCE_ID, TASK_ID,
|
DmsWorkflowFileType.REVISE))).thenReturn(existing);
|
|
DmsWorkflowFilePrepareVO result = fixture.prepare(
|
fixture.form(DmsWorkflowFileType.REVISE, VERSION_ID));
|
|
assertEquals(DOCUMENT_ID, result.getDocumentId());
|
assertEquals("D(01)", result.getVersionLabel());
|
verify(fixture.fileVersionMapper, never()).selectByTenantAndId(any(), any());
|
}
|
|
private static DmsFileVersionEntity version(UUID id, UUID documentId) {
|
DmsFileVersionEntity version = new DmsFileVersionEntity();
|
version.setId(id);
|
version.setDocumentId(documentId);
|
return version;
|
}
|
|
private static class Fixture {
|
private final DmsCurrentIdentity currentIdentity = mock(DmsCurrentIdentity.class);
|
private final DmsPermissionDecisionService decisionService =
|
mock(DmsPermissionDecisionService.class);
|
private final DmsWenjianXinzengShenheMapper newAuditMapper =
|
mock(DmsWenjianXinzengShenheMapper.class);
|
private final DmsWenjianXiudingShenheMapper revisionAuditMapper =
|
mock(DmsWenjianXiudingShenheMapper.class);
|
private final DmsFileVersionMapper fileVersionMapper = mock(DmsFileVersionMapper.class);
|
private final DmsFileObjectMapper fileObjectMapper = mock(DmsFileObjectMapper.class);
|
private final DmsWorkflowApprovalValidator approvalValidator = mock(DmsWorkflowApprovalValidator.class);
|
private final DmsWorkflowFilePrepareService service = new DmsWorkflowFilePrepareService(
|
currentIdentity, decisionService, newAuditMapper, revisionAuditMapper,
|
fileVersionMapper, fileObjectMapper, approvalValidator);
|
|
private Fixture() {
|
UserInfo user = new UserInfo();
|
user.setUserId("user-1");
|
user.setTenantId("tenant-1");
|
when(currentIdentity.requireUser()).thenReturn(user);
|
when(currentIdentity.tenantId(user)).thenReturn("tenant-1");
|
}
|
|
private DmsWorkflowFilePrepareForm form(DmsWorkflowFileType type, UUID versionId) {
|
DmsWorkflowFilePrepareForm form = new DmsWorkflowFilePrepareForm();
|
form.setSourceId(SOURCE_ID);
|
form.setTaskId(TASK_ID);
|
form.setFileType(type);
|
form.setVersionId(versionId);
|
return form;
|
}
|
|
private DmsWorkflowFilePrepareVO prepare(DmsWorkflowFilePrepareForm form) {
|
return service.prepare(form, "jnpf-file");
|
}
|
}
|
}
|