|
@@ -0,0 +1,125 @@
|
|
|
|
|
+package com.malk.service.personnel.impl;
|
|
|
|
|
+
|
|
|
|
|
+import com.malk.server.aliwork.YDConf;
|
|
|
|
|
+import com.malk.server.aliwork.YDParam;
|
|
|
|
|
+import com.malk.server.dingtalk.DDR_New;
|
|
|
|
|
+import com.malk.server.personnel.PersonnelSyncConf;
|
|
|
|
|
+import com.malk.service.aliwork.YDClient;
|
|
|
|
|
+import com.malk.service.dingtalk.DDClient;
|
|
|
|
|
+import com.malk.service.dingtalk.DDClient_Contacts;
|
|
|
|
|
+import org.junit.Test;
|
|
|
|
|
+
|
|
|
|
|
+import java.lang.reflect.Field;
|
|
|
|
|
+import java.lang.reflect.Method;
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
|
+import java.time.ZoneId;
|
|
|
|
|
+import java.util.Collections;
|
|
|
|
|
+import java.util.LinkedHashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+import static org.junit.Assert.assertEquals;
|
|
|
|
|
+import static org.junit.Assert.fail;
|
|
|
|
|
+import static org.junit.Assert.assertNull;
|
|
|
|
|
+import static org.junit.Assert.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;
|
|
|
|
|
+
|
|
|
|
|
+public class PersonnelSyncServiceImplTest {
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ public void fetchAllDingUsersShouldAbortWhenExternalDepartmentCannotBeLoaded() throws Exception {
|
|
|
|
|
+ DDClient ddClient = mock(DDClient.class);
|
|
|
|
|
+ DDClient_Contacts contacts = mock(DDClient_Contacts.class);
|
|
|
|
|
+ YDClient ydClient = mock(YDClient.class);
|
|
|
|
|
+ PersonnelSyncConf conf = testConf();
|
|
|
|
|
+ conf.setExternalDeptIds(Collections.singletonList(123L));
|
|
|
|
|
+ when(ddClient.getAccessToken()).thenReturn("test-access-token");
|
|
|
|
|
+ when(contacts.getAllUserDetails("test-access-token", true)).thenReturn(Collections.emptyList());
|
|
|
|
|
+ when(contacts.listDepartmentUserDetail_all("test-access-token", 123L))
|
|
|
|
|
+ .thenThrow(new RuntimeException("source unavailable"));
|
|
|
|
|
+
|
|
|
|
|
+ PersonnelSyncServiceImpl service = new PersonnelSyncServiceImpl();
|
|
|
|
|
+ setField(service, "ddClient", ddClient);
|
|
|
|
|
+ setField(service, "ddClient_contacts", contacts);
|
|
|
|
|
+ setField(service, "ydClient", ydClient);
|
|
|
|
|
+ setField(service, "conf", conf);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ service.fullSync(null);
|
|
|
|
|
+ fail("人员源不完整时必须中止同步");
|
|
|
|
|
+ } catch (IllegalStateException expected) {
|
|
|
|
|
+ assertTrue(expected.getMessage().contains("避免误标离职"));
|
|
|
|
|
+ }
|
|
|
|
|
+ verify(ydClient, never()).queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ public void syncSingleShouldClearOfflineDateWhenEmployeeReturnsActive() throws Exception {
|
|
|
|
|
+ DDClient ddClient = mock(DDClient.class);
|
|
|
|
|
+ DDClient_Contacts contacts = mock(DDClient_Contacts.class);
|
|
|
|
|
+ YDClient ydClient = mock(YDClient.class);
|
|
|
|
|
+ PersonnelSyncConf conf = testConf();
|
|
|
|
|
+ String userId = "employee-1";
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Object> dingUser = new LinkedHashMap<>();
|
|
|
|
|
+ dingUser.put("userid", userId);
|
|
|
|
|
+ dingUser.put("name", "Employee One");
|
|
|
|
|
+ when(ddClient.getAccessToken()).thenReturn("test-access-token");
|
|
|
|
|
+ when(contacts.getUserInfoById("test-access-token", userId)).thenReturn(dingUser);
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Object> existingFormData = new LinkedHashMap<>();
|
|
|
|
|
+ existingFormData.put(conf.getFieldEmployee(), Collections.singletonList(userId));
|
|
|
|
|
+ existingFormData.put(conf.getFieldStatus(), conf.getStatusValueInactive());
|
|
|
|
|
+ existingFormData.put(conf.getFieldOfflineDate(),
|
|
|
|
|
+ LocalDate.of(2026, 7, 15).atStartOfDay(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli());
|
|
|
|
|
+ Map<String, Object> existingRecord = new LinkedHashMap<>();
|
|
|
|
|
+ existingRecord.put("formInstanceId", "instance-1");
|
|
|
|
|
+ existingRecord.put("formData", existingFormData);
|
|
|
|
|
+ DDR_New<Object> queryResult = new DDR_New<>();
|
|
|
|
|
+ queryResult.setTotalCount(1);
|
|
|
|
|
+ queryResult.setData(Collections.singletonList(existingRecord));
|
|
|
|
|
+ when(ydClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form)))
|
|
|
|
|
+ .thenReturn(queryResult);
|
|
|
|
|
+
|
|
|
|
|
+ PersonnelSyncServiceImpl service = new PersonnelSyncServiceImpl();
|
|
|
|
|
+ setField(service, "ddClient", ddClient);
|
|
|
|
|
+ setField(service, "ddClient_contacts", contacts);
|
|
|
|
|
+ setField(service, "ydClient", ydClient);
|
|
|
|
|
+ setField(service, "conf", conf);
|
|
|
|
|
+ invokeNoArg(service, "initRateLimiters");
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Object> result = service.syncSingle(userId);
|
|
|
|
|
+
|
|
|
|
|
+ assertEquals("UPDATE", result.get("action"));
|
|
|
|
|
+ assertEquals(1, result.get("updated"));
|
|
|
|
|
+ Map<String, Object> formData = (Map<String, Object>) result.get("formData");
|
|
|
|
|
+ assertEquals(conf.getStatusValueActive(), formData.get(conf.getFieldStatus()));
|
|
|
|
|
+ assertTrue(formData.containsKey(conf.getFieldOfflineDate()));
|
|
|
|
|
+ assertNull(formData.get(conf.getFieldOfflineDate()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static PersonnelSyncConf testConf() {
|
|
|
|
|
+ PersonnelSyncConf conf = new PersonnelSyncConf();
|
|
|
|
|
+ conf.setYidaAppType("test-app");
|
|
|
|
|
+ conf.setYidaSystemToken("test-token");
|
|
|
|
|
+ conf.setFormUuidPersonnel("test-personnel");
|
|
|
|
|
+ return conf;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static void setField(Object target, String name, Object value) throws Exception {
|
|
|
|
|
+ Field field = target.getClass().getDeclaredField(name);
|
|
|
|
|
+ field.setAccessible(true);
|
|
|
|
|
+ field.set(target, value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static void invokeNoArg(Object target, String name) throws Exception {
|
|
|
|
|
+ Method method = target.getClass().getDeclaredMethod(name);
|
|
|
|
|
+ method.setAccessible(true);
|
|
|
|
|
+ method.invoke(target);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|