Parent directory

browser_test.go

4085 bytes
  1package pages
  2
  3import (
  4	"bytes"
  5	"strings"
  6	"testing"
  7)
  8
  9func TestRenderRepositoryMarkdownRewritesRelativeImages(t *testing.T) {
 10	rendered, err := RenderRepositoryMarkdown("team/repository", "refs/heads/main", "docs/README.md", []byte("![logo](../images/logo.png#preview)\n\n[external](https://example.com/docs)\n"))
 11	if err != nil {
 12		t.Fatal(err)
 13	}
 14	output := string(rendered)
 15	if !strings.Contains(output, `/team/repository/@/raw?path=images%2Flogo.png&ref=refs%2Fheads%2Fmain#preview`) {
 16		t.Fatalf("relative image was not rewritten to raw endpoint: %s", output)
 17	}
 18	if !strings.Contains(output, `https://example.com/docs`) {
 19		t.Fatalf("external URL was unexpectedly rewritten: %s", output)
 20	}
 21}
 22
 23func TestSafeDownloadFilenameRemovesHeaderControls(t *testing.T) {
 24	metadata := RawFileMetadata("image\r\nInjected: value.html")
 25	if strings.ContainsAny(metadata.ContentDisposition, "\r\n") {
 26		t.Fatalf("unsafe content disposition: %q", metadata.ContentDisposition)
 27	}
 28}
 29
 30func TestDocumentAndCloneStyles(t *testing.T) {
 31	css, err := files.ReadFile("assets/site.css")
 32	if err != nil {
 33		t.Fatal(err)
 34	}
 35	for _, expected := range []string{
 36		".markdown h1,", ".markdown blockquote", ".markdown pre", ".markdown table", ".markdown hr", ".markdown a", ".markdown img", "height: auto;", "max-width: 100%;",
 37		".repository-tab-button", "margin-left: auto;", ".sr-only",
 38	} {
 39		if !strings.Contains(string(css), expected) {
 40			t.Errorf("stylesheet missing %q", expected)
 41		}
 42	}
 43
 44	var rendered bytes.Buffer
 45	if err := pageTemplates.ExecuteTemplate(&rendered, "repository", repositoryPage{HTTPCloneURL: "https://example.test/team/project.git"}); err != nil {
 46		t.Fatal(err)
 47	}
 48	body := rendered.String()
 49	if !strings.Contains(body, `data-copy="https://example.test/team/project.git"`) || !strings.Contains(body, `aria-label="Copy HTTP clone URL"`) || !strings.Contains(body, `site.js`) || strings.Contains(body, "SSH clone") {
 50		t.Fatalf("clone control is not a HTTP copy button: %s", body)
 51	}
 52}
 53
 54func TestTreeEntriesShowLatestAffectingCommit(t *testing.T) {
 55	repo := newTestRepository(t, map[string]string{"README.md": "hello", "dir/a.txt": "first"})
 56	appendCommitMessage(t, repo.Path, "dir/a.txt", "second", "update <script>")
 57	ref, err := ResolveRef(repo, "")
 58	if err != nil {
 59		t.Fatal(err)
 60	}
 61	entries, truncated, err := treePageEntries(repo, ref, "team/project", ref.Name().String(), "")
 62	if err != nil || truncated {
 63		t.Fatalf("tree entries = %#v, truncated=%t, err=%v", entries, truncated, err)
 64	}
 65	hash := strings.TrimSpace(runGitOutput(t, repo.Path, "rev-parse", "HEAD"))
 66	var directory *treePageEntry
 67	for index := range entries {
 68		if entries[index].Name == "dir" {
 69			directory = &entries[index]
 70			break
 71		}
 72	}
 73	if directory == nil || directory.LastCommit == nil {
 74		t.Fatalf("directory commit metadata missing: %#v", entries)
 75	}
 76	if directory.LastCommit.ShortHash != shortHash(hash) || directory.LastCommit.Subject != "update <script>" || directory.LastCommit.URL != CommitURL("team/project", hash) {
 77		t.Fatalf("directory latest commit = %#v", directory.LastCommit)
 78	}
 79
 80	var rendered bytes.Buffer
 81	if err := pageTemplates.ExecuteTemplate(&rendered, "tree", treePage{Entries: entries}); err != nil {
 82		t.Fatal(err)
 83	}
 84	body := rendered.String()
 85	if strings.Contains(body, `scope="col">Mode`) || strings.Contains(body, "100644") {
 86		t.Fatalf("tree still renders modes: %s", body)
 87	}
 88	if !strings.Contains(body, "Last commit") || !strings.Contains(body, shortHash(hash)) || !strings.Contains(body, "update &lt;script&gt;") || strings.Contains(body, "update <script>") {
 89		t.Fatalf("tree commit information was not rendered safely: %s", body)
 90	}
 91	if !strings.Contains(body, `href="`+CommitURL("team/project", hash)+`"`) {
 92		t.Fatalf("tree commit link missing: %s", body)
 93	}
 94
 95	rendered.Reset()
 96	if err := pageTemplates.ExecuteTemplate(&rendered, "tree", treePage{File: &treePageFile{Name: "a.txt", Size: 42}}); err != nil {
 97		t.Fatal(err)
 98	}
 99	if strings.Contains(rendered.String(), "100644") {
100		t.Fatalf("selected-file metadata renders a mode: %s", rendered.String())
101	}
102}