139 lines
5.1 KiB
Java
139 lines
5.1 KiB
Java
package com.yunhai.question.fc;
|
||
|
||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||
import com.yunhai.platform.openapi.core.YschOpenCall;
|
||
import com.yunhai.platform.utils.exception.DException;
|
||
import org.junit.jupiter.api.BeforeEach;
|
||
import org.junit.jupiter.api.Test;
|
||
|
||
import java.util.Arrays;
|
||
import java.util.HashMap;
|
||
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;
|
||
|
||
/**
|
||
* FormCenterClient 单元测试(mock YschOpenCall):
|
||
* ① 业务拒绝(DException=FC 信封 code!=0)不重试直接转 Reject;
|
||
* ② 网络/信封异常重试 2 次后转 Unavailable;③ answers 分页解析(rows/nextCursor/after 透传)。
|
||
*/
|
||
class FormCenterClientTest {
|
||
|
||
private YschOpenCall openCall;
|
||
private FormCenterClient client;
|
||
|
||
@BeforeEach
|
||
void setUp() {
|
||
openCall = mock(YschOpenCall.class);
|
||
client = new FormCenterClient(openCall, new ObjectMapper());
|
||
}
|
||
|
||
@Test
|
||
void fetchSchemaReturnsData() {
|
||
Map<String, Object> data = new HashMap<>();
|
||
data.put("formUuid", "U1");
|
||
data.put("version", 2);
|
||
data.put("groups", Arrays.asList(
|
||
group("base", field("q1", "你的性别", "radio",
|
||
option("男", "m"), option("女", "f")))));
|
||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class))).thenReturn(data);
|
||
|
||
Map<String, Object> got = client.fetchSchema(27L, "U1");
|
||
|
||
assertEquals("U1", got.get("formUuid"));
|
||
assertEquals(1, client.parseFields(got).size());
|
||
assertEquals("radio", client.parseFields(got).get(0).get("type"));
|
||
}
|
||
|
||
@Test
|
||
void fcBusinessRejectIsNotRetried() {
|
||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||
.thenThrow(new DException("表单尚未发布:q-001"));
|
||
|
||
FormCenterClient.FormCenterRejectException e = assertThrows(
|
||
FormCenterClient.FormCenterRejectException.class,
|
||
() -> client.fetchSchema(27L, "U1"));
|
||
assertTrue(e.getMessage().contains("表单尚未发布"));
|
||
verify(openCall, times(1)).get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||
}
|
||
|
||
@Test
|
||
void networkFailureRetriesTwiceThenUnavailable() {
|
||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class)))
|
||
.thenThrow(new RuntimeException("connect refused"));
|
||
|
||
assertThrows(FormCenterClient.FormCenterUnavailableException.class,
|
||
() -> client.fetchSchema(27L, "U1"));
|
||
verify(openCall, times(FormCenterClient.MAX_ATTEMPTS))
|
||
.get(anyString(), anyString(), anyMap(), eq(Map.class));
|
||
}
|
||
|
||
@Test
|
||
@SuppressWarnings("unchecked")
|
||
void pullAnswersParsesRowsAndCursor() {
|
||
Map<String, Object> page = new HashMap<>();
|
||
page.put("rows", Arrays.asList(row("a1"), row("a2")));
|
||
page.put("nextCursor", "a2");
|
||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class))).thenReturn(page);
|
||
|
||
FormCenterClient.AnswersPage got = client.pullAnswers(27L, "U1", null, 500);
|
||
|
||
assertEquals(2, got.getRows().size());
|
||
assertEquals("a2", got.getNextCursor());
|
||
assertEquals("a1", got.getRows().get(0).get("answer_uuid"));
|
||
}
|
||
|
||
@Test
|
||
void pullAnswersEndOfWindowHasNullCursor() {
|
||
Map<String, Object> page = new HashMap<>();
|
||
page.put("rows", Arrays.asList());
|
||
page.put("nextCursor", null);
|
||
when(openCall.get(anyString(), anyString(), anyMap(), eq(Map.class))).thenReturn(page);
|
||
|
||
FormCenterClient.AnswersPage got = client.pullAnswers(27L, "U1", "a2", 500);
|
||
|
||
assertEquals(null, got.getNextCursor());
|
||
assertTrue(got.getRows().isEmpty());
|
||
}
|
||
|
||
private static Map<String, Object> row(String uuid) {
|
||
Map<String, Object> r = new HashMap<>();
|
||
r.put("answer_uuid", uuid);
|
||
r.put("is_deleted", 0);
|
||
return r;
|
||
}
|
||
|
||
static Map<String, Object> group(String key, Map<String, Object>... fields) {
|
||
Map<String, Object> g = new HashMap<>();
|
||
g.put("key", key);
|
||
g.put("fields", Arrays.asList(fields));
|
||
return g;
|
||
}
|
||
|
||
static Map<String, Object> field(String key, String label, String type, Map<String, Object>... options) {
|
||
Map<String, Object> f = new HashMap<>();
|
||
f.put("key", key);
|
||
f.put("label", label);
|
||
f.put("type", type);
|
||
f.put("options", Arrays.asList(options));
|
||
return f;
|
||
}
|
||
|
||
static Map<String, Object> option(String label, String value) {
|
||
Map<String, Object> o = new HashMap<>();
|
||
o.put("label", label);
|
||
o.put("value", value);
|
||
return o;
|
||
}
|
||
}
|