e2e/autolink_test.go
92 lines · 3511 bytes
1package e2e
2
3import (
4 "os"
5 "path/filepath"
6 "strings"
7 "testing"
8)
9
10func TestWebAutolinks(t *testing.T) {
11 inst := startInstance(t)
12 aliceKey := inst.newKey(t, "alice")
13 bobKey := inst.newKey(t, "bob")
14 inst.admin(t, "admin", "user", "create", "alice",
15 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
16 inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
17
18 // Public repo with an issue, an MR, and a private repo with an issue.
19 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
20 t.Fatalf("repo create: %s", errOut)
21 }
22 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/secret", "--private"); code != 0 {
23 t.Fatal("private repo create failed")
24 }
25 if _, _, code := inst.ssh(t, aliceKey, "", "issue", "create", "alice/secret", "--title", "'hidden'"); code != 0 {
26 t.Fatal("private issue create failed")
27 }
28 work := t.TempDir()
29 env := inst.gitEnv(aliceKey)
30 mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
31 dir := filepath.Join(work, "w")
32 os.WriteFile(filepath.Join(dir, "a.txt"), []byte("a\n"), 0o644)
33 mustGit(t, dir, env, "checkout", "-q", "-b", "main")
34 mustGit(t, dir, env, "add", ".")
35 mustGit(t, dir, env, "commit", "-q", "-m", "base")
36 mustGit(t, dir, env, "push", "-q", "origin", "main")
37 mustGit(t, dir, env, "checkout", "-q", "-b", "feat")
38 os.WriteFile(filepath.Join(dir, "b.txt"), []byte("b\n"), 0o644)
39 mustGit(t, dir, env, "add", ".")
40 mustGit(t, dir, env, "commit", "-q", "-m", "feat")
41 mustGit(t, dir, env, "push", "-q", "origin", "feat")
42 if _, errOut, code := inst.ssh(t, aliceKey, "", "mr", "create", "alice/app",
43 "--source", "feat", "--target", "main", "--title", "'feat'"); code != 0 {
44 t.Fatalf("mr create: %s", errOut)
45 }
46 if _, _, code := inst.ssh(t, aliceKey, "", "issue", "create", "alice/app", "--title", "'first'"); code != 0 {
47 t.Fatal("issue 1 create failed")
48 }
49 if _, _, code := inst.ssh(t, aliceKey, "", "issue", "create", "alice/app",
50 "--title", "'refs'", "--body",
51 "'see #1 and !1 and alice/app#1 and @bob, not #99, not alice/secret#1, not `#1` in code'"); code != 0 {
52 t.Fatal("issue 2 create failed")
53 }
54
55 status, body := inst.get(t, "/alice/app/issues/2")
56 if status != 200 {
57 t.Fatalf("issue page: %d", status)
58 }
59 for _, want := range []string{
60 `<a href="/alice/app/issues/1" class="xref">#1</a>`,
61 `<a href="/alice/app/mrs/1" class="xref">!1</a>`,
62 `<a href="/alice/app/issues/1" class="xref">alice/app#1</a>`,
63 `<a href="/bob" class="xref">@bob</a>`,
64 } {
65 if !strings.Contains(body, want) {
66 t.Errorf("missing %q on issue page", want)
67 }
68 }
69 if strings.Contains(body, "issues/99") {
70 t.Error("nonexistent issue got linked")
71 }
72 // The private repo must stay plain text for anonymous viewers: a link
73 // would confirm it exists.
74 if strings.Contains(body, `href="/alice/secret`) {
75 t.Error("private repo reference leaked as a link")
76 }
77 if !strings.Contains(body, "alice/secret#1") {
78 t.Error("private repo reference text missing entirely")
79 }
80 if !strings.Contains(body, "<code>#1</code>") {
81 t.Error("code-span reference was rewritten")
82 }
83
84 // Comments on MR pages get the same treatment.
85 if _, _, code := inst.ssh(t, bobKey, "", "mr", "comment", "alice/app", "1", "--message", "'closes #2'"); code != 0 {
86 t.Fatal("mr comment failed")
87 }
88 _, body = inst.get(t, "/alice/app/mrs/1")
89 if !strings.Contains(body, `<a href="/alice/app/issues/2" class="xref">#2</a>`) {
90 t.Error("MR comment reference not linked")
91 }
92}