e2e/profileabout_test.go
168 lines · 6444 bytes
4 symbols in this file
1package e2e
2
3import (
4 "strings"
5 "testing"
6)
7
8// The about text is a file in <owner>/.gitbay, read on every surface with
9// the reader's own access.
10func TestProfileAboutFromRepo(t *testing.T) {
11 t.Parallel()
12 inst := startInstance(t)
13 aliceKey := inst.newKey(t, "alice")
14 inst.admin(t, "admin", "user", "create", "alice",
15 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
16 bobKey := inst.newKey(t, "bob")
17 inst.admin(t, "admin", "user", "create", "bob",
18 "--key", bobKey+".pub", "--email", "bob@example.test", "--verified")
19
20 if _, _, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/.gitbay"); code != 0 {
21 t.Fatal("creating alice/.gitbay failed")
22 }
23 if _, _, code := inst.ssh(t, aliceKey, "# alice\n\nhello from a file\n",
24 "repo", "commit-file", "alice/.gitbay", "profile/README.md",
25 "--ref", "main", "--file", "-"); code != 0 {
26 t.Fatal("committing the about failed")
27 }
28
29 out, _, code := inst.ssh(t, bobKey, "", "profile", "show", "alice", "--json")
30 if code != 0 {
31 t.Fatalf("profile show: %d", code)
32 }
33 if !strings.Contains(out, "hello from a file") {
34 t.Errorf("about not read from the repository: %s", out)
35 }
36 if !strings.Contains(out, `"about_format":"md"`) {
37 t.Errorf("about_format not md: %s", out)
38 }
39 if !strings.Contains(out, `"about_path":"profile/README.md"`) {
40 t.Errorf("about_path missing: %s", out)
41 }
42
43 _, body := inst.get(t, "/alice")
44 if !strings.Contains(body, "hello from a file") {
45 t.Error("web profile does not render the about")
46 }
47
48 // The extension drives the renderer: an .org about renders as org.
49 if _, _, code := inst.ssh(t, bobKey, "", "repo", "create", "bob/.gitbay"); code != 0 {
50 t.Fatal("creating bob/.gitbay failed")
51 }
52 if _, errOut, code := inst.ssh(t, bobKey, "a /note/ in org\n",
53 "repo", "commit-file", "bob/.gitbay", "profile/README.org",
54 "--ref", "main", "--file", "-"); code != 0 {
55 t.Fatalf("committing bob's org about: %s", errOut)
56 }
57 if _, page := inst.get(t, "/bob"); !strings.Contains(page, "<em>note</em>") {
58 t.Errorf("about did not render as org:\n%s", page)
59 }
60}
61
62// The extension picks the format, .md wins the resolution order, and a
63// private .gitbay keeps the about to the people who can read it.
64func TestProfileAboutFormatAndPrivacy(t *testing.T) {
65 t.Parallel()
66 inst := startInstance(t)
67 aliceKey := inst.newKey(t, "alice")
68 inst.admin(t, "admin", "user", "create", "alice",
69 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
70 bobKey := inst.newKey(t, "bob")
71 inst.admin(t, "admin", "user", "create", "bob",
72 "--key", bobKey+".pub", "--email", "bob@example.test", "--verified")
73
74 inst.ssh(t, aliceKey, "", "repo", "create", "alice/.gitbay", "--private")
75 if _, _, code := inst.ssh(t, aliceKey, "* heading\n\norg text here\n",
76 "repo", "commit-file", "alice/.gitbay", "profile/README.org",
77 "--ref", "main", "--file", "-"); code != 0 {
78 t.Fatal("committing the org about failed")
79 }
80
81 out, _, _ := inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
82 if !strings.Contains(out, "org text here") || !strings.Contains(out, `"about_format":"org"`) {
83 t.Errorf("owner cannot read their own private about: %s", out)
84 }
85
86 out, _, code := inst.ssh(t, bobKey, "", "profile", "show", "alice", "--json")
87 if code != 0 {
88 t.Fatalf("profile show for an outsider should succeed: %d", code)
89 }
90 if strings.Contains(out, "org text here") {
91 t.Errorf("private about leaked to an outsider: %s", out)
92 }
93
94 // A .md beside the .org wins: it is first in the resolution order.
95 if _, _, code := inst.ssh(t, aliceKey, "markdown wins\n",
96 "repo", "commit-file", "alice/.gitbay", "profile/README.md",
97 "--ref", "main", "--file", "-"); code != 0 {
98 t.Fatal("committing the md about failed")
99 }
100 out, _, _ = inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
101 if !strings.Contains(out, "markdown wins") {
102 t.Errorf(".md did not win resolution: %s", out)
103 }
104}
105
106// A dot-repo is infrastructure: it stays out of explore and off the
107// profile's repository list, and stays in the owner's own inventory.
108func TestDotReposHiddenFromListings(t *testing.T) {
109 t.Parallel()
110 inst := startInstance(t)
111 aliceKey := inst.newKey(t, "alice")
112 inst.admin(t, "admin", "user", "create", "alice",
113 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
114 inst.ssh(t, aliceKey, "", "repo", "create", "alice/.gitbay")
115 inst.ssh(t, aliceKey, "", "repo", "create", "alice/app")
116
117 out, _, _ := inst.ssh(t, aliceKey, "", "explore", "--json")
118 if strings.Contains(out, ".gitbay") {
119 t.Errorf("dot-repo listed in explore: %s", out)
120 }
121 if !strings.Contains(out, "alice/app") {
122 t.Errorf("ordinary repo missing from explore: %s", out)
123 }
124
125 out, _, _ = inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
126 if strings.Contains(out, `"path":"alice/.gitbay"`) {
127 t.Errorf("dot-repo listed on the profile: %s", out)
128 }
129 if !strings.Contains(out, `"path":"alice/app"`) {
130 t.Errorf("ordinary repo missing from the profile: %s", out)
131 }
132
133 out, _, _ = inst.ssh(t, aliceKey, "", "repo", "list", "--json")
134 if !strings.Contains(out, "alice/.gitbay") {
135 t.Errorf("dot-repo missing from the owner's own inventory: %s", out)
136 }
137
138 // It is still reachable at its URL.
139 if _, page := inst.get(t, "/alice/.gitbay"); strings.Contains(page, "not found") {
140 t.Error("dot-repo page not reachable")
141 }
142}
143
144// The about is not settable through profile set any more: it is a file.
145func TestProfileSetHasNoAbout(t *testing.T) {
146 t.Parallel()
147 inst := startInstance(t)
148 aliceKey := inst.newKey(t, "alice")
149 inst.admin(t, "admin", "user", "create", "alice",
150 "--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
151
152 if _, _, code := inst.ssh(t, aliceKey, "", "profile", "set", "--about", "'inline text'"); code == 0 {
153 t.Error("profile set --about still accepted")
154 }
155 if _, _, code := inst.ssh(t, aliceKey, "x", "profile", "set", "--file", "-"); code == 0 {
156 t.Error("profile set --file still accepted")
157 }
158
159 // The flags that stay still work.
160 if _, errOut, code := inst.ssh(t, aliceKey, "",
161 "profile", "set", "--description", "'a line'", "--link", "'site|https://example.org'"); code != 0 {
162 t.Fatalf("profile set --description --link: %s", errOut)
163 }
164 out, _, _ := inst.ssh(t, aliceKey, "", "profile", "show", "alice", "--json")
165 if !strings.Contains(out, "a line") || !strings.Contains(out, "https://example.org") {
166 t.Errorf("description or link not saved: %s", out)
167 }
168}