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