e2e/description_test.go
110 lines · 4300 bytes
1 symbol in this file
1package e2e
2
3import (
4 "strings"
5 "testing"
6)
7
8func TestRepoDescriptions(t *testing.T) {
9 t.Parallel()
10 inst := startInstance(t)
11 aliceKey := inst.newKey(t, "alice")
12 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
13
14 // Set at creation; visible in show and list (human and JSON).
15 if _, errOut, code := inst.ssh(t, aliceKey, "",
16 "repo", "create", "alice/tool", "--description", "'a fine tool'"); code != 0 {
17 t.Fatalf("create: %s", errOut)
18 }
19 out, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/tool", "--json")
20 if !strings.Contains(out, `"description":"a fine tool"`) {
21 t.Fatalf("show json: %s", out)
22 }
23 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "list")
24 if !strings.Contains(out, "a fine tool") {
25 t.Fatalf("list: %s", out)
26 }
27
28 // The description lives in the bare repo's native description file.
29 sshOut, _, _ := inst.ssh(t, aliceKey, "", "repo", "show", "alice/tool")
30 if !strings.Contains(sshOut, "a fine tool") {
31 t.Fatalf("show human: %s", sshOut)
32 }
33
34 // Update via settings; first line only, trimmed.
35 if _, errOut, code := inst.ssh(t, aliceKey, "",
36 "repo", "settings", "description", "alice/tool", "'better now'"); code != 0 {
37 t.Fatalf("settings description: %s", errOut)
38 }
39 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/tool", "--json")
40 if !strings.Contains(out, `"description":"better now"`) {
41 t.Fatalf("updated show: %s", out)
42 }
43
44 // Non-admins cannot set it.
45 bobKey := inst.newKey(t, "bob")
46 inst.admin(t, "admin", "user", "create", "bob", "--key", bobKey+".pub")
47 if _, _, code := inst.ssh(t, bobKey, "", "repo", "settings", "description", "alice/tool", "hax"); code != 4 {
48 t.Fatalf("non-admin set: exit %d, want 4", code)
49 }
50
51 // Web: explore, the profile's repositories tab, and the repo header
52 // all show it.
53 for _, path := range []string{"/explore", "/alice/-/repositories", "/alice/tool"} {
54 status, body := inst.get(t, path)
55 if status != 200 || !strings.Contains(body, "better now") {
56 t.Fatalf("description missing at %s (%d)", path, status)
57 }
58 }
59
60 // Website: set, shown in show and on the repo page; bad scheme and
61 // non-admins refused.
62 if _, errOut, code := inst.ssh(t, aliceKey, "",
63 "repo", "settings", "website", "alice/tool", "https://tool.example.org"); code != 0 {
64 t.Fatalf("settings website: %s", errOut)
65 }
66 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/tool", "--json")
67 if !strings.Contains(out, `"website":"https://tool.example.org"`) {
68 t.Fatalf("website show: %s", out)
69 }
70 if _, body := inst.get(t, "/alice/tool"); !strings.Contains(body, `href="https://tool.example.org"`) {
71 t.Fatalf("website missing on repo page:\n%s", body)
72 }
73 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "settings", "website", "alice/tool", "javascript:alert(1)"); code != 2 {
74 t.Fatalf("bad scheme accepted")
75 }
76 if _, _, code := inst.ssh(t, bobKey, "", "repo", "settings", "website", "alice/tool", "https://x.example"); code != 4 {
77 t.Fatalf("non-admin set website: want exit 4")
78 }
79 // Clearing removes it.
80 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "settings", "website", "alice/tool", "''"); code != 0 {
81 t.Fatal("website clear failed")
82 }
83 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/tool", "--json")
84 if strings.Contains(out, `"website"`) {
85 t.Fatalf("website not cleared: %s", out)
86 }
87 if _, _, code := inst.ssh(t, aliceKey, "",
88 "repo", "settings", "website", "alice/tool", "https://tool.example.org"); code != 0 {
89 t.Fatal("website re-set failed")
90 }
91
92 // Forks inherit the description.
93 if _, errOut, code := inst.ssh(t, bobKey, "", "repo", "fork", "alice/tool"); code != 0 {
94 t.Fatalf("fork: %s", errOut)
95 }
96 out, _, _ = inst.ssh(t, bobKey, "", "repo", "show", "bob/tool", "--json")
97 if !strings.Contains(out, `"description":"better now"`) {
98 t.Fatalf("fork description: %s", out)
99 }
100
101 // A repo with no description set stays clean (git's placeholder is
102 // treated as empty).
103 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/plain"); code != 0 {
104 t.Fatal("plain create failed")
105 }
106 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "show", "alice/plain", "--json")
107 if strings.Contains(out, "Unnamed repository") || strings.Contains(out, `"description"`) {
108 t.Fatalf("placeholder leaked: %s", out)
109 }
110}