package service import "testing" func TestNormalizeBrandURL(t *testing.T) { png := "/uploads/brand/0123456789abcdef0123456789abcdef.png" got, ok := NormalizeBrandURL(BrandSlotLight, png) if !ok || got != png { t.Fatalf("logo png want %s got %q ok=%v", png, got, ok) } ico := "/uploads/brand/0123456789abcdef0123456789abcdef.ico" if _, ok := NormalizeBrandURL(BrandSlotLight, ico); ok { t.Fatal("logo should reject ico") } got, ok = NormalizeBrandURL(BrandSlotFavicon, ico) if !ok || got != ico { t.Fatalf("favicon ico want %s got %q ok=%v", ico, got, ok) } empty, ok := NormalizeBrandURL(BrandSlotDark, " ") if !ok || empty != "" { t.Fatalf("empty should clear, got %q ok=%v", empty, ok) } rejects := []string{ "http://evil.test/x.png", "/uploads/brand/../avatars/x.png", "/uploads/backgrounds/0123456789abcdef0123456789abcdef.png", "/uploads/brand/short.png", "javascript:alert(1)", } for _, u := range rejects { if _, ok := NormalizeBrandURL(BrandSlotFavicon, u); ok { t.Fatalf("should reject %q", u) } } } func TestNormalizeKeywords(t *testing.T) { got, err := NormalizeKeywords([]string{" Go , gin ", "论坛,Go"}) if err != nil { t.Fatal(err) } if len(got) != 3 || got[0] != "Go" || got[1] != "gin" || got[2] != "论坛" { t.Fatalf("unexpected %v", got) } long := "" for i := 0; i < MaxKeywordRunes+1; i++ { long += "字" } if _, err := NormalizeKeywords([]string{long}); err == nil { t.Fatal("overlong keyword should fail") } many := make([]string, MaxKeywordCount+1) for i := range many { many[i] = string(rune('a' + i)) } if _, err := NormalizeKeywords(many); err == nil { t.Fatal("too many keywords should fail") } } func TestNormalizeFooterLinks(t *testing.T) { got, err := NormalizeFooterLinks([]FooterLink{ {Label: "备案", URL: "https://beian.miit.gov.cn/", NewTab: true}, {Label: "关于", URL: "/about", NewTab: false}, }) if err != nil || len(got) != 2 || got[1].URL != "/about" { t.Fatalf("got %+v err=%v", got, err) } bad := []FooterLink{ {Label: "x", URL: "javascript:alert(1)"}, {Label: "x", URL: "//evil.test"}, {Label: "", URL: "/a"}, {Label: "x", URL: "ftp://files.test/a"}, } for _, item := range bad { if _, err := NormalizeFooterLinks([]FooterLink{item}); err == nil { t.Fatalf("should reject %+v", item) } } raw := `[{"label":"ICP","url":"https://beian.miit.gov.cn/"}]` parsed, err := parseFooterLinksJSON(raw) if err != nil || len(parsed) != 1 || !parsed[0].NewTab { t.Fatalf("external default new tab, got %+v err=%v", parsed, err) } } func TestNormalizeBrandMarkAndSize(t *testing.T) { mark, ok := NormalizeBrandMark(" image ") if !ok || mark != BrandMarkImage { t.Fatalf("mark got %q ok=%v", mark, ok) } mark, ok = NormalizeBrandMark("") if !ok || mark != BrandMarkImageText { t.Fatalf("empty mark should default, got %q", mark) } if _, ok := NormalizeBrandMark("banner"); ok { t.Fatal("unknown mark should fail") } size, ok := NormalizeBrandLogoSize("4x1") if !ok || size != BrandLogoSize4x1 { t.Fatalf("size got %q", size) } size, ok = NormalizeBrandLogoSize("") if !ok || size != BrandLogoSizeSQ { t.Fatalf("empty size should default, got %q", size) } if _, ok := NormalizeBrandLogoSize("xl"); ok { t.Fatal("old height preset should fail") } fit, ok := NormalizeBrandLogoFit("repeat") if !ok || fit != BrandLogoFitRepeat { t.Fatalf("fit got %q", fit) } fit, ok = NormalizeBrandLogoFit("") if !ok || fit != BrandLogoFitContain { t.Fatalf("empty fit should default, got %q", fit) } if _, ok := NormalizeBrandLogoFit("zoom"); ok { t.Fatal("unknown fit should fail") } }