aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/web_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/web/web_test.go')
-rw-r--r--internal/web/web_test.go90
1 files changed, 81 insertions, 9 deletions
diff --git a/internal/web/web_test.go b/internal/web/web_test.go
index 48f380e..aa9b78e 100644
--- a/internal/web/web_test.go
+++ b/internal/web/web_test.go
@@ -96,6 +96,9 @@ func TestThemeNormalizeAndCSS(t *testing.T) {
if !th.HeaderOn || !th.LeftOn || !th.RightOn || !th.FooterOn || th.LeftWidth != 15 {
t.Errorf("old theme layout defaults: %+v", th)
}
+ if th.PostsPerPage != 10 || th.TitleSize != "normal" || th.FooterAlign != "center" {
+ t.Errorf("old theme content defaults: %+v", th)
+ }
f := url.Values{"bg_color": {"#ABCDEF"}, "bg_image": {"not-a-uuid"}, "logo_size": {"large"},
"link_hover": {"#ff0000"}, "nav_hover": {"#00ff00"}, "nav_hover_custom": {"on"}, "nav_style": {"uppercase"}, "nav_align": {"center"},
"link_underline": {"hover"}, "heading_font": {"serif"}, "content_style": {"flat"}, "content_padding": {"roomy"}, "date_format": {"iso"}}
@@ -123,12 +126,20 @@ func TestThemeNormalizeAndCSS(t *testing.T) {
}
func TestLayoutTheme(t *testing.T) {
- th := LayoutFromForm(DefaultTheme(), url.Values{"left_width": {"40"}, "right_width": {"40"}, "keep_columns": {"on"}})
+ // The layout switches ride in the design form: the areas are checkboxes, so an unticked one is off.
+ th := ThemeFromForm(DefaultTheme(), url.Values{"left_width": {"40"}, "right_width": {"40"}, "keep_columns": {"on"}, "header_on": {"on"}, "left_on": {"on"}, "right_on": {"on"},
+ "posts_per_page": {"20"}, "title_size": {"large"}, "footer_align": {"left"}})
if th.LeftWidth != 40 || th.RightWidth != 30 || th.MainWidth() != 30 || !th.KeepColumns {
t.Errorf("the right column should give way: %+v", th)
}
- th = LayoutFromForm(th, url.Values{"left_width": {"junk"}, "right_width": {"20"}})
- if th.LeftWidth != 15 || th.RightWidth != 20 || th.KeepColumns {
+ if th.FooterOn || !th.HeaderOn || th.PostsPerPage != 20 || th.TitleSize != "large" || th.FooterAlign != "left" {
+ t.Errorf("switches and the content options: %+v", th)
+ }
+ if css := th.CSS(); !strings.Contains(css, ".site-title { font-size:2.6em") || !strings.Contains(css, "text-align:left") {
+ t.Errorf("css: %s", css)
+ }
+ th = ThemeFromForm(th, url.Values{"left_width": {"junk"}, "right_width": {"20"}, "posts_per_page": {"7"}})
+ if th.LeftWidth != 15 || th.RightWidth != 20 || th.KeepColumns || th.PostsPerPage != 10 {
t.Errorf("junk clamps to the minimum: %+v", th)
}
css := th.CSS()
@@ -138,13 +149,74 @@ func TestLayoutTheme(t *testing.T) {
t.Errorf("css missing %q:\n%s", want, css)
}
}
- th.SetAreaOn("left", false)
- th.SetAreaOn("bogus", false)
- if th.AreaOn("left") || !th.AreaOn("right") || !th.AreaOn("above") {
+ th.LeftOn = false
+ if th.AreaOn("left") || !th.AreaOn("above") || !th.AreaOn("bogus") {
t.Errorf("area switches: %+v", th)
}
}
+// The design form sends every module as indexed fields; pos orders them and
+// add.<area> appends. The index only tells rows apart.
+func TestParseModulesForm(t *testing.T) {
+ f := url.Values{
+ "mod.0.id": {"1"}, "mod.0.area": {"header"}, "mod.0.kind": {"title"}, "mod.0.pos": {"1"},
+ "mod.1.id": {"2"}, "mod.1.area": {"header"}, "mod.1.kind": {"menu"}, "mod.1.pos": {"0"},
+ "mod.2.id": {"3"}, "mod.2.area": {"left"}, "mod.2.kind": {"recent"}, "mod.2.pos": {"0"}, "mod.2.title": {" New "}, "mod.2.count": {"99"},
+ "mod.3.id": {"4"}, "mod.3.area": {"footer"}, "mod.3.kind": {"rss"}, "mod.3.pos": {"0"}, "mod.3.del": {"on"},
+ "mod.7.id": {"0"}, "mod.7.area": {"below"}, "mod.7.kind": {"html"}, "mod.7.body": {"<b>hi</b>\r\n"},
+ "add.left": {"tags"}, "add.footer": {""},
+ }
+ mods, err := parseModules(f, "en", "el")
+ if err != nil {
+ t.Fatal(err)
+ }
+ var got []string
+ for _, m := range mods {
+ got = append(got, m.Area+"/"+m.Kind)
+ }
+ if want := "header/menu header/title left/recent left/tags below/html"; strings.Join(got, " ") != want {
+ t.Errorf("order: %v, want %s", got, want)
+ }
+ if mods[2].Title != "New" || mods[2].Count != maxRecentCount || mods[2].ID != 3 || mods[3].ID != 0 || mods[3].Title != "Ετικέτες" || mods[3].Count != 10 || mods[4].Body != "<b>hi</b>\n" {
+ t.Errorf("fields: %+v", mods)
+ }
+ if mods, _ := parseModules(url.Values{"mod.0.area": {"header"}, "mod.0.kind": {"html"}, "add.header": {"rss"}}, "en", "en"); len(mods) != 0 {
+ t.Errorf("kinds an area does not take are dropped: %+v", mods)
+ }
+ // Errors still come with every row, so the form can be shown again as sent.
+ if mods, err := parseModules(url.Values{"mod.0.area": {"above"}, "mod.0.kind": {"html"}, "add.above": {"html"}}, "en", "en"); err == nil || len(mods) != 2 {
+ t.Errorf("two modules above the posts should be refused: %v %+v", err, mods)
+ }
+ if mods, err := parseModules(url.Values{"mod.0.area": {"footer"}, "mod.0.kind": {"text"}, "mod.0.body": {strings.Repeat("x", maxModuleBytes+1)}}, "en", "en"); err == nil || len(mods) != 1 {
+ t.Errorf("a long body should be refused: %v %+v", err, mods)
+ }
+}
+
+func TestParseMenuForm(t *testing.T) {
+ pages := []store.Page{{ID: 1, Title: "Home", Slug: "home", IsHome: true}, {ID: 2, Title: "About", Slug: "about"}}
+ f := url.Values{
+ "menu.0.id": {"10"}, "menu.0.page": {"2"}, "menu.0.pos": {"1"},
+ "menu.1.id": {"11"}, "menu.1.label": {"Photos"}, "menu.1.url": {"example.org/pics"}, "menu.1.pos": {"0"},
+ "menu.2.id": {"12"}, "menu.2.page": {"9"}, "menu.2.pos": {"2"}, // deleted meanwhile
+ "menu.3.id": {"13"}, "menu.3.page": {"2"}, "menu.3.pos": {"3"}, // listed twice
+ "menu_add_page": {"1"}, "menu_add_label": {"Mail"}, "menu_add_url": {"mailto:me@example.org"},
+ }
+ menu, err := parseMenu(f, "en", pages)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(menu) != 4 || menu[0].ID != 11 || menu[0].URL != "https://example.org/pics" || menu[1].ID != 10 || menu[1].PageTitle != "About" ||
+ menu[2].ID != 0 || !menu[2].IsHome || menu[3].URL != "mailto:me@example.org" || menu[3].Label != "Mail" {
+ t.Errorf("menu: %+v", menu)
+ }
+ if menu, err := parseMenu(url.Values{"menu.0.label": {"x"}, "menu.0.url": {"not a url"}}, "en", pages); err == nil || len(menu) != 1 {
+ t.Errorf("a bad address should be refused, and kept for fixing: %v %+v", err, menu)
+ }
+ if menu, err := parseMenu(url.Values{"menu_add_label": {""}, "menu_add_url": {"https://example.org"}}, "en", pages); err == nil || len(menu) != 1 {
+ t.Errorf("a link without text should be refused: %v %+v", err, menu)
+ }
+}
+
func TestBuildLayout(t *testing.T) {
mods := []store.Module{{ID: 1, Area: "header", Kind: "title"}, {ID: 2, Area: "left", Kind: "recent", Count: 3}, {ID: 3, Area: "right", Kind: "recent", Count: 8},
{ID: 4, Area: "right", Kind: "archive"}, {ID: 5, Area: "footer", Kind: "rss"}, {ID: 6, Area: "above", Kind: "html"}, {ID: 7, Area: "right", Kind: "tagcloud"}}
@@ -326,8 +398,8 @@ func TestMenuItemLinks(t *testing.T) {
func TestRedirectOKKeepsAnchor(t *testing.T) {
rec := httptest.NewRecorder()
- redirectOK(rec, httptest.NewRequest("GET", "/", nil), "/b/a/layout#menu", "hi there")
- if got := rec.Header().Get("Location"); got != "/b/a/layout?ok=hi+there#menu" {
+ redirectOK(rec, httptest.NewRequest("GET", "/", nil), "/b/a/design#menu", "hi there")
+ if got := rec.Header().Get("Location"); got != "/b/a/design?ok=hi+there#menu" {
t.Errorf("location: %q", got)
}
}
@@ -379,7 +451,7 @@ func TestAllTemplatesParse(t *testing.T) {
tpl := newTemplates(false)
for _, name := range []string{"auth/login.html", "dashboard/overview.html", "dashboard/pages.html", "dashboard/page_form.html",
"dashboard/posts.html", "dashboard/post_form.html", "dashboard/design.html", "dashboard/files.html", "dashboard/settings.html",
- "dashboard/password.html", "dashboard/confirm.html", "dashboard/sections.html", "dashboard/section_form.html", "dashboard/layout.html", "dashboard/module_form.html", "admin/index.html", "admin/new_user.html", "admin/delete_user.html",
+ "dashboard/password.html", "dashboard/confirm.html", "dashboard/sections.html", "dashboard/section_form.html", "admin/index.html", "admin/new_user.html", "admin/delete_user.html",
"blog/page.html", "blog/post.html", "blog/tag.html", "blog/search.html", "blog/404.html"} {
for _, l := range i18n.Languages() {
if _, err := tpl.get(l.Code, name); err != nil {