备案号原来只能写死在 pageInfo.footer 的 HTML 里。现在 /admin/ 站点信息 拆出「ICP 备案号」「公安备案号」两个输入框,页脚 HTML 由服务端 beianFooter() 统一按模板生成(含 html.EscapeString 转义), 自定义页脚 HTML 降级为「高级」折叠项;旧 footer 会被解析回填到字段。 conf.example.yml 里重复的 .navi-search-bar 规则已由 web/navi.css 接管,删除。
64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestBeianFooter(t *testing.T) {
|
|
cases := []struct {
|
|
name, icp, gongan string
|
|
wantParts []string
|
|
wantEmpty bool
|
|
}{
|
|
{name: "both", icp: "京ICP备00000000号-1", gongan: "京公网安备00000000000000号",
|
|
wantParts: []string{"class=\"navi-footer\"", "beian.miit.gov.cn", "京ICP备00000000号-1", "navi-footer-sep", "beian.mps.gov.cn", "京公网安备00000000000000号"}},
|
|
{name: "only icp", icp: " 京ICP备12345678号 ", wantParts: []string{"class=\"navi-footer\"", "京ICP备12345678号"}},
|
|
{name: "only gongan", gongan: "沪公网安备31010102002555号", wantParts: []string{"class=\"navi-footer\"", "沪公网安备31010102002555号"}},
|
|
{name: "blank", icp: " ", gongan: "", wantEmpty: true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := beianFooter(tc.icp, tc.gongan)
|
|
if tc.wantEmpty {
|
|
if got != "" {
|
|
t.Fatalf("want empty footer, got %q", got)
|
|
}
|
|
return
|
|
}
|
|
for _, p := range tc.wantParts {
|
|
if !strings.Contains(got, p) {
|
|
t.Fatalf("footer %q missing %q", got, p)
|
|
}
|
|
}
|
|
if strings.Contains(got, " ") {
|
|
t.Fatalf("footer keeps stray whitespace: %q", got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// 备案号里若混入引号/尖括号,必须被转义,不能原样拼进 HTML。
|
|
func TestBeianFooterEscapesInput(t *testing.T) {
|
|
got := beianFooter(`"><script>alert(1)</script>`, "")
|
|
if strings.Contains(got, "<script>") {
|
|
t.Fatalf("unescaped input leaked into footer: %q", got)
|
|
}
|
|
if !strings.Contains(got, "<script>") && !strings.Contains(got, """) {
|
|
t.Fatalf("expected escaped output, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestMapString(t *testing.T) {
|
|
m := map[string]any{"a": "x", "b": 1, "c": nil}
|
|
if got := mapString(m, "a"); got != "x" {
|
|
t.Fatalf("mapString(a) = %q; want x", got)
|
|
}
|
|
if got := mapString(m, "b"); got != "" {
|
|
t.Fatalf("mapString(b) = %q; want empty for non-string", got)
|
|
}
|
|
if got := mapString(m, "missing"); got != "" {
|
|
t.Fatalf("mapString(missing) = %q; want empty", got)
|
|
}
|
|
}
|