| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- package com.malk.service.workhours;
- import com.alibaba.fastjson.JSON;
- import com.malk.server.aliwork.YDConf;
- import com.malk.server.aliwork.YDParam;
- import com.malk.server.dingtalk.DDR_New;
- import com.malk.server.common.McException;
- import com.malk.server.workhours.TimeCardDuplicateCleanupRequest;
- import com.malk.server.workhours.TimeCardDuplicateCleanupResult;
- import com.malk.server.workhours.TimeCardSummaryUpsertRequest;
- import com.malk.server.workhours.WHConf;
- import com.malk.service.aliwork.YDClient;
- import org.junit.jupiter.api.Test;
- import org.mockito.ArgumentCaptor;
- import org.springframework.test.util.ReflectionTestUtils;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import static org.junit.jupiter.api.Assertions.assertEquals;
- import static org.junit.jupiter.api.Assertions.assertThrows;
- import static org.junit.jupiter.api.Assertions.assertTrue;
- import static org.mockito.ArgumentMatchers.any;
- import static org.mockito.ArgumentMatchers.eq;
- import static org.mockito.Mockito.mock;
- import static org.mockito.Mockito.never;
- import static org.mockito.Mockito.verify;
- import static org.mockito.Mockito.when;
- class TimeCardSummaryServiceTest {
- @Test
- void shouldUpsertBySubmitterIdAndDayText() {
- YDClient ydClient = mock(YDClient.class);
- WHConf whConf = new WHConf();
- whConf.setYidaAppType("APP");
- whConf.setYidaSystemToken("TOKEN");
- whConf.setFormUuidWorkHoursSummary("FORM-SUMMARY");
- TimeCardSummaryService service = new TimeCardSummaryService();
- ReflectionTestUtils.setField(service, "ydClient", ydClient);
- ReflectionTestUtils.setField(service, "whConf", whConf);
- TimeCardSummaryUpsertRequest request = new TimeCardSummaryUpsertRequest();
- request.setSubmitterUserId("user-1");
- request.setDayText("20260716");
- request.setFormData(Collections.singletonMap("numberField_hours", 8));
- DDR_New<Object> empty = new DDR_New<>();
- empty.setData(Collections.emptyList());
- when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form)))
- .thenReturn(empty);
- assertTrue(service.upsert(request));
- ArgumentCaptor<YDParam> captor = ArgumentCaptor.forClass(YDParam.class);
- verify(ydClient).operateData(captor.capture(), eq(YDConf.FORM_OPERATION.upsert));
- YDParam param = captor.getValue();
- Map<String, Object> condition = JSON.parseObject(param.getSearchCondition(), Map.class);
- Map<String, Object> formData = JSON.parseObject(param.getFormDataJson(), Map.class);
- assertEquals("user-1", condition.get("textField_mmbffvd9"));
- assertEquals("20260716", condition.get("textField_mmbffvdb"));
- assertEquals("user-1", formData.get("textField_mmbffvd9"));
- assertEquals("20260716", formData.get("textField_mmbffvdb"));
- assertEquals(8, ((Number) formData.get("numberField_hours")).intValue());
- }
- @Test
- void shouldNotOverwriteApprovedSummaryEvenWhenDailyTotalIsZero() {
- YDClient ydClient = mock(YDClient.class);
- WHConf whConf = new WHConf();
- whConf.setFormUuidWorkHoursSummary("FORM-SUMMARY");
- TimeCardSummaryService service = new TimeCardSummaryService();
- ReflectionTestUtils.setField(service, "ydClient", ydClient);
- ReflectionTestUtils.setField(service, "whConf", whConf);
- Map<String, Object> item = summaryItem("APPROVED-ID", "user-1", "20260716");
- Map<String, Object> data = (Map<String, Object>) item.get("formData");
- data.put("numberField_mmeakgi4", 0);
- Map<String, Object> child = new LinkedHashMap<>();
- child.put("numberField_mmczo637", 8);
- data.put("tableField_mmczo634", Collections.singletonList(child));
- DDR_New<Object> existing = new DDR_New<>();
- existing.setData(Collections.singletonList(item));
- when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form)))
- .thenReturn(existing);
- TimeCardSummaryUpsertRequest request = new TimeCardSummaryUpsertRequest();
- request.setSubmitterUserId("user-1");
- request.setDayText("20260716");
- request.setFormData(Collections.singletonMap("numberField_mmd1smel", 8));
- assertThrows(McException.class, () -> service.upsert(request));
- verify(ydClient, never()).operateData(any(YDParam.class), eq(YDConf.FORM_OPERATION.upsert));
- }
- @Test
- void shouldNotOverwriteApprovedRepairFromNormalSummary() {
- YDClient ydClient = mock(YDClient.class);
- WHConf whConf = new WHConf();
- whConf.setFormUuidWorkHoursSummary("FORM-SUMMARY");
- whConf.setFormUuidRepairWorkHoursSummary("FORM-REPAIR");
- whConf.setRepairSummarySyncStatusField("repair-status");
- TimeCardSummaryService service = new TimeCardSummaryService();
- ReflectionTestUtils.setField(service, "ydClient", ydClient);
- ReflectionTestUtils.setField(service, "whConf", whConf);
- DDR_New<Object> empty = new DDR_New<>();
- empty.setData(Collections.emptyList());
- Map<String, Object> repair = summaryItem("REPAIR-ID", "user-1", "20260716");
- ((Map<String, Object>) repair.get("formData")).put("repair-status", "已审批");
- DDR_New<Object> approved = new DDR_New<>();
- approved.setData(Collections.singletonList(repair));
- when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form)))
- .thenReturn(empty, approved);
- TimeCardSummaryUpsertRequest request = new TimeCardSummaryUpsertRequest();
- request.setSubmitterUserId("user-1");
- request.setDayText("20260716");
- request.setFormData(Collections.singletonMap("numberField_mmd1smel", 8));
- assertThrows(McException.class, () -> service.upsert(request));
- verify(ydClient, never()).operateData(any(YDParam.class), eq(YDConf.FORM_OPERATION.upsert));
- }
- @Test
- void shouldLockWholeFormalDayWhenOneChildIsSubmitted() {
- Map<String, Object> record = summaryItem("SUBMITTED-ID", "user-1", "20260716");
- Map<String, Object> child = new LinkedHashMap<>();
- child.put("numberField_mmczo636", 8);
- ((Map<String, Object>) record.get("formData"))
- .put("tableField_mmczo634", Collections.singletonList(child));
- assertTrue(TimeCardSummaryService.isFormalRecordLocked(record));
- }
- @Test
- void shouldValidateDuplicateCleanupWithoutDeletingInDryRun() {
- YDClient ydClient = mock(YDClient.class);
- WHConf whConf = new WHConf();
- whConf.setYidaAppType("APP");
- whConf.setYidaSystemToken("TOKEN");
- whConf.setFormUuidWorkHoursSummary("FORM-SUMMARY");
- TimeCardSummaryService service = new TimeCardSummaryService();
- ReflectionTestUtils.setField(service, "ydClient", ydClient);
- ReflectionTestUtils.setField(service, "whConf", whConf);
- DDR_New queryResult = mock(DDR_New.class);
- when(queryResult.getData()).thenReturn(Arrays.asList(
- summaryItem("DELETE-ID", "user-1", "20260507"),
- summaryItem("KEEP-ID", "user-1", "20260507")));
- when(ydClient.queryData(
- any(YDParam.class),
- eq(YDConf.FORM_QUERY.retrieve_search_form)))
- .thenReturn(queryResult);
- TimeCardDuplicateCleanupResult result =
- service.cleanupDuplicates(cleanupRequest(true));
- assertEquals(1, result.getValidated());
- assertEquals(0, result.getDeleted());
- verify(ydClient, never()).operateData(
- any(YDParam.class),
- eq(YDConf.FORM_OPERATION.delete_batch));
- }
- @Test
- void shouldRejectCleanupWhenCurrentDuplicateSetChanged() {
- TimeCardDuplicateCleanupRequest.Target target =
- cleanupRequest(true).getTargets().get(0);
- assertThrows(
- RuntimeException.class,
- () -> TimeCardSummaryService.validateCleanupTarget(
- target, Collections.singletonList("KEEP-ID")));
- }
- @Test
- void shouldValidateDuplicateGroupWithThreeDeleteTargets() {
- TimeCardDuplicateCleanupRequest request = cleanupRequest(true);
- request.setTargets(new ArrayList<>(request.getTargets()));
- for (int index = 2; index <= 3; index++) {
- TimeCardDuplicateCleanupRequest.Target target =
- new TimeCardDuplicateCleanupRequest.Target();
- target.setUserId("user-1");
- target.setDayText("20260507");
- target.setDeleteInstanceId("DELETE-ID-" + index);
- target.setKeepInstanceId("KEEP-ID");
- request.getTargets().add(target);
- }
- TimeCardSummaryService.validateCleanupTargets(
- request.getTargets(),
- Arrays.asList("KEEP-ID", "DELETE-ID", "DELETE-ID-2", "DELETE-ID-3"));
- }
- @Test
- void shouldDeleteValidatedTargetAndVerifyKeeper() {
- YDClient ydClient = mock(YDClient.class);
- WHConf whConf = new WHConf();
- whConf.setYidaAppType("APP");
- whConf.setYidaSystemToken("TOKEN");
- whConf.setFormUuidWorkHoursSummary("FORM-SUMMARY");
- TimeCardSummaryService service = new TimeCardSummaryService();
- ReflectionTestUtils.setField(service, "ydClient", ydClient);
- ReflectionTestUtils.setField(service, "whConf", whConf);
- DDR_New duplicateResult = mock(DDR_New.class);
- when(duplicateResult.getData()).thenReturn(Arrays.asList(
- summaryItem("DELETE-ID", "user-1", "20260507"),
- summaryItem("KEEP-ID", "user-1", "20260507")));
- DDR_New keeperResult = mock(DDR_New.class);
- when(keeperResult.getData()).thenReturn(Collections.singletonList(
- summaryItem("KEEP-ID", "user-1", "20260507")));
- when(ydClient.queryData(
- any(YDParam.class),
- eq(YDConf.FORM_QUERY.retrieve_search_form)))
- .thenReturn(duplicateResult, keeperResult);
- TimeCardDuplicateCleanupResult result =
- service.cleanupDuplicates(cleanupRequest(false));
- ArgumentCaptor<YDParam> captor = ArgumentCaptor.forClass(YDParam.class);
- verify(ydClient).operateData(
- captor.capture(),
- eq(YDConf.FORM_OPERATION.delete_batch));
- assertEquals(Collections.singletonList("DELETE-ID"),
- captor.getValue().getFormInstanceIdList());
- assertEquals(1, result.getDeleted());
- assertEquals(1, result.getVerified());
- }
- private static TimeCardDuplicateCleanupRequest cleanupRequest(boolean dryRun) {
- TimeCardDuplicateCleanupRequest.Target target =
- new TimeCardDuplicateCleanupRequest.Target();
- target.setUserId("user-1");
- target.setDayText("20260507");
- target.setDeleteInstanceId("DELETE-ID");
- target.setKeepInstanceId("KEEP-ID");
- TimeCardDuplicateCleanupRequest request =
- new TimeCardDuplicateCleanupRequest();
- request.setDryRun(dryRun);
- request.setTargets(Collections.singletonList(target));
- return request;
- }
- private static Map<String, Object> summaryItem(String instanceId,
- String userId,
- String dayText) {
- Map<String, Object> formData = new LinkedHashMap<>();
- formData.put("textField_mmbffvd9", userId);
- formData.put("textField_mmbffvdb", dayText);
- Map<String, Object> item = new LinkedHashMap<>();
- item.put("formInstanceId", instanceId);
- item.put("formData", formData);
- return item;
- }
- }
|