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.common.McException; import com.malk.server.dingtalk.DDR_New; import com.malk.server.workhours.WHConf; import com.malk.service.aliwork.YDClient; import com.malk.service.aliwork.YDService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class ChangeProjectManagerLookupServiceTest { private YDClient ydClient; private YDService ydService; private ChangeProjectManagerLookupService service; @BeforeEach void setUp() { ydClient = mock(YDClient.class); ydService = mock(YDService.class); WHConf conf = new WHConf(); conf.setYidaAppType("APP_TEST"); conf.setYidaSystemToken("test-token"); conf.setFormUuidProject("FORM_PROJECT"); service = new ChangeProjectManagerLookupService(ydClient, ydService, conf); } @Test void mergesManagersFromChangedProjectsAndSkipsZeroHourRows() { Map change = new HashMap<>(); change.put("employeeField_mmacxew4_id", Collections.singletonList("worker")); change.put("employeeField_mmacxew4", Collections.singletonList("Worker")); change.put("tableField_mmczo634", Arrays.asList( row("textField_mmd25ngw", "P1", "numberField_mmd25ngz", 2), row("textField_mmd25ngw", "P0", "numberField_mmd25ngz", 0))); change.put("tableField_mmecojwk", Collections.singletonList( row("textField_mmecojwe", "P2", "numberField_mmecojwh", -1))); when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_process_id))) .thenReturn(process(change)); when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form))) .thenAnswer(invocation -> { YDParam param = invocation.getArgument(0); String code = JSON.parseObject(param.getSearchFieldJson()).getString("textField_mkov5ozb"); if ("P1".equals(code)) return project("P1", "worker", "manager-a"); if ("P2".equals(code)) return project("P2", "worker", "manager-a", "manager-b"); throw new AssertionError("不应查询 0 工时项目: " + code); }); assertEquals(Arrays.asList("manager-a", "manager-b"), service.lookup("process-1")); } @Test void readsMemberBeyondInlineFiftyRows() { Map change = new HashMap<>(); change.put("employeeField_mmacxew4_id", Collections.singletonList("worker")); change.put("employeeField_mmacxew4", Collections.singletonList("Worker")); change.put("tableField_mmczo634", Collections.singletonList( row("textField_mmd25ngw", "P1", "numberField_mmd25ngz", 3))); when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_process_id))) .thenReturn(process(change)); DDR_New project = project("P1", "other", "manager-other"); Map projectRow = (Map) ((List) project.getData()).get(0); Map projectData = (Map) projectRow.get("formData"); List inline = new ArrayList<>(); for (int i = 0; i < 50; i++) inline.add(member("other-" + i, "manager-other")); projectData.put("tableField_mkowyn6d", inline); when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form))) .thenReturn(project); List full = new ArrayList<>(inline); full.add(member("worker", "manager-a")); when(ydService.queryDetails(any(YDParam.class))).thenReturn(full); assertEquals(Collections.singletonList("manager-a"), service.lookup("process-2")); verify(ydService).queryDetails(any(YDParam.class)); } @Test void rejectsChangedProjectWithoutSubmitterMember() { Map change = new HashMap<>(); change.put("employeeField_mmacxew4_id", Collections.singletonList("worker")); change.put("employeeField_mmacxew4", Collections.singletonList("Worker")); change.put("tableField_mmczo634", Collections.singletonList( row("textField_mmd25ngw", "P1", "numberField_mmd25ngz", 1))); when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_process_id))) .thenReturn(process(change)); when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form))) .thenReturn(project("P1", "other", "manager-other")); assertThrows(McException.class, () -> service.lookup("process-3")); } private static DDR_New process(Map data) { DDR_New result = new DDR_New(); result.setData(data); return result; } private static DDR_New project(String code, String memberId, String... managerIds) { Map formData = new HashMap<>(); formData.put("textField_mkov5ozb", code); formData.put("tableField_mkowyn6d", Collections.singletonList(member(memberId, managerIds))); Map item = new HashMap<>(); item.put("formInstanceId", "FINST-1"); item.put("formData", formData); DDR_New result = new DDR_New(); result.setData(Collections.singletonList(item)); result.setTotalCount(1); return result; } private static Map member(String memberId, String... managerIds) { Map row = new HashMap<>(); row.put("employeeField_mmbfe0ij_id", Collections.singletonList(memberId)); row.put("employeeField_mkoxpswf_id", Arrays.asList(managerIds)); return row; } private static Map row(String firstKey, Object firstValue, String secondKey, Object secondValue) { Map row = new HashMap<>(); row.put(firstKey, firstValue); row.put(secondKey, secondValue); return row; } }