package com.yunhai.flowcenter.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yunhai.platform.openapi.core.YschOpenCall;
import com.yunhai.platform.openapi.core.OpenApiException;
import com.yunhai.platform.openapi.core.OpenApiErrorCode;
import com.yunhai.platform.utils.exception.DException;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
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.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* {@link FormCenterSchemaClient} 单元测试(2026-10-20 C1 第一刀)。
* 覆盖:① SchemaView(data) → 快照节的 fields 扁平化(分组展开、enum 收 options 值域);
* ② audience 数组解析(契约 v2 C5/G3 breaking)+ 旧单值串容错;③ 失败重试 2 次后转
* SchemaUnavailableException(发布阻断语义)。
*/
class FormCenterSchemaClientTest {
private YschOpenCall openCall;
private FormCenterSchemaClient client;
@BeforeEach
void setUp() {
openCall = mock(YschOpenCall.class);
client = new FormCenterSchemaClient(openCall, new ObjectMapper());
}
@SuppressWarnings("unchecked")
private Map schemaData(String uuid, int version, List audience) {
Map data = new HashMap<>();
data.put("formUuid", uuid);
data.put("version", version);
data.put("code", "leave-form");
data.put("appCode", "svc-hall");
data.put("audience", audience);
data.put("groups", Arrays.asList(
map("key", "base", "label", "基本信息", "fields", Arrays.asList(
map("key", "days", "label", "天数", "type", "number", "required", true),
map("key", "grade", "label", "年级", "type", "select", "required", false,
"options", Arrays.asList(map("label", "高一", "value", "g1"),
map("label", "高二", "value", "g2"))))),
map("key", "extra", "label", "补充", "fields", Arrays.asList(
map("key", "reason", "label", "事由", "type", "text", "required", true)))));
return data;
}
private static Map map(Object... kv) {
Map m = new HashMap<>();
for (int i = 0; i + 1 < kv.length; i += 2) {
m.put((String) kv[i], kv[i + 1]);
}
return m;
}
@Test
@SuppressWarnings("unchecked")
void flattensGroupsIntoFieldsAndCollectsEnumFromOptions() {
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
.thenReturn(schemaData("U1", 3, Arrays.asList("STUDENT", "TEACHER")));
Map snap = client.fetchSchema(27L, "U1", 3);
assertEquals("U1", snap.get("formUuid"));
assertEquals(3, snap.get("formVersion"));
assertEquals(Arrays.asList("STUDENT", "TEACHER"), snap.get("audience"));
List