package jnpf.dmsService;
|
|
import jnpf.dmsEntity.storage.approval.DmsDisableOccupancy;
|
import jnpf.dmsEntity.storage.form.DmsDisableSubmitValidationForm;
|
import jnpf.dmsMapper.DmsDisableApplicationMapper;
|
import jnpf.exception.DataException;
|
import jnpf.flowable.WorkFlowApi;
|
import jnpf.flowable.entity.TaskEntity;
|
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.provider.ValueSource;
|
import org.springframework.test.util.ReflectionTestUtils;
|
import java.util.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.Mockito.*;
|
|
class DmsDisableOccupancyServiceTest {
|
DmsDisableApplicationMapper mapper=mock(DmsDisableApplicationMapper.class);
|
WorkFlowApi workflow=mock(WorkFlowApi.class);
|
DmsDisableOccupancyService service=new DmsDisableOccupancyService(mapper,workflow);
|
TaskEntity task; DmsDisableOccupancy application;
|
@BeforeEach void init() {
|
ReflectionTestUtils.setField(service,"enabled",true);
|
task=new TaskEntity();task.setId("task");task.setFlowId("flow");task.setTemplateId("template");
|
application=new DmsDisableOccupancy();application.setApplicationId("app");application.setFlowId("template");application.setCreatorUserId("applicant");
|
when(workflow.getInfoSubmit("task")).thenReturn(task);
|
when(mapper.application("tenant","task","yichexiao")).thenReturn(application);
|
}
|
void state(int status, boolean ended) {task.setStatus(status);task.setEndTime(ended?new Date():null);application.setFlowState(status);}
|
DmsDisableOccupancy file(String id) {DmsDisableOccupancy r=new DmsDisableOccupancy();r.setFileId(id);r.setFolderId("folder-"+id);return r;}
|
boolean event(String type) {return service.onEvent("tenant","flow","task","yichexiao",type);}
|
@Test void submittedRowsProduceTenantTaskAndDirectorySnapshot() {
|
state(1,false);DmsDisableOccupancy row=file("main");
|
when(mapper.applicationFiles("tenant","app","yichexiao")).thenReturn(List.of(row));
|
when(mapper.selectedFiles("tenant",List.of("main"))).thenReturn(List.of(row));
|
assertFalse(event("start"));
|
verify(mapper).conflictingFiles("tenant",List.of("main"),"task");
|
verify(mapper).releaseTask("tenant","task","yichexiao");verify(mapper).occupy(row);
|
assertEquals("tenant",row.getTenantId());assertEquals("task",row.getTaskId());assertEquals("app",row.getApplicationId());
|
assertEquals("folder-main",row.getFolderId());
|
}
|
@Test void resubmitReplacesOnlyOwnSnapshotAfterCheckingLatestSelection() {
|
state(1,false);DmsDisableOccupancy current=file("replacement");
|
when(mapper.applicationFiles("tenant","app","yichexiao")).thenReturn(List.of(current));
|
when(mapper.selectedFiles("tenant",List.of("replacement"))).thenReturn(List.of(current));
|
event("start");
|
org.mockito.InOrder order=inOrder(mapper);
|
order.verify(mapper).application("tenant","task","yichexiao");
|
order.verify(mapper).applicationFiles("tenant","app","yichexiao");
|
order.verify(mapper).selectedFiles("tenant",List.of("replacement"));
|
order.verify(mapper).conflictingFiles("tenant",List.of("replacement"),"task");
|
order.verify(mapper).releaseTask("tenant","task","yichexiao");
|
order.verify(mapper).occupy(current);
|
}
|
@ParameterizedTest @ValueSource(ints={0,1,3,4,5,6,7,8,9,10})
|
void noReleaseWithoutTrueEndEvenForReturnAndReject(int status) {
|
state(status,false);assertFalse(event(status==8?"back":"reject"));
|
verify(mapper,never()).releaseTask(any(),any(),any());verify(mapper,never()).occupy(any());
|
}
|
@ParameterizedTest @ValueSource(ints={3,4,7,9})
|
void trueUnsuccessfulEndReleasesOwnTaskOnly(int status) {
|
state(status,true);assertFalse(event("end"));verify(mapper).releaseTask("tenant","task","yichexiao");
|
verify(mapper,never()).applicationFiles(any(),any(),any());
|
}
|
@Test void approvedEndDispatchesDisableAndKeepsOccupancyUntilProjection() {
|
state(2,true);assertTrue(event("end"));verify(mapper,never()).releaseTask(any(),any(),any());
|
}
|
@Test void lateStartCannotReoccupyFinishedApprovedFile() {
|
state(2,true);assertFalse(event("start"));verify(mapper,never()).occupy(any());
|
}
|
@Test void eventCannotChangeAnotherNativeApplication() {
|
state(1,false);application.setFlowId("another");assertThrows(DataException.class,()->event("start"));
|
verify(mapper,never()).releaseTask(any(),any(),any());
|
}
|
DmsDisableSubmitValidationForm form(String taskId) {
|
DmsDisableSubmitValidationForm f=new DmsDisableSubmitValidationForm();f.setFlowId("flow");f.setTaskId(taskId);f.setFileIds(List.of("main"));
|
when(mapper.selectedFiles("tenant",List.of("main"))).thenReturn(List.of(file("main")));return f;
|
}
|
@Test void crossOperationConflictBlocksBeforeNativeSubmit() {
|
DmsDisableSubmitValidationForm f=form(null);when(mapper.conflictingFiles("tenant",List.of("main"),null)).thenReturn(1);
|
assertThrows(DataException.class,()->service.validateSubmission("tenant","applicant","yishixiao",f));
|
verify(mapper,never()).occupy(any());
|
}
|
@ParameterizedTest @ValueSource(ints={0,8,9})
|
void ownDraftReturnedOrRecalledApplicationUsesNativeCreatorWhenWorkflowOmitsIt(int status) {
|
state(status,false);service.validateSubmission("tenant","applicant","yichexiao",form("task"));
|
verify(mapper).conflictingFiles("tenant",List.of("main"),"task");verify(mapper,never()).releaseTask(any(),any(),any());
|
}
|
@Test void cannotExcludeAnotherApplicantsOccupancy() {
|
state(8,false);assertThrows(DataException.class,()->service.validateSubmission("tenant","other","yichexiao",form("task")));
|
verify(mapper,never()).conflictingFiles(any(),any(),any());
|
}
|
@Test void activeChangedOrFinishedTaskCannotBeUsedAsNewSubmissionExclusion() {
|
state(1,false);assertThrows(DataException.class,()->service.validateSubmission("tenant","applicant","yichexiao",form("task")));
|
state(3,true);assertThrows(DataException.class,()->service.validateSubmission("tenant","applicant","yichexiao",form("task")));
|
}
|
@Test void nativeApprovalPreflightAllowsUnchangedOwnApplicationForReviewer() {
|
state(1,false);when(mapper.applicationFiles("tenant","app","yichexiao")).thenReturn(List.of(file("main")));
|
service.validateSubmission("tenant","reviewer","yichexiao",form("task"));
|
verify(mapper).conflictingFiles("tenant",List.of("main"),"task");
|
verify(mapper,never()).occupy(any());
|
}
|
@Test void startConflictDoesNotClearExistingSnapshot() {
|
state(1,false);DmsDisableOccupancy row=file("main");when(mapper.applicationFiles("tenant","app","yichexiao")).thenReturn(List.of(row));
|
when(mapper.selectedFiles("tenant",List.of("main"))).thenReturn(List.of(row));
|
when(mapper.conflictingFiles("tenant",List.of("main"),"task")).thenReturn(1);
|
assertThrows(DataException.class,()->event("start"));verify(mapper,never()).releaseTask(any(),any(),any());
|
}
|
@Test void disabledFeatureKeepsExistingEndCallbackUsableWithoutTechnicalTable() {
|
ReflectionTestUtils.setField(service,"enabled",false);state(3,true);assertFalse(event("end"));
|
state(2,true);assertTrue(event("end"));verify(mapper,never()).releaseTask(any(),any(),any());
|
assertThrows(DataException.class,()->event("start"));
|
}
|
}
|