|
@@ -17,14 +17,19 @@ import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
|
|
+import java.util.concurrent.CountDownLatch;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
|
import static org.mockito.ArgumentMatchers.eq;
|
|
import static org.mockito.ArgumentMatchers.eq;
|
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.mock;
|
|
|
import static org.mockito.Mockito.verifyNoInteractions;
|
|
import static org.mockito.Mockito.verifyNoInteractions;
|
|
|
|
|
+import static org.mockito.Mockito.times;
|
|
|
import static org.mockito.Mockito.when;
|
|
import static org.mockito.Mockito.when;
|
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
|
|
|
@@ -97,6 +102,70 @@ class ReSubmitApprovalServiceTest {
|
|
|
assertEquals("正常", started.get("radioField_fill_type"));
|
|
assertEquals("正常", started.get("radioField_fill_type"));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void shouldNotStartSameNormalApprovalTwiceWithinGuardWindow() {
|
|
|
|
|
+ YDClient ydClient = mock(YDClient.class);
|
|
|
|
|
+ WHConf whConf = new WHConf();
|
|
|
|
|
+ whConf.setYidaAppType("APP");
|
|
|
|
|
+ whConf.setYidaSystemToken("TOKEN");
|
|
|
|
|
+ whConf.setFormUuidApproval("FORM-APPROVAL");
|
|
|
|
|
+ whConf.setApprovalProcessCode("PROCESS-APPROVAL");
|
|
|
|
|
+ whConf.setApprovalOriginatorUserId("system-user");
|
|
|
|
|
+ whConf.setApprovalFillTypeField("radioField_fill_type");
|
|
|
|
|
+
|
|
|
|
|
+ ReSubmitApprovalService service = new ReSubmitApprovalService();
|
|
|
|
|
+ ReflectionTestUtils.setField(service, "ydClient", ydClient);
|
|
|
|
|
+ ReflectionTestUtils.setField(service, "whConf", whConf);
|
|
|
|
|
+ TimeCardApprovalStartRequest request = new TimeCardApprovalStartRequest();
|
|
|
|
|
+ request.setFormUuid("FORM-APPROVAL");
|
|
|
|
|
+ request.setProcessCode("PROCESS-APPROVAL");
|
|
|
|
|
+ request.setFormDataJson("{\"textField_test\":\"same-hours\"}");
|
|
|
|
|
+
|
|
|
|
|
+ assertTrue(service.startApproval(request));
|
|
|
|
|
+ assertTrue(service.startApproval(request));
|
|
|
|
|
+ verify(ydClient, times(1)).operateData(any(YDParam.class), eq(YDConf.FORM_OPERATION.start));
|
|
|
|
|
+
|
|
|
|
|
+ request.setFormDataJson("{\"textField_test\":\"changed-hours\"}");
|
|
|
|
|
+ assertTrue(service.startApproval(request));
|
|
|
|
|
+ verify(ydClient, times(2)).operateData(any(YDParam.class), eq(YDConf.FORM_OPERATION.start));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void shouldBlockConcurrentNormalApprovalStart() throws Exception {
|
|
|
|
|
+ YDClient ydClient = mock(YDClient.class);
|
|
|
|
|
+ WHConf whConf = new WHConf();
|
|
|
|
|
+ whConf.setYidaAppType("APP");
|
|
|
|
|
+ whConf.setYidaSystemToken("TOKEN");
|
|
|
|
|
+ whConf.setFormUuidApproval("FORM-APPROVAL");
|
|
|
|
|
+ whConf.setApprovalProcessCode("PROCESS-APPROVAL");
|
|
|
|
|
+ whConf.setApprovalOriginatorUserId("system-user");
|
|
|
|
|
+ CountDownLatch entered = new CountDownLatch(1);
|
|
|
|
|
+ CountDownLatch release = new CountDownLatch(1);
|
|
|
|
|
+ when(ydClient.operateData(any(YDParam.class), eq(YDConf.FORM_OPERATION.start)))
|
|
|
|
|
+ .thenAnswer(invocation -> {
|
|
|
|
|
+ entered.countDown();
|
|
|
|
|
+ release.await(5, TimeUnit.SECONDS);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ });
|
|
|
|
|
+ ReSubmitApprovalService service = new ReSubmitApprovalService();
|
|
|
|
|
+ ReflectionTestUtils.setField(service, "ydClient", ydClient);
|
|
|
|
|
+ ReflectionTestUtils.setField(service, "whConf", whConf);
|
|
|
|
|
+ TimeCardApprovalStartRequest request = new TimeCardApprovalStartRequest();
|
|
|
|
|
+ request.setFormUuid("FORM-APPROVAL");
|
|
|
|
|
+ request.setProcessCode("PROCESS-APPROVAL");
|
|
|
|
|
+ request.setFormDataJson("{\"textField_test\":\"same-hours\"}");
|
|
|
|
|
+
|
|
|
|
|
+ CompletableFuture<Boolean> first = CompletableFuture.supplyAsync(() -> service.startApproval(request));
|
|
|
|
|
+ try {
|
|
|
|
|
+ assertTrue(entered.await(5, TimeUnit.SECONDS));
|
|
|
|
|
+ assertThrows(RuntimeException.class, () -> service.startApproval(request));
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ release.countDown();
|
|
|
|
|
+ }
|
|
|
|
|
+ assertTrue(first.get(5, TimeUnit.SECONDS));
|
|
|
|
|
+ verify(ydClient, times(1)).operateData(any(YDParam.class), eq(YDConf.FORM_OPERATION.start));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Test
|
|
@Test
|
|
|
void shouldKeepExplicitRepairFillTypeWhenStartingApproval() {
|
|
void shouldKeepExplicitRepairFillTypeWhenStartingApproval() {
|
|
|
YDClient ydClient = mock(YDClient.class);
|
|
YDClient ydClient = mock(YDClient.class);
|