Files
2026-08-15 07:13:00 +00:00

57 lines
1.7 KiB
Go

package site
import "testing"
func TestSplitTilde(t *testing.T) {
tests := []struct {
path string
project string
rest string
ok bool
}{
{"/~proj", "proj", "", true},
{"/~proj/", "proj", "/", true},
{"/~proj/a/b", "proj", "/a/b", true},
{"/~proj/a/b/", "proj", "/a/b/", true},
{"/~proj//a", "proj", "//a", true},
{"/~p", "p", "", true},
{"/~proj/~other/x", "proj", "/~other/x", true},
// A percent-encoded traversal arrives here already decoded; the project
// still ends at the first slash, and Resolve cleans the remainder.
{"/~proj/../../etc/passwd", "proj", "/../../etc/passwd", true},
// Not a site request at all.
{"", "", "", false},
{"/", "", "", false},
{"/x", "", "", false},
{"/~", "", "", false},
{"/~/", "", "", false},
{"~proj/", "", "", false},
{"//~proj/", "", "", false},
{"/favicon.ico", "", "", false},
{"/api/v1/projects", "", "", false},
}
for _, tc := range tests {
project, rest, ok := splitTilde(tc.path)
if project != tc.project || rest != tc.rest || ok != tc.ok {
t.Errorf("splitTilde(%q) = (%q, %q, %v), want (%q, %q, %v)",
tc.path, project, rest, ok, tc.project, tc.rest, tc.ok)
}
}
}
// The project name never contains a slash, which is what makes "~" + name a
// single entry inside the webroot and keeps a redirect built from it inside the
// project's own prefix.
func TestSplitTildeProjectIsOneSegment(t *testing.T) {
for _, p := range []string{"/~a/b", "/~a//b", "/~a/../b", "/~a/b/c/d"} {
project, _, ok := splitTilde(p)
if !ok {
t.Fatalf("splitTilde(%q) refused a site path", p)
}
if project != "a" {
t.Errorf("splitTilde(%q) project = %q, want %q", p, project, "a")
}
}
}