fix(W3): 预览资产代理前缀拼 request.getContextPath(/yschcms 下 CSS 404 裸 HTML),T-W3-01..04 全绿+全量 264/264

This commit is contained in:
chenxing
2026-09-08 10:51:52 +08:00
parent 32448f097e
commit 5da6f7ee5d
3 changed files with 48 additions and 2 deletions
@@ -57,8 +57,12 @@ public class PortalUrlHelper {
*/
public static PortalUrlHelper forPreview(HttpServletRequest request, String siteCode, String theme) {
PortalUrlHelper base = fromRequest(request, siteCode, theme);
// 显式走 5 参构造:第 4 参是 base-origin,代理前缀必须落第 5 参(避免误绑 4 参重载)
return new PortalUrlHelper(base.baseUrl, siteCode, theme, null, "/api/theme/" + theme + "/asset/");
// 显式走 5 参构造:第 4 参是 base-origin,代理前缀必须落第 5 参(避免误绑 4 参重载)。
// W3(方案 §7.4):前缀拼 request.getContextPath()——base/prod 上下文 /yschcms 下
// 不拼会导致 iframe 内 CSS/JS 链接打到网关根 404(预览裸 HTML);
// 空上下文(dev)退化为根相对 /api/theme/…,dev 形态不回归(T-W3-02)。
return new PortalUrlHelper(base.baseUrl, siteCode, theme, null,
request.getContextPath() + "/api/theme/" + theme + "/asset/");
}
/**
@@ -137,6 +137,17 @@ class PreviewApiIT extends CmsIntegrationTestBase {
assertThat(body(result)).contains("/api/theme/t-demo-red/asset/css/main.css");
}
@Test
@DisplayName("T-W3-04: 端到端回归:contextPath=/yschcms 时预览资产 href 带上下文前缀")
void previewAssetHrefCarriesContextPathEndToEnd() throws Exception {
MvcResult result = standalone.perform(get("/yschcms/api/theme/preview")
.contextPath("/yschcms")
.param("siteCode", "demo").param("theme", "t-demo-red"))
.andExpect(status().isOk()).andReturn();
assertThat(body(result))
.contains("href=\"/yschcms/api/theme/t-demo-red/asset/css/main.css\"");
}
@Test
@DisplayName("T26: 预览响应 no-store(不进缓存/CDN)")
void previewNoStore() throws Exception {
@@ -149,6 +149,37 @@ class PortalUrlHelperTest {
assertThat(url.rewriteUploadUrls(null)).isNull();
}
// ===== forPreview 预览资产前缀(W3:context-path 修复,方案 §7.3)=====
@Test
@DisplayName("T-W3-01: forPreview 带上下文:资产前缀含 contextPath")
void forPreview_assetPrefixCarriesContextPath() {
PortalUrlHelper url = PortalUrlHelper.forPreview(
request("http", "base.yunhaixingtong.com", 80, "/yschcms"), "demo", "scholar-blue");
assertThat(url.asset("css/main.css"))
.isEqualTo("/yschcms/api/theme/scholar-blue/asset/css/main.css");
}
@Test
@DisplayName("T-W3-02: forPreview 空上下文退化:前缀 /api/theme/…(dev 形态不回归)")
void forPreview_emptyContextFallsBackToRootPrefix() {
PortalUrlHelper url = PortalUrlHelper.forPreview(
request("http", "localhost", 8072, ""), "demo", "t-demo-red");
assertThat(url.asset("css/main.css"))
.isEqualTo("/api/theme/t-demo-red/asset/css/main.css");
}
@Test
@DisplayName("T-W3-03: forPreview 站内链接不受资产前缀串味(home/category 仍指真实门户)")
void forPreview_homeStaysRealPortal() {
PortalUrlHelper url = PortalUrlHelper.forPreview(
request("http", "base.yunhaixingtong.com", 80, "/yschcms"), "demo", "scholar-blue");
assertThat(url.home()).isEqualTo("http://base.yunhaixingtong.com/yschcms/portal/demo/");
assertThat(url.category(3)).isEqualTo("http://base.yunhaixingtong.com/yschcms/portal/demo/c/3");
assertThat(url.search("x", null))
.isEqualTo("http://base.yunhaixingtong.com/yschcms/portal/demo/search?q=x");
}
// ===== siteHome 分支(B-4:学校域形态下未配域子站不再退化为 "/")=====
@Test