574bc91c2e459aa8afd9f4c77698b3417ce47883 / internal/web/tree_test.go · 6615 bytes · raw
package web
import (
"net/http"
"strings"
"testing"
)
func noFollowClient() *http.Client {
return &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error {
return http.ErrUseLastResponse
}}
}
func TestTreeView(t *testing.T) {
httpServer, _, dataDir := newTestServer(t)
createRepo(t, newLoggedInClient(t, httpServer), httpServer, "pub", "public")
seedFiles(t, dataDir, "pub")
// The ref view is the repo home layout at that ref: recursive file tree
// plus the rendered README.
resp, err := (&http.Client{}).Get(httpServer.URL + "/josie/pub/tree/main")
if err != nil {
t.Fatalf("GET tree root: %v", err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusOK {
t.Fatalf("tree status = %d: %q", resp.StatusCode, body)
}
for _, want := range []string{
"/josie/pub/blob/main/hello.c", "/josie/pub/blob/main/sub/note.txt",
"<strong>readme</strong>", `class="file-tree`,
} {
if !strings.Contains(body, want) {
t.Errorf("ref view lacks %q", want)
}
}
// Subdirectory pages are gone; the recursive tree links files directly.
resp, err = (&http.Client{}).Get(httpServer.URL + "/josie/pub/tree/main/sub/")
if err != nil {
t.Fatalf("GET tree sub: %v", err)
}
readAll(t, resp)
if resp.StatusCode != http.StatusNotFound {
t.Errorf("subdirectory tree status = %d, want 404", resp.StatusCode)
}
resp, err = (&http.Client{}).Get(httpServer.URL + "/josie/pub/tree/nosuchref")
if err != nil {
t.Fatalf("GET bad ref: %v", err)
}
readAll(t, resp)
if resp.StatusCode != http.StatusNotFound {
t.Errorf("bad ref status = %d, want 404", resp.StatusCode)
}
}
// TestSlashBranchViews checks refs containing "/" (feature/greeting) resolve
// on the tree, blob, and commits views.
func TestSlashBranchViews(t *testing.T) {
httpServer, _, _ := newTestServer(t)
owner := noFollow(newLoggedInClient(t, httpServer))
createRepo(t, owner, httpServer, "pub", "public")
work := cloneRepo(t, httpServer, "pub")
writeWork(t, work, "hello.c", "int main(void) { return 0; }\n")
runGit(t, work, "add", ".")
runGit(t, work, "commit", "-qm", "a")
runGit(t, work, "-c", "credential.helper=", "push", "-q", "origin", "HEAD:refs/heads/main")
runGit(t, work, "checkout", "-qb", "feature/greeting")
writeWork(t, work, "hello.c", "int main(void) { return 1; }\n")
runGit(t, work, "commit", "-qam", "b")
runGit(t, work, "-c", "credential.helper=", "push", "-q", "origin", "feature/greeting")
for _, path := range []string{
"/josie/pub/tree/feature/greeting",
"/josie/pub/commits/feature/greeting",
} {
resp, err := (&http.Client{}).Get(httpServer.URL + path)
if err != nil {
t.Fatalf("GET %s: %v", path, err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusOK {
t.Errorf("GET %s = %d, want 200: %q", path, resp.StatusCode, body)
}
}
resp, err := (&http.Client{}).Get(httpServer.URL + "/josie/pub/blob/feature/greeting/hello.c")
if err != nil {
t.Fatalf("GET slash-branch blob: %v", err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusOK || !strings.Contains(body, "feature/greeting / hello.c") {
t.Errorf("slash-branch blob = %d, want 200 resolved to the branch: %q", resp.StatusCode, body)
}
}
func TestBlobViews(t *testing.T) {
httpServer, _, dataDir := newTestServer(t)
createRepo(t, newLoggedInClient(t, httpServer), httpServer, "pub", "public")
seedFiles(t, dataDir, "pub")
resp, err := (&http.Client{}).Get(httpServer.URL + "/josie/pub/blob/main/hello.c")
if err != nil {
t.Fatalf("GET blob c: %v", err)
}
body := readAll(t, resp)
if resp.StatusCode != http.StatusOK {
t.Fatalf("blob status = %d: %q", resp.StatusCode, body)
}
if !strings.Contains(body, "<span") {
t.Errorf("no chroma spans in: %q", body)
}
if !strings.Contains(body, "/josie/pub/raw/main/hello.c") {
t.Error("no raw link")
}
resp, err = (&http.Client{}).Get(httpServer.URL + "/josie/pub/blob/main/README.md")
if err != nil {
t.Fatalf("GET blob md: %v", err)
}
body = readAll(t, resp)
if !strings.Contains(body, "<strong>readme</strong>") {
t.Errorf("markdown blob not rendered: %q", body)
}
resp, err = (&http.Client{}).Get(httpServer.URL + "/josie/pub/blob/main/sub/note.txt")
if err != nil {
t.Fatalf("GET blob txt: %v", err)
}
body = readAll(t, resp)
if !strings.Contains(body, "<pre") || !strings.Contains(body, "note") {
t.Errorf("plain blob not pre-wrapped: %q", body)
}
if strings.Count(body, "<!DOCTYPE") != 1 {
t.Error("chroma embedded a whole document inside the page")
}
if !strings.Contains(body, `class="file-tree`) {
t.Error("blob page lacks the file tree")
}
resp, err = noFollowClient().Get(httpServer.URL + "/josie/pub/blob/main/sub")
if err != nil {
t.Fatalf("GET blob dir: %v", err)
}
readAll(t, resp)
if resp.StatusCode != http.StatusNotFound {
t.Errorf("dir-blob status = %d, want 404", resp.StatusCode)
}
resp, err = (&http.Client{}).Get(httpServer.URL + "/josie/pub/blob/main/nope.txt")
if err != nil {
t.Fatalf("GET blob missing: %v", err)
}
readAll(t, resp)
if resp.StatusCode != http.StatusNotFound {
t.Errorf("missing blob status = %d, want 404", resp.StatusCode)
}
}
func TestRawAndPrivateGate(t *testing.T) {
httpServer, _, dataDir := newTestServer(t)
loggedIn := newLoggedInClient(t, httpServer)
createRepo(t, loggedIn, httpServer, "pub", "public")
createRepo(t, loggedIn, httpServer, "sec", "private")
seedFiles(t, dataDir, "pub")
seedFiles(t, dataDir, "sec")
resp, err := (&http.Client{}).Get(httpServer.URL + "/josie/pub/raw/main/hello.c")
if err != nil {
t.Fatalf("GET raw: %v", err)
}
body := readAll(t, resp)
if ct := resp.Header.Get("Content-Type"); !strings.HasPrefix(ct, "text/plain") {
t.Errorf("raw Content-Type = %q", ct)
}
if resp.Header.Get("X-Content-Type-Options") != "nosniff" {
t.Error("raw response missing nosniff")
}
if !strings.Contains(body, "int main") {
t.Errorf("raw body = %q", body)
}
resp, err = noFollowClient().Get(httpServer.URL + "/josie/sec/blob/main/hello.c")
if err != nil {
t.Fatalf("GET private blob anonymous: %v", err)
}
readAll(t, resp)
if resp.StatusCode != http.StatusNotFound {
t.Errorf("private blob status = %d, want 404 (no existence oracle)", resp.StatusCode)
}
resp, err = loggedIn.Get(httpServer.URL + "/josie/sec/blob/main/hello.c")
if err != nil {
t.Fatalf("GET private blob signed-in: %v", err)
}
body = readAll(t, resp)
if resp.StatusCode != http.StatusOK || !strings.Contains(body, "<pre") || !strings.Contains(body, "int") {
t.Errorf("signed-in private blob = %d, want 200 with highlighted content", resp.StatusCode)
}
}