Przeglądaj źródła

feat(benteler): add yida connector writeback test

malk 1 tydzień temu
rodzic
commit
186c59721d

+ 3 - 0
mjava-benteler/src/main/java/com/malk/benteler/config/BentelerYidaConf.java

@@ -42,6 +42,9 @@ public class BentelerYidaConf {
     private String offboardingEmployeeFieldId;
     private String offboardingRemarkFieldId;
 
+    private String testFormUuid;
+    private String testResultFieldId;
+
     private String detailStatusFieldId;
     private String failureMessageFieldId;
     private String totalFieldId;

+ 42 - 0
mjava-benteler/src/main/java/com/malk/benteler/controller/EiamTestController.java

@@ -0,0 +1,42 @@
+package com.malk.benteler.controller;
+
+import com.malk.benteler.dto.EiamTestResult;
+import com.malk.benteler.dto.FormInstanceRequest;
+import com.malk.benteler.service.BentelerYidaTestService;
+import com.malk.server.common.McR;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 宜搭连接器测试接口。
+ */
+@RestController
+@RequestMapping("/benteler/eiam/test")
+public class EiamTestController {
+
+    private final BentelerYidaTestService yidaTestService;
+
+    public EiamTestController(BentelerYidaTestService yidaTestService) {
+        this.yidaTestService = yidaTestService;
+    }
+
+    /**
+     * 读取当前宜搭实例的最终处理结果,并在接口执行后回写为成功。
+     *
+     * @param request JSON 请求体中的宜搭表单实例 ID
+     * @param formInstanceId Query 参数中的宜搭表单实例 ID(兼容宜搭连接器)
+     * @return 字段回写前后的值
+     */
+    @PostMapping("/mark-result-success")
+    public McR<EiamTestResult> markResultSuccess(
+            @RequestBody(required = false) FormInstanceRequest request,
+            @RequestParam(value = "formInstanceId", required = false) String formInstanceId) {
+        String bodyFormInstanceId = request == null ? null : request.getFormInstanceId();
+        return McR.success(yidaTestService.markResultSuccess(
+                StringUtils.defaultIfBlank(bodyFormInstanceId, formInstanceId)));
+    }
+}

+ 20 - 0
mjava-benteler/src/main/java/com/malk/benteler/dto/EiamTestResult.java

@@ -0,0 +1,20 @@
+package com.malk.benteler.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 宜搭连接器测试接口的字段读取与回写结果。
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class EiamTestResult {
+
+    private String formInstanceId;
+    private String originalResult;
+    private String updatedResult;
+}

+ 101 - 0
mjava-benteler/src/main/java/com/malk/benteler/service/BentelerYidaTestService.java

@@ -0,0 +1,101 @@
+package com.malk.benteler.service;
+
+import com.alibaba.fastjson.JSON;
+import com.malk.benteler.config.BentelerYidaConf;
+import com.malk.benteler.dto.EiamTestResult;
+import com.malk.server.aliwork.YDAuth;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.common.McException;
+import com.malk.service.aliwork.YDClient_Form;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 宜搭连接器测试实例的读取与回写服务。
+ */
+@Service
+public class BentelerYidaTestService {
+
+    private static final String SUCCESS_RESULT = "成功";
+
+    private final YDClient_Form ydClientForm;
+    private final YDConf ydConf;
+    private final BentelerYidaConf conf;
+
+    public BentelerYidaTestService(YDClient_Form ydClientForm, YDConf ydConf,
+                                   BentelerYidaConf conf) {
+        this.ydClientForm = ydClientForm;
+        this.ydConf = ydConf;
+        this.conf = conf;
+    }
+
+    /**
+     * 读取测试表单的最终处理结果,并回写为成功。
+     *
+     * @param formInstanceId 宜搭表单实例 ID
+     * @return 回写前后的字段值
+     */
+    public EiamTestResult markResultSuccess(String formInstanceId) {
+        validateConfiguration(formInstanceId);
+        Map<String, Object> instance = ydClientForm.getForm(auth(), formInstanceId, null);
+        validateForm(instance);
+        String originalResult = readResult(instance);
+        writeSuccess(formInstanceId);
+        return EiamTestResult.builder()
+                .formInstanceId(formInstanceId)
+                .originalResult(originalResult)
+                .updatedResult(SUCCESS_RESULT)
+                .build();
+    }
+
+    private void validateConfiguration(String formInstanceId) {
+        if (StringUtils.isBlank(formInstanceId)) {
+            throw new McException("YIDA_FORM_INSTANCE_ID_EMPTY", "formInstanceId 不能为空");
+        }
+        if (StringUtils.isBlank(conf.getTestFormUuid())
+                || StringUtils.isBlank(conf.getTestResultFieldId())) {
+            throw new McException("YIDA_TEST_CONFIG_EMPTY", "宜搭测试表单字段配置不能为空");
+        }
+    }
+
+    private void validateForm(Map<String, Object> instance) {
+        if (instance == null || instance.get("formData") == null) {
+            throw new McException("YIDA_FORM_DATA_EMPTY", "宜搭实例数据为空");
+        }
+        Object modelUuid = instance.get("modelUuid");
+        String actualFormUuid = modelUuid == null
+                ? null
+                : StringUtils.trimToNull(String.valueOf(modelUuid));
+        if (StringUtils.isNotBlank(actualFormUuid)
+                && !StringUtils.equals(conf.getTestFormUuid(), actualFormUuid)) {
+            throw new McException("YIDA_FORM_MISMATCH", "宜搭实例与测试表单不匹配: expected="
+                    + conf.getTestFormUuid() + ", actual=" + actualFormUuid);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private String readResult(Map<String, Object> instance) {
+        Object value = instance.get("formData");
+        Map<String, Object> formData = value instanceof Map
+                ? (Map<String, Object>) value
+                : JSON.parseObject(String.valueOf(value), Map.class);
+        return formData == null ? null : StringUtils.trimToNull(
+                String.valueOf(formData.get(conf.getTestResultFieldId())));
+    }
+
+    private void writeSuccess(String formInstanceId) {
+        Map<String, Object> update = new HashMap<>();
+        update.put(conf.getTestResultFieldId(), SUCCESS_RESULT);
+        Map<String, Object> bodyExt = new HashMap<>();
+        bodyExt.put("useLatestVersion", true);
+        bodyExt.put("ignoreEmpty", false);
+        ydClientForm.updateForm(auth(), formInstanceId, JSON.toJSONString(update), bodyExt);
+    }
+
+    private YDAuth auth() {
+        return YDAuth.ofGlobal(ydConf);
+    }
+}

+ 3 - 0
mjava-benteler/src/main/resources/application.yml

@@ -57,6 +57,9 @@ benteler:
     offboardingTableFieldId: tableField_mrcxjcq5
     offboardingEmployeeFieldId: employeeField_mrcxgkq0
     offboardingRemarkFieldId: textField_mrcxjcq6
+    # prd 宜搭连接器测试:读取该表单“最终处理结果”后回写为“成功”。
+    testFormUuid: FORM-ADEC3F114FAB4BE3A1ED104D5124072BACNK
+    testResultFieldId: textField_mr4b3pnb
     detailStatusFieldId: selectField_mrcxjcq8
     failureMessageFieldId: textareaField_mrn3kh8m
     totalFieldId: numberField_mrcxjcq9

+ 41 - 0
mjava-benteler/src/test/java/com/malk/benteler/controller/EiamTestControllerTest.java

@@ -0,0 +1,41 @@
+package com.malk.benteler.controller;
+
+import com.malk.benteler.dto.EiamTestResult;
+import com.malk.benteler.dto.FormInstanceRequest;
+import com.malk.benteler.service.BentelerYidaTestService;
+import org.junit.Test;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * {@link EiamTestController} 参数兼容验证。
+ */
+public class EiamTestControllerTest {
+
+    @Test
+    public void markResultSuccess_usesQueryParameterWhenBodyIsEmpty() {
+        BentelerYidaTestService service = mock(BentelerYidaTestService.class);
+        when(service.markResultSuccess(anyString())).thenReturn(EiamTestResult.builder().build());
+        EiamTestController controller = new EiamTestController(service);
+
+        controller.markResultSuccess(null, "FINST_QUERY");
+
+        verify(service).markResultSuccess("FINST_QUERY");
+    }
+
+    @Test
+    public void markResultSuccess_prefersBodyParameter() {
+        BentelerYidaTestService service = mock(BentelerYidaTestService.class);
+        when(service.markResultSuccess(anyString())).thenReturn(EiamTestResult.builder().build());
+        EiamTestController controller = new EiamTestController(service);
+        FormInstanceRequest request = new FormInstanceRequest();
+        request.setFormInstanceId("FINST_BODY");
+
+        controller.markResultSuccess(request, "FINST_QUERY");
+
+        verify(service).markResultSuccess("FINST_BODY");
+    }
+}

+ 85 - 0
mjava-benteler/src/test/java/com/malk/benteler/service/BentelerYidaTestServiceTest.java

@@ -0,0 +1,85 @@
+package com.malk.benteler.service;
+
+import com.alibaba.fastjson.JSON;
+import com.malk.benteler.config.BentelerYidaConf;
+import com.malk.benteler.dto.EiamTestResult;
+import com.malk.server.aliwork.YDAuth;
+import com.malk.server.aliwork.YDConf;
+import com.malk.service.aliwork.YDClient_Form;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * {@link BentelerYidaTestService} 宜搭测试回写验证。
+ */
+public class BentelerYidaTestServiceTest {
+
+    private YDClient_Form ydClientForm;
+    private BentelerYidaConf conf;
+    private BentelerYidaTestService service;
+
+    @Before
+    public void setUp() {
+        ydClientForm = mock(YDClient_Form.class);
+        conf = TestBentelerYidaConf.create();
+        YDConf ydConf = new YDConf();
+        ydConf.setAppType("APP_TEST");
+        ydConf.setSystemToken("TOKEN_TEST");
+        service = new BentelerYidaTestService(ydClientForm, ydConf, conf);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void markResultSuccess_readsOriginalValueAndWritesSuccess() {
+        Map<String, Object> formData = new HashMap<>();
+        formData.put(conf.getTestResultFieldId(), "处理中");
+        Map<String, Object> instance = new HashMap<>();
+        instance.put("modelUuid", conf.getTestFormUuid());
+        instance.put("formData", formData);
+        when(ydClientForm.getForm(any(YDAuth.class), anyString(), isNull()))
+                .thenReturn(instance);
+        when(ydClientForm.updateForm(any(YDAuth.class), anyString(), anyString(), anyMap()))
+                .thenReturn(Collections.emptyMap());
+
+        EiamTestResult result = service.markResultSuccess("FINST_TEST");
+
+        assertEquals("处理中", result.getOriginalResult());
+        assertEquals("成功", result.getUpdatedResult());
+        ArgumentCaptor<String> jsonCaptor = ArgumentCaptor.forClass(String.class);
+        verify(ydClientForm).updateForm(any(YDAuth.class), anyString(),
+                jsonCaptor.capture(), anyMap());
+        Map<String, Object> update = JSON.parseObject(jsonCaptor.getValue(), Map.class);
+        assertEquals("成功", update.get(conf.getTestResultFieldId()));
+    }
+
+    @Test
+    public void markResultSuccess_allowsMissingModelUuid() {
+        Map<String, Object> formData = new HashMap<>();
+        formData.put(conf.getTestResultFieldId(), "待处理");
+        Map<String, Object> instance = new HashMap<>();
+        instance.put("formData", formData);
+        when(ydClientForm.getForm(any(YDAuth.class), anyString(), isNull()))
+                .thenReturn(instance);
+        when(ydClientForm.updateForm(any(YDAuth.class), anyString(), anyString(), anyMap()))
+                .thenReturn(Collections.emptyMap());
+
+        EiamTestResult result = service.markResultSuccess("FINST_TEST");
+
+        assertEquals("待处理", result.getOriginalResult());
+        assertEquals("成功", result.getUpdatedResult());
+    }
+}

+ 2 - 0
mjava-benteler/src/test/java/com/malk/benteler/service/TestBentelerYidaConf.java

@@ -41,6 +41,8 @@ final class TestBentelerYidaConf {
         conf.setOffboardingTableFieldId("table_delete");
         conf.setOffboardingEmployeeFieldId("employee_delete");
         conf.setOffboardingRemarkFieldId("remark");
+        conf.setTestFormUuid("FORM_TEST");
+        conf.setTestResultFieldId("test_result");
         conf.setDetailStatusFieldId("status");
         conf.setFailureMessageFieldId("failure_message");
         conf.setTotalFieldId("total");