|
@@ -0,0 +1,192 @@
|
|
|
|
|
+package com.malk.minglei.service.impl.yida;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
+import com.malk.minglei.config.YidaApplicationsProperties;
|
|
|
|
|
+import com.malk.minglei.dto.ErpYidaPushMainData;
|
|
|
|
|
+import com.malk.minglei.dto.ErpYidaPushRequest;
|
|
|
|
|
+import com.malk.minglei.service.yida.MingleiDocumentService;
|
|
|
|
|
+import com.malk.minglei.service.yida.YidaProcessOpenApiClient;
|
|
|
|
|
+import com.malk.server.aliwork.YDConf;
|
|
|
|
|
+import com.malk.server.aliwork.YDParam;
|
|
|
|
|
+import com.malk.server.dingtalk.DDConf;
|
|
|
|
|
+import com.malk.server.dingtalk.DDR_New;
|
|
|
|
|
+import com.malk.service.aliwork.YDClient;
|
|
|
|
|
+import com.malk.service.dingtalk.DDClient;
|
|
|
|
|
+import com.malk.service.dingtalk.DDClient_Contacts;
|
|
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
|
|
+import org.junit.jupiter.params.ParameterizedTest;
|
|
|
|
|
+import org.junit.jupiter.params.provider.ValueSource;
|
|
|
|
|
+import org.mockito.ArgumentCaptor;
|
|
|
|
|
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
|
|
|
|
+
|
|
|
|
|
+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.assertFalse;
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
|
|
|
+import static org.mockito.ArgumentMatchers.anyMap;
|
|
|
|
|
+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 CustomerReleaseDepartmentConfigurationTest {
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void usesMainDepartmentConfigurationAndMemberIdsInsteadOfErpValues() {
|
|
|
|
|
+ Map<String, Object> user = new LinkedHashMap<String, Object>();
|
|
|
|
|
+ user.put("main_dept_id", 20L);
|
|
|
|
|
+ user.put("dept_id_list", Arrays.asList(10L, 20L));
|
|
|
|
|
+ Map<String, Object> configuration = new LinkedHashMap<String, Object>();
|
|
|
|
|
+ configuration.put("textField_mtgmtiwb", "Configured Company");
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl8", Collections.singletonList("Display Name"));
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl8_id", Arrays.asList("manager-1", "manager-1b"));
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl9_id", Collections.singletonList(Collections.singletonMap("userId", "manager-2")));
|
|
|
|
|
+ configuration.put("employeeField_mszdqrla_id", Collections.singletonList("manager-3"));
|
|
|
|
|
+ try (Fixture fixture = new Fixture(user, configuration)) {
|
|
|
|
|
+ JSONObject form = fixture.start();
|
|
|
|
|
+ assertEquals("Configured Company", form.getString("selectField_mtv7uxgd"));
|
|
|
|
|
+ assertEquals(Collections.singletonList("20"), form.getJSONArray("departmentSelectField_msh186ry"));
|
|
|
|
|
+ assertEquals(Arrays.asList("manager-1", "manager-1b"), form.getJSONArray("employeeField_mt6thsdh"));
|
|
|
|
|
+ assertEquals(Collections.singletonList("manager-2"), form.getJSONArray("employeeField_mt6thsdi"));
|
|
|
|
|
+ assertEquals(Collections.singletonList("manager-3"), form.getJSONArray("employeeField_mt6v6alx"));
|
|
|
|
|
+ fixture.verifyDepartmentQuery("20");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @ParameterizedTest
|
|
|
|
|
+ @ValueSource(strings = {"department", "dept_id_list"})
|
|
|
|
|
+ void fallsBackToFirstDepartmentWhenNoMainDepartmentIsPresent(String departmentKey) {
|
|
|
|
|
+ Map<String, Object> configuration = Collections.<String, Object>singletonMap("textField_mtgmtiwb", "Configured Company");
|
|
|
|
|
+ try (Fixture fixture = new Fixture(Collections.<String, Object>singletonMap(departmentKey,
|
|
|
|
|
+ Arrays.asList(10L, 20L)), configuration)) {
|
|
|
|
|
+ assertEquals("Configured Company", fixture.start().getString("selectField_mtv7uxgd"));
|
|
|
|
|
+ fixture.verifyDepartmentQuery("10");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void startsWhenSomeManagerLevelsAreEmpty() {
|
|
|
|
|
+ Map<String, Object> configuration = new LinkedHashMap<String, Object>();
|
|
|
|
|
+ configuration.put("textField_mtgmtiwb", "Configured Company");
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl8_id", Collections.singletonList("manager-1"));
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl9_id", Collections.emptyList());
|
|
|
|
|
+ try (Fixture fixture = new Fixture(Collections.<String, Object>singletonMap("main_dept_id", 20L), configuration)) {
|
|
|
|
|
+ JSONObject form = fixture.start();
|
|
|
|
|
+ assertEquals(Collections.singletonList("manager-1"), form.getJSONArray("employeeField_mt6thsdh"));
|
|
|
|
|
+ assertFalse(form.containsKey("employeeField_mt6thsdi"));
|
|
|
|
|
+ assertFalse(form.containsKey("employeeField_mt6v6alx"));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @ParameterizedTest
|
|
|
|
|
+ @ValueSource(booleans = {true, false})
|
|
|
|
|
+ void startsWithoutCompanyOrManagersWhenConfigurationIsMissingOrEmpty(boolean noRecord) {
|
|
|
|
|
+ Map<String, Object> configuration = noRecord ? null : new LinkedHashMap<String, Object>();
|
|
|
|
|
+ if (configuration != null) {
|
|
|
|
|
+ configuration.put("textField_mtgmtiwb", " ");
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl8_id", Collections.emptyList());
|
|
|
|
|
+ configuration.put("employeeField_mszdqrl9", Collections.singletonList("Display Name Only"));
|
|
|
|
|
+ }
|
|
|
|
|
+ try (Fixture fixture = new Fixture(Collections.<String, Object>singletonMap("main_dept_id", 20L), configuration)) {
|
|
|
|
|
+ JSONObject form = fixture.start();
|
|
|
|
|
+ assertFalse(form.containsKey("selectField_mtv7uxgd"));
|
|
|
|
|
+ assertFalse(form.containsKey("employeeField_mt6thsdh"));
|
|
|
|
|
+ assertFalse(form.containsKey("employeeField_mt6thsdi"));
|
|
|
|
|
+ assertFalse(form.containsKey("employeeField_mt6v6alx"));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void doesNotStartWhenDepartmentConfigurationQueryFails() {
|
|
|
|
|
+ try (Fixture fixture = new Fixture(Collections.<String, Object>singletonMap("main_dept_id", 20L), null)) {
|
|
|
|
|
+ when(fixture.masterDataClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form)))
|
|
|
|
|
+ .thenThrow(new IllegalStateException("Master data unavailable"));
|
|
|
|
|
+ assertThrows(IllegalStateException.class, () -> fixture.handler.push(fixture.request));
|
|
|
|
|
+ verify(fixture.processClient, never()).startProcess(anyMap());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static class Fixture implements AutoCloseable {
|
|
|
|
|
+ private final YDClient masterDataClient = mock(YDClient.class);
|
|
|
|
|
+ private final YidaProcessOpenApiClient processClient = mock(YidaProcessOpenApiClient.class);
|
|
|
|
|
+ private final DDClient_Contacts contactsClient = mock(DDClient_Contacts.class);
|
|
|
|
|
+ private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
|
|
|
|
+ private final ErpYidaPushRequest request = new ErpYidaPushRequest();
|
|
|
|
|
+ private final CustomerReleaseFormPushHandler handler;
|
|
|
|
|
+
|
|
|
|
|
+ private Fixture(Map<String, Object> user, Map<String, Object> configuration) {
|
|
|
|
|
+ DDClient dingTalkClient = mock(DDClient.class);
|
|
|
|
|
+ when(dingTalkClient.getAccessToken()).thenReturn("access-token");
|
|
|
|
|
+ when(contactsClient.getUserInfoById("access-token", "applicant-1")).thenReturn(user);
|
|
|
|
|
+ DDConf ddConf = new DDConf();
|
|
|
|
|
+ ddConf.setAppKey("app-key");
|
|
|
|
|
+ ddConf.setAppSecret("app-secret");
|
|
|
|
|
+ YidaApplicationsProperties applications = new YidaApplicationsProperties();
|
|
|
|
|
+ applications.getCoordinationOffice().setAppType("APP_RJJL69QUIZVQSV7YC8TL");
|
|
|
|
|
+ applications.getCoordinationOffice().setSystemToken("office-token");
|
|
|
|
|
+ applications.getMasterData().setAppType("APP_KI0AOTH7OLFS2UAUHZXI");
|
|
|
|
|
+ applications.getMasterData().setSystemToken("master-data-token");
|
|
|
|
|
+ DDR_New queryResponse = mock(DDR_New.class);
|
|
|
|
|
+ when(queryResponse.getRecords()).thenReturn(configuration == null ? Collections.emptyList()
|
|
|
|
|
+ : Collections.singletonList(Collections.singletonMap("formData", configuration)));
|
|
|
|
|
+ when(masterDataClient.queryData(any(YDParam.class), eq(YDConf.FORM_QUERY.retrieve_search_form)))
|
|
|
|
|
+ .thenReturn(queryResponse);
|
|
|
|
|
+ DDR_New startResponse = new DDR_New();
|
|
|
|
|
+ startResponse.setResult("process-1");
|
|
|
|
|
+ when(processClient.startProcess(anyMap())).thenReturn(startResponse);
|
|
|
|
|
+ MingleiDocumentService documentService = new MingleiDocumentServiceImpl(masterDataClient,
|
|
|
|
|
+ dingTalkClient, contactsClient, ddConf, applications, new ObjectMapper());
|
|
|
|
|
+ context.registerBean(YidaProcessOpenApiClient.class, () -> processClient);
|
|
|
|
|
+ context.registerBean(DDConf.class, () -> ddConf);
|
|
|
|
|
+ context.registerBean(YidaApplicationsProperties.class, () -> applications);
|
|
|
|
|
+ context.registerBean(MingleiDocumentService.class, () -> documentService);
|
|
|
|
|
+ context.registerBean(CustomerReleaseFormPushHandler.class);
|
|
|
|
|
+ context.refresh();
|
|
|
|
|
+ handler = context.getBean(CustomerReleaseFormPushHandler.class);
|
|
|
|
|
+ ErpYidaPushMainData main = new ErpYidaPushMainData();
|
|
|
|
|
+ main.setExtraField("xmfxdocno", "CR-001");
|
|
|
|
|
+ main.setExtraField("selectField_mtv7uxgd", "Wrong ERP Company");
|
|
|
|
|
+ main.setExtraField("employeeField_mt6thsdh", Collections.singletonList("wrong-manager"));
|
|
|
|
|
+ main.setExtraField("employeeField_mt6thsdi", Collections.singletonList("wrong-manager"));
|
|
|
|
|
+ main.setExtraField("employeeField_mt6v6alx", Collections.singletonList("wrong-manager"));
|
|
|
|
|
+ request.setType("axmt140");
|
|
|
|
|
+ request.setOriginatorUserId("applicant-1");
|
|
|
|
|
+ request.setGs("ERP Company");
|
|
|
|
|
+ request.setBm("ERP Department");
|
|
|
|
|
+ request.setMainData(main);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("rawtypes")
|
|
|
|
|
+ private JSONObject start() {
|
|
|
|
|
+ assertEquals("process-1", handler.push(request));
|
|
|
|
|
+ ArgumentCaptor<Map> body = ArgumentCaptor.forClass(Map.class);
|
|
|
|
|
+ verify(processClient).startProcess(body.capture());
|
|
|
|
|
+ assertEquals("applicant-1", body.getValue().get("userId"));
|
|
|
|
|
+ return JSONObject.parseObject(String.valueOf(body.getValue().get("formDataJson")));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void verifyDepartmentQuery(String departmentId) {
|
|
|
|
|
+ verify(contactsClient).getUserInfoById("access-token", "applicant-1");
|
|
|
|
|
+ ArgumentCaptor<YDParam> parameter = ArgumentCaptor.forClass(YDParam.class);
|
|
|
|
|
+ verify(masterDataClient).queryData(parameter.capture(), eq(YDConf.FORM_QUERY.retrieve_search_form));
|
|
|
|
|
+ assertEquals("APP_KI0AOTH7OLFS2UAUHZXI", parameter.getValue().getAppType());
|
|
|
|
|
+ assertEquals("FORM-8F527F696C5B4AF7AB7A53979527FBA23USO", parameter.getValue().getFormUuid());
|
|
|
|
|
+ JSONObject filter = JSONObject.parseArray(parameter.getValue().getSearchFieldJson()).getJSONObject(0);
|
|
|
|
|
+ assertEquals("textField_msztwhs2", filter.getString("key"));
|
|
|
|
|
+ assertEquals(departmentId, filter.getString("value"));
|
|
|
|
|
+ assertEquals("eq", filter.getString("operator"));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void close() {
|
|
|
|
|
+ context.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|