feat: 支持创作入口公告配置
This commit is contained in:
@@ -253,11 +253,135 @@ mod tests {
|
||||
assert!(rpg.open);
|
||||
assert_eq!(rpg.badge, "可创建");
|
||||
assert_eq!(rpg.sort_order, 10);
|
||||
assert_eq!(rpg.category_id, "recent");
|
||||
assert_eq!(rpg.category_label, "最近创作");
|
||||
assert_eq!(rpg.category_id, "recommended");
|
||||
assert_eq!(rpg.category_label, "热门推荐");
|
||||
assert_eq!(rpg.category_sort_order, 20);
|
||||
assert_eq!(rpg.image_src, "/creation-type-references/rpg.webp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_creation_entry_types_do_not_seed_recent_as_template_category() {
|
||||
let configs = default_creation_entry_type_snapshots(1);
|
||||
|
||||
assert!(configs.iter().all(|item| item.category_id != "recent"));
|
||||
assert!(configs.iter().all(|item| item.category_label != "最近创作"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_entry_event_banners_json_normalizes_multiple_banners() {
|
||||
let normalized = normalize_creation_entry_event_banners_json(
|
||||
r#"[
|
||||
{
|
||||
"title": " 周末拼图赛 ",
|
||||
"description": " 拼一个新主题 ",
|
||||
"coverImageSrc": "/creation-type-references/puzzle.webp",
|
||||
"prizePoolMudPoints": 1200,
|
||||
"startsAtText": "2026-06-01",
|
||||
"endsAtText": "2026-06-30",
|
||||
"renderMode": "structured",
|
||||
"htmlCode": "<div>ignored</div>"
|
||||
},
|
||||
{
|
||||
"title": "HTML 横幅",
|
||||
"description": "沙箱片段",
|
||||
"coverImageSrc": "/creation-type-references/match3d.webp",
|
||||
"prizePoolMudPoints": 900,
|
||||
"startsAtText": "2026-07-01",
|
||||
"endsAtText": "2026-07-31",
|
||||
"renderMode": "html",
|
||||
"htmlCode": " <section>安全片段</section> "
|
||||
}
|
||||
]"#,
|
||||
)
|
||||
.expect("valid banner json should normalize");
|
||||
let banners = decode_creation_entry_event_banner_snapshots(&normalized)
|
||||
.expect("normalized banner json should decode");
|
||||
|
||||
assert_eq!(banners.len(), 2);
|
||||
assert_eq!(banners[0].title, "周末拼图赛");
|
||||
assert_eq!(banners[0].description, "拼一个新主题");
|
||||
assert_eq!(banners[0].render_mode, "structured");
|
||||
assert!(banners[0].html_code.is_none());
|
||||
assert_eq!(banners[1].render_mode, "html");
|
||||
assert_eq!(
|
||||
banners[1].html_code.as_deref(),
|
||||
Some("<section>安全片段</section>")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_entry_event_banners_json_empty_input_returns_defaults() {
|
||||
let normalized = normalize_creation_entry_event_banners_json(" ")
|
||||
.expect("blank banner json should use defaults");
|
||||
let banners = decode_creation_entry_event_banner_snapshots(&normalized)
|
||||
.expect("default banner json should decode");
|
||||
|
||||
assert_eq!(banners, default_creation_entry_event_banner_snapshots());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_entry_event_banners_json_accepts_announcement_html_code() {
|
||||
let normalized = normalize_creation_entry_event_banners_json(
|
||||
r#"[
|
||||
"<section>纯 HTML 公告</section>",
|
||||
{"title": "后台公告", "htmlCode": "<article>自定义公告</article>"}
|
||||
]"#,
|
||||
)
|
||||
.expect("announcement html json should normalize");
|
||||
let banners = decode_creation_entry_event_banner_snapshots(&normalized)
|
||||
.expect("normalized announcement json should decode");
|
||||
|
||||
assert_eq!(banners.len(), 2);
|
||||
assert_eq!(banners[0].title, "公告 1");
|
||||
assert_eq!(banners[0].render_mode, "html");
|
||||
assert_eq!(
|
||||
banners[0].html_code.as_deref(),
|
||||
Some("<section>纯 HTML 公告</section>")
|
||||
);
|
||||
assert_eq!(banners[1].title, "后台公告");
|
||||
assert_eq!(
|
||||
banners[1].html_code.as_deref(),
|
||||
Some("<article>自定义公告</article>")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_entry_event_banners_json_rejects_script_like_html() {
|
||||
let script_error = normalize_creation_entry_event_banners_json(
|
||||
r#"[
|
||||
{
|
||||
"title": "脚本横幅",
|
||||
"description": "不允许脚本",
|
||||
"coverImageSrc": "/creation-type-references/puzzle.webp",
|
||||
"prizePoolMudPoints": 100,
|
||||
"startsAtText": "2026-06-01",
|
||||
"endsAtText": "2026-06-30",
|
||||
"renderMode": "html",
|
||||
"htmlCode": "<script>alert(1)</script>"
|
||||
}
|
||||
]"#,
|
||||
)
|
||||
.expect_err("script tag should be rejected");
|
||||
let javascript_url_error = normalize_creation_entry_event_banners_json(
|
||||
r#"[
|
||||
{
|
||||
"title": "链接横幅",
|
||||
"description": "不允许 javascript URL",
|
||||
"coverImageSrc": "/creation-type-references/puzzle.webp",
|
||||
"prizePoolMudPoints": 100,
|
||||
"startsAtText": "2026-06-01",
|
||||
"endsAtText": "2026-06-30",
|
||||
"renderMode": "html",
|
||||
"htmlCode": "<a href=\"javascript:alert(1)\">bad</a>"
|
||||
}
|
||||
]"#,
|
||||
)
|
||||
.expect_err("javascript url should be rejected");
|
||||
|
||||
assert!(script_error.contains("脚本代码"));
|
||||
assert!(javascript_url_error.contains("脚本代码"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_creation_entry_types_include_bark_battle() {
|
||||
let configs = default_creation_entry_type_snapshots(1);
|
||||
|
||||
Reference in New Issue
Block a user