feat(hall): 站点主题中转 + 用户面站点信息端点(T2)——SiteOptionVo 扩 theme/themeParams(@JsonIgnoreProperties 兜未知键,兼容旧 CMS 三键形态,测试已证);SiteDirectory 新增 findOption(resolveSite 的全量形态,resolveSite 委托之,SiteInfo 三字段不动);HallController 新增 GET /api/hall/site(requireMember 同口径 + 防御性 SiteInfo 补壳)
This commit is contained in:
@@ -128,6 +128,48 @@ class CmsSiteDirectoryImplTest {
|
||||
assertThrows(BizException.class, () -> directory.listSites(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("T2 主题联动:theme/themeParams 随全量 VO 透传(findOption),resolveSite 三字段结构不变")
|
||||
void findOption_mapsThemeFieldsThrough() {
|
||||
SvcModels.SiteOptionVo row = vo("S1", "站点一", 1L);
|
||||
row.setTheme("campus-glow");
|
||||
row.getThemeParams().put("primary", "#0e8a5f");
|
||||
when(openCall.getList(any(TargetSpec.class), eq(PATH), eq(Collections.emptyMap()), eq(VO_TYPE)))
|
||||
.thenReturn(Collections.singletonList(row));
|
||||
|
||||
SvcModels.SiteOptionVo option = directory.findOption("S1");
|
||||
assertEquals("S1", option.getSiteCode());
|
||||
assertEquals("campus-glow", option.getTheme());
|
||||
assertEquals("#0e8a5f", option.getThemeParams().get("primary"));
|
||||
// resolveSite 委托 findOption:SiteInfo 三字段结构不动(避免 ripple)
|
||||
SiteDirectory.SiteInfo site = directory.resolveSite("S1");
|
||||
assertEquals("S1", site.getSiteCode());
|
||||
assertEquals("站点一", site.getName());
|
||||
assertEquals(1L, site.getSchId());
|
||||
// 同一全量缓存:再取不重复出站
|
||||
assertNull(directory.findOption("NOPE"));
|
||||
verify(openCall, times(1)).getList(any(TargetSpec.class), eq(PATH), eq(Collections.emptyMap()), eq(VO_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("T2 兼容性证明:旧三键+未知键 JSON 反序列化不炸(theme=null),新键正常映射")
|
||||
void siteOptionVo_backwardCompatibleDeserialization() throws Exception {
|
||||
com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
// 旧形态(CMS 未升级)+ 未来未知键:不得抛异常(@JsonIgnoreProperties 兜住)
|
||||
SvcModels.SiteOptionVo legacy = mapper.readValue(
|
||||
"{\"siteCode\":\"S1\",\"name\":\"站点一\",\"schId\":2,\"someFutureKey\":true}",
|
||||
SvcModels.SiteOptionVo.class);
|
||||
assertEquals("S1", legacy.getSiteCode());
|
||||
assertNull(legacy.getTheme());
|
||||
// 新形态:theme/themeParams 正常映射
|
||||
SvcModels.SiteOptionVo fresh = mapper.readValue(
|
||||
"{\"siteCode\":\"S2\",\"name\":\"站点二\",\"schId\":3,\"theme\":\"campus-glow\","
|
||||
+ "\"themeParams\":{\"primary\":\"#0e8a5f\"}}",
|
||||
SvcModels.SiteOptionVo.class);
|
||||
assertEquals("campus-glow", fresh.getTheme());
|
||||
assertEquals("#0e8a5f", fresh.getThemeParams().get("primary"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("rootCauseBrief:ioError 包装层要透出最内层原因(区分\"对端没起\"与\"读超时\")")
|
||||
void rootCauseBrief_exposesInnermostCause() {
|
||||
|
||||
Reference in New Issue
Block a user