e2e/design_test.go
166 lines · 6764 bytes
1package e2e
2
3import (
4 "encoding/json"
5 "net/url"
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10)
11
12func TestReadmeRelativeLinks(t *testing.T) {
13 inst := startInstance(t)
14 aliceKey := inst.newKey(t, "alice")
15 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
16 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/site"); code != 0 {
17 t.Fatal("repo create failed")
18 }
19 work := t.TempDir()
20 env := inst.gitEnv(aliceKey)
21 mustGit(t, work, env, "clone", inst.sshURL("alice/site"), "w")
22 dir := filepath.Join(work, "w")
23 os.MkdirAll(filepath.Join(dir, "docs"), 0o755)
24 os.MkdirAll(filepath.Join(dir, "img"), 0o755)
25 os.WriteFile(filepath.Join(dir, "README.md"), []byte(
26 "# site\n\n[guide](docs/guide.md) and [export](docs/paper.html) and "+
27 "[abs](https://example.org/x) here\n\n\n"), 0o644)
28 os.WriteFile(filepath.Join(dir, "docs", "guide.md"), []byte("# guide\n"), 0o644)
29 os.WriteFile(filepath.Join(dir, "docs", "paper.org"), []byte("* paper\n"), 0o644)
30 os.WriteFile(filepath.Join(dir, "img", "logo.png"), []byte{0x89, 0x50}, 0o644)
31 mustGit(t, dir, env, "checkout", "-q", "-b", "main")
32 mustGit(t, dir, env, "add", ".")
33 mustGit(t, dir, env, "commit", "-q", "-m", "base")
34 mustGit(t, dir, env, "push", "-q", "origin", "main")
35
36 status, body := inst.get(t, "/alice/site")
37 if status != 200 {
38 t.Fatalf("tree: %d", status)
39 }
40 for _, want := range []string{
41 `href="/alice/site/blob/main/docs/guide.md"`, // relative link
42 `href="/alice/site/blob/main/docs/paper.org"`, // .html mapped to .org source
43 `src="/alice/site/raw/main/img/logo.png"`, // relative image via raw
44 `href="https://example.org/x"`, // absolute untouched
45 `href="/alice/site/blob/main/README.md">README.md</a>`, // clickable card header
46 `<th>name</th>`, // file table column headers
47 } {
48 if !strings.Contains(body, want) {
49 t.Errorf("missing %q", want)
50 }
51 }
52 // Branch dropdown lists branches.
53 if !strings.Contains(body, `class="refmenu"`) || !strings.Contains(body, ">all refs") {
54 t.Error("branch dropdown missing")
55 }
56 // Explore rows carry topics, license, and updated date.
57 inst.ssh(t, aliceKey, "", "repo", "topics", "add", "alice/site", "web")
58 os.WriteFile(filepath.Join(dir, "LICENSE"), []byte("Permission to use, copy, modify, and/or distribute this software...\n"), 0o644)
59 mustGit(t, dir, env, "add", ".")
60 mustGit(t, dir, env, "commit", "-q", "-m", "license")
61 mustGit(t, dir, env, "push", "-q", "origin", "main")
62 _, body = inst.get(t, "/explore")
63 for _, want := range []string{`href="/explore?q=web"`, "ISC", "updated 20"} {
64 if !strings.Contains(body, want) {
65 t.Errorf("explore row missing %q", want)
66 }
67 }
68}
69
70func TestWebInteractions(t *testing.T) {
71 inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n")
72 aliceKey := inst.newKey(t, "alice")
73 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
74 if _, _, code := inst.ssh(t, aliceKey, "", "org", "create", "theorg"); code != 0 {
75 t.Fatal("org create failed")
76 }
77
78 out, _, code := inst.ssh(t, aliceKey, "", "web", "login", "--json")
79 if code != 0 {
80 t.Fatal("web login failed")
81 }
82 var env2 struct {
83 Data struct {
84 URL string `json:"url"`
85 } `json:"data"`
86 }
87 json.Unmarshal([]byte(out), &env2)
88 browser := newBrowser(t)
89 browserGet(t, browser, inst.base()+env2.Data.URL[strings.Index(env2.Data.URL, "/login"):])
90
91 // Create a repo under the org through the web form.
92 if status, _ := browserPost(t, browser, inst.base()+"/new",
93 url.Values{"owner": {"theorg"}, "name": {"webborn"}, "visibility": {"public"}}); status != 200 {
94 t.Fatalf("org repo via web: %d", status)
95 }
96 if out, _, code := inst.ssh(t, aliceKey, "", "repo", "show", "theorg/webborn"); code != 0 {
97 t.Fatalf("org repo missing: %s", out)
98 }
99
100 // Pin from the web; the repo header reflects it and the dashboard
101 // lists it; a second toggle unpins.
102 if status, _ := browserPost(t, browser, inst.base()+"/theorg/webborn/pin", url.Values{}); status != 200 {
103 t.Fatal("pin toggle failed")
104 }
105 _, body := browserGet(t, browser, inst.base()+"/theorg/webborn")
106 if !strings.Contains(body, "★ pinned") {
107 t.Fatal("repo header not pinned")
108 }
109 if _, body = browserGet(t, browser, inst.base()+"/"); !strings.Contains(body, "theorg<span") {
110 t.Fatal("dashboard missing pinned repo")
111 }
112 browserPost(t, browser, inst.base()+"/theorg/webborn/pin", url.Values{})
113 if _, body = browserGet(t, browser, inst.base()+"/theorg/webborn"); !strings.Contains(body, "☆ pin") {
114 t.Fatal("unpin failed")
115 }
116
117 // New issue with labels through the form; label chips filter.
118 if status, _ := browserPost(t, browser, inst.base()+"/theorg/webborn/issues/new",
119 url.Values{"title": {"styled"}, "body": {"b"}, "labels": {"bug ui"}}); status != 200 {
120 t.Fatal("issue via web failed")
121 }
122 if status, _ := browserPost(t, browser, inst.base()+"/theorg/webborn/issues/new",
123 url.Values{"title": {"plain"}}); status != 200 {
124 t.Fatal("second issue failed")
125 }
126 _, body = browserGet(t, browser, inst.base()+"/theorg/webborn/issues?label=bug")
127 if !strings.Contains(body, "styled") || strings.Contains(body, ">plain<") {
128 t.Fatalf("label filter wrong:\n%s", body)
129 }
130 _, body = browserGet(t, browser, inst.base()+"/theorg/webborn/issues/1")
131 if !strings.Contains(body, `href="/theorg/webborn/issues?label=bug"`) ||
132 !strings.Contains(body, `href="/alice">alice</a>`) {
133 t.Fatal("issue page chips/author not linked")
134 }
135}
136
137func TestCommitParentLinks(t *testing.T) {
138 inst := startInstance(t)
139 aliceKey := inst.newKey(t, "alice")
140 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
141 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
142 t.Fatal("repo create failed")
143 }
144 work := t.TempDir()
145 env := inst.gitEnv(aliceKey)
146 mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
147 dir := filepath.Join(work, "w")
148 os.WriteFile(filepath.Join(dir, "a.txt"), []byte("a\n"), 0o644)
149 mustGit(t, dir, env, "checkout", "-q", "-b", "main")
150 mustGit(t, dir, env, "add", ".")
151 mustGit(t, dir, env, "commit", "-q", "-m", "first")
152 first := strings.TrimSpace(mustGit(t, dir, env, "rev-parse", "HEAD"))
153 os.WriteFile(filepath.Join(dir, "a.txt"), []byte("b\n"), 0o644)
154 mustGit(t, dir, env, "commit", "-qam", "second")
155 head := strings.TrimSpace(mustGit(t, dir, env, "rev-parse", "HEAD"))
156 mustGit(t, dir, env, "push", "-q", "origin", "main")
157
158 _, body := inst.get(t, "/alice/app/commit/"+head)
159 if !strings.Contains(body, `href="/alice/app/commit/`+first+`"`) {
160 t.Fatal("parent commit not linked")
161 }
162 _, body = inst.get(t, "/alice/app/commit/"+first)
163 if strings.Contains(body, ">parent") {
164 t.Fatal("root commit shows a parent")
165 }
166}