package web import ( "net/http/httptest" "testing" "gardomatic.kleiax.de/lib/client" ) func TestWebPathBuildsRegisteredRoutes(t *testing.T) { tests := []struct { name string params []any want string }{ {"home", nil, "/"}, {"garden.dashboard", []any{3}, "/g/3"}, {"plant.edit", []any{3, 7}, "/g/3/plants/edit/7"}, {"account.session.delete", []any{"session/with slash"}, "/account/sessions/session%2Fwith%20slash/delete"}, } for _, test := range tests { if got := webPath(test.name, test.params...); got != test.want { t.Errorf("webPath(%q): got %q, want %q", test.name, got, test.want) } } } func TestPathWithQueryEncodesValues(t *testing.T) { got := pathWithQuery(webPath("location.new", 3), "return_to", webPath("plant.new", 3), "name", "Süd Beet") want := "/g/3/locations/new?name=S%C3%BCd+Beet&return_to=%2Fg%2F3%2Fplants%2Fnew" if got != want { t.Fatalf("got %q, want %q", got, want) } } func TestSafeReturnPath(t *testing.T) { tests := []struct { name string value string want string }{ {name: "local path", value: "/invite?token=abc", want: "/invite?token=abc"}, {name: "absolute URL", value: "https://example.com/phishing"}, {name: "scheme relative URL", value: "//example.com/phishing"}, {name: "backslash", value: `/\\example.com/phishing`}, {name: "encoded backslash", value: `/%5C%5Cexample.com/phishing`}, {name: "encoded leading slashes", value: `/%2F%2Fexample.com/phishing`}, {name: "relative path", value: "invite?token=abc"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { if got := safeReturnPath(test.value); got != test.want { t.Errorf("safeReturnPath(%q): got %q, want %q", test.value, got, test.want) } }) } } func TestGardenAwareAdminPaths(t *testing.T) { garden := &client.Garden{ID: 3} if got := gardenAwarePath(webPath("admin.role.new"), garden); got != "/admin/roles/new?garden=3" { t.Fatalf("gardenAwarePath: got %q", got) } request := httptest.NewRequest("POST", "/admin/test-mail?garden=3", nil) if got := adminPath(request, "#mail-settings", "test-mail", "sent"); got != "/admin?garden=3&test-mail=sent#mail-settings" { t.Fatalf("adminPath: got %q", got) } } func TestEveryRoutePatternStartsWithSlash(t *testing.T) { for name, pattern := range webRoutes { if pattern == "" || pattern[0] != '/' { t.Errorf("route %q has invalid pattern %q", name, pattern) } } }