裸 HttpClient 不走 YschOpenCall 自动拆信封:userbase 顶层取 id 恒失败=登录态 恒 503(160 实录 2026-10-12);userhome 信封原样透传会被 init 当异常形态跳过 收敛。unwrap 镜像 OpenApiEnvelope 语义(code≠0→503 / code==0 取 data / 无 code 视为已裸),data 裸 payload 透传。单测 stub 从裸 JSON 对齐真实信封形态并补 4 例信封语义用例(6→10,全量 225/225 绿)。
This commit is contained in:
@@ -30,10 +30,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* 外观偏好同源读端点契约(对接规范 §3,网关自建同构哑管道):
|
||||
* <ul>
|
||||
* <li>无会话断言 → 401;未配 app-key / 密钥链解析不到 → 503(绝不 200+兜底值);</li>
|
||||
* <li>happy path:byLoginName 换 userId → appearance 裸 payload 整体透传(无信封);</li>
|
||||
* <li>两腿响应按平台统一信封 {code,msg,data} 解析(镜像 OpenApiEnvelope.unwrap:
|
||||
* code==0 取 data,code≠0 或 data:null → 503;无 code 视为已裸);</li>
|
||||
* <li>happy path:byLoginName 换 userId → appearance 的 data 裸 payload 整体透传;</li>
|
||||
* <li>上游任一环节非 200 / 解析不到 userId → 503(init 侧静默保键语义的前提)。</li>
|
||||
* </ul>
|
||||
* 回环用 JDK HttpServer 按路径分桩(standalone MockMvc 不装 advice,String 返回即裸体)。
|
||||
* 信封坑(2026-10-12 线上实录):真实 UserBase/UserHome oapi 均包 {code,msg,data},
|
||||
* 裸 JSON stub 曾造成顶层取 id 恒失败=登录态恒 503——stub 一律按真实信封形态。
|
||||
*/
|
||||
class AppearanceProxyControllerTest {
|
||||
|
||||
@@ -118,7 +122,20 @@ class AppearanceProxyControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void happyPath_passesThroughBarePayload() throws Exception {
|
||||
void happyPath_unwrapsEnvelopeAndPassesBarePayload() throws Exception {
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName",
|
||||
"{\"code\":0,\"msg\":\"\",\"data\":{\"id\":353,\"loginName\":\"admin\"}}");
|
||||
stubBodies.put("/userhome/oapi/appearance", "{\"code\":0,\"msg\":\"\",\"data\":" + PAYLOAD + "}");
|
||||
|
||||
mvc.perform(get("/api/appearance").session(sessionWithPrincipal("admin")))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().json(PAYLOAD));
|
||||
}
|
||||
|
||||
@Test
|
||||
void bareFallback_stillResolvesAndPassesThrough() throws Exception {
|
||||
// 防御兼容:上游若返回无 code 的裸数据形态,unwrap 原样放行(同 OpenApiEnvelope 语义)
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"id\":353,\"loginName\":\"admin\"}");
|
||||
stubBodies.put("/userhome/oapi/appearance", PAYLOAD);
|
||||
@@ -128,10 +145,36 @@ class AppearanceProxyControllerTest {
|
||||
.andExpect(content().json(PAYLOAD));
|
||||
}
|
||||
|
||||
@Test
|
||||
void userbaseBusinessError_is503() throws Exception {
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"code\":4,\"msg\":\"无此用户\",\"data\":null}");
|
||||
mvc.perform(get("/api/appearance").session(sessionWithPrincipal("ghost")))
|
||||
.andExpect(status().isServiceUnavailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
void userhomeBusinessError_is503() throws Exception {
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"code\":0,\"msg\":\"\",\"data\":{\"id\":353}}");
|
||||
stubBodies.put("/userhome/oapi/appearance", "{\"code\":5,\"msg\":\"外观服务异常\",\"data\":null}");
|
||||
mvc.perform(get("/api/appearance").session(sessionWithPrincipal("admin")))
|
||||
.andExpect(status().isServiceUnavailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
void userhomeNullData_is503() throws Exception {
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"code\":0,\"msg\":\"\",\"data\":{\"id\":353}}");
|
||||
stubBodies.put("/userhome/oapi/appearance", "{\"code\":0,\"msg\":\"\",\"data\":null}");
|
||||
mvc.perform(get("/api/appearance").session(sessionWithPrincipal("admin")))
|
||||
.andExpect(status().isServiceUnavailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
void userNotFound_is503() throws Exception {
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "null");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"code\":0,\"msg\":\"\",\"data\":null}");
|
||||
mvc.perform(get("/api/appearance").session(sessionWithPrincipal("ghost")))
|
||||
.andExpect(status().isServiceUnavailable());
|
||||
}
|
||||
@@ -139,7 +182,7 @@ class AppearanceProxyControllerTest {
|
||||
@Test
|
||||
void upstreamError_is503() throws Exception {
|
||||
controller.setAppKey("gw-appearance");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"id\":353}");
|
||||
stubBodies.put("/userbase/oapi/user/byLoginName", "{\"code\":0,\"msg\":\"\",\"data\":{\"id\":353}}");
|
||||
stubStatus.put("/userhome/oapi/appearance", 404);
|
||||
mvc.perform(get("/api/appearance").session(sessionWithPrincipal("admin")))
|
||||
.andExpect(status().isServiceUnavailable());
|
||||
|
||||
Reference in New Issue
Block a user